русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Оператори приросту та спаду


Дата додавання: 2014-11-28; переглядів: 840.


C забезпечує двома незвичними операторами приросту та спаду змінних. Оператор приросту ++додає 1 до свого операнду, тоді як --, навпаки, віднімає 1. Ми вже не раз користувалися ++ для збільшення значення змінних, як, наприклад, у

if (c == '\n')

++nl;

Незвична сторона полягає в тому, що як ++, так і -- можуть використовуватись як префіксні оператори (перед змінною, наприклад ++n), так і постфіксні (після змінної: n++). В обох випадках, як наслідок — збільшується значення n. Але вираз ++n збільшує n до того, як це значення буде використане, тоді як n++ збільшує n після того, як було використане початкове значення. Це означає, що в контексті, де дійсно використовується значення, а не тільки самий ефект, ++n і n++ — відмінні. Якщо n дорівнює 5, тоді

x = n++;

присвоїть x значення 5, зате у випадку

x = ++n;

x дорівнюватиме вже 6. В обох випадках, n стане рівним 6. Оператори приросту та спаду можуть використовуватись тільки зі змінними; вирази на кшталт (i+j)++ заборонені.

У контексті, коли значення не потрібне, а тільки ефект приросту, як наприклад

if (c == '\n')

nl++;

префікс і постфікс тотожні. Але існують випадки, коли треба звернутися тільки до одного, або тільки до іншого. Наприклад, розглянемо функцію squeeze(s,c), яка вилучає всі знайдені знаки c з ланцюжка s.

/* squeeze: вилучає всі c з s */

void squeeze(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';

}

Кожного разу, як знайдено не-c, його копійовано до поточної позиції j, і тільки після цього jзбільшено, щоб бути готовим до наступного знака. Це точний еквівалент

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), яка зчеплює ланцюжок t із кінцем ланцюжка s. strcat припускає, що s має досить місця, щоб зберегти комбінацію обох ланцюжків. Так, як ми це написали, strcat не повертає жодного значення; версія зі стандартної бібліотеки повертає покажчик на отриманий ланцюжок.

/* strcat: зчеплює t із кінцем s; s має бути досить великим */

void strcat(char s[], char t[])

{

int i, j;

 

i = j = 0;

while (s[i] != '\0') /* знаходить кінець s */

i++;

while ((s[i++] = t[j++]) != '\0') /* копіює t */

;

}

Одночасно з копіюванням t до s до них застосовано постфіксний ++, щоб упевнитись, що вони в позиції для наступного проходження через цикл.

Вправа 2-4. Напишіть альтернативну версію squeeze(s1,s2), яка би вилучала кожний знак ізs1, який збігається із будь-яким знаком s2.

Вправа 2-5. Напишіть функцію any(s1, s2), яка повертає перше положення в ланцюжку s1одного із знаків ланцюжка s2, або -1, якщо жодного не знайдено. (Функція strpbrk зі стандартної бібліотеки здійснює те саме, тільки повертає покажчик на положення.)


<== попередня лекція | наступна лекція ==>
Перетворення типів | Розрядні оператори


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн