Операции увеличения и уменьшения
В языке "C" предусмотрены две необычные операции для увеличения и уменьшения значений переменных. Операция увели- чения ++ добавляет 1 к своему операнду, а операция уменьше- ния -- вычитает 1. Мы часто использовали операцию ++ для увеличения переменных, как, например, в
IF(C == '\N') ++I;
Необычный аспект заключается в том, что ++ и -- можно использовать либо как префиксные операции (перед переменной, как в ++N), либо как постфиксные (после переменной: N++). Эффект в обоих случаях состоит в увеличении N. Но выражение ++N увеличивает переменную N до использования ее значения, в то время как N++ увеличивает переменную N после того, как ее значение было использовано. Это означает, что в контексте, где используется значение переменной, а не только эффект увеличения, использование ++N и N++ приводит к разным ре- зультатам. Если N = 5, то
х = N++;
устанавливает х равным 5, а
х = ++N;
полагает х равным 6. В обоих случаях N становится равным 6. Операции увеличения и уменьшения можно применять только к переменным; выражения типа х=(I+J)++ являются незаконными. В случаях, где нужен только эффект увеличения, а само значение не используется, как, например, в
IF ( C == '\N' ) NL++;
выбор префиксной или постфиксной операции является делом вкуса. но встречаются ситуации, где нужно использовать имен- но ту или другую операцию. Рассмотрим, например, функцию SQUEEZE(S,C), которая удаляет символ 'с' из строки S, каждый раз, как он встречается.
SQUEEZE(S,C) /* DELETE ALL C FROM S */ CHAR S[]; INT C; { INT I, J;
FOR ( I = J = 0; S[I] != '\0'; I++) IF ( S[I] != C ) S[J++] = S[I]; S[J] = '\0'; }
Каждый раз, как встечается символ, отличный от 'с', он копи- руется в текущую позицию J, и только после этого J увеличи- вается на 1, чтобы быть готовым для поступления следующего символа. Это в точности эквивалентно записи
IF ( S[I] != C ) { S[J] = S[I]; J++; }
Другой пример подобной конструкции дает функция GETLINE, которую мы запрограммировали в главе 1, где можно заменить
IF ( C == '\N' ) { S[I] = C; ++I; }
более компактной записью
IF ( C == '\N' ) S[I++] = C; В качестве третьего примера рассмотрим функцию STRCAT(S,T), которая приписывает строку т в конец строки S, образуя конкатенацию строк S и т. При этом предполагается, что в S достаточно места для хранения полученной комбинации.
STRCAT(S,T) /* CONCATENATE T TO END OF S */ CHAR S[], T[]; /* S MUST BE BIG ENOUGH */ { INT I, J;
I = J = 0; WHILE (S[I] != '\0') / *FIND END OF S */ I++; WHILE((S[I++] = T[J++]) != '\0') /*COPY T*/ ; }
Tак как из T в S копируется каждый символ, то для подготовки к следующему прохождению цикла постфиксная операция ++ при- меняется к обеим переменным I и J.
Упражнение 2-3
--------------- Напишите другой вариант функции SQUEEZE(S1,S2), который удаляет из строки S1 каждый символ, совпадающий с каким-либо символом строки S2.
Упражнение 2-4
--------------- Напишите программу для функции ANY(S1,S2), которая нахо- дит место первого появления в строке S1 какого-либо символа из строки S2 и, если строка S1 не содержит символов строки S2, возвращает значение -1.