
- •1 Основні елементи мови с
- •1.1 Алфавіт мови програмування
- •1.2 Лексеми
- •1.3 Ключові слова
- •1.4 Ідентифікатори
- •1.5 Класифікація типів даних
- •1.6 Літерали
- •1.7 Оператори
- •1.8 Коментарі
- •1.9 Директиви препроцесора
- •1.10 Організація програми
- •2 Операції та вирази
- •2.1 Загальні відомості
- •2.2 Арифметичні операції
- •2.3 Операції приведення типів
- •2.4 Операції присвоєння
- •2.5 Операції інкремента і декремента
- •2.6 Операції порівняння
- •2.7 Операції зсуву
- •2.8 Порозрядні операції
- •2.9 Логічні операції
- •2.10 Операція sizeof
- •2.11 Операція послідовного обчислення
- •2.12 Операція умови (?:)
- •2.13 Адресні операції
- •3 Прості типи даних
- •3.1 Оголошення змінних
- •3.2 Час існування та область видимості змінних
- •3.3 Цілі типи даних
- •3.4 Дійсні типи даних
- •4 Оператори керування
- •4.1 Оператор розгалуження if
- •4.2 Оператор розгалуження if-else
- •4.3 Оператор множинного розгалуження switch
- •4.4 Оператор циклу for
- •4.5 Оператор циклу while
- •4.6 Оператор циклу do while
- •4.7 Оператор break
- •4.8 Оператор continue
- •5 Функції
- •5.1 Основні поняття
- •5.2 Види виклику функцій
- •5.3 Область видимості
- •5.4 Порожній тип void
- •5.5 Передача аргументів у функцію
- •5.6 Рекурсивні функції
- •5.7 Прототипи функцій
- •6 Покажчики
- •6.1 Визначення та ініціалізація покажчиків
- •6.2 Визначення покажчиків
- •6.3 Масиви
- •6.4 Операції порівняння
- •6.5 Копіювання рядка
- •6.6 Покажчики на функцію
- •6.7 Покажчики на void
- •6.8 Арифметика покажчиків
- •7 Масиви
- •7.1 Загальні поняття
- •7.2 Одновимірні масиви
- •7.3 Багатовимірні масиви
- •8 Рядки в с
- •8.1 Рядки
- •8.2.Створення рядків
- •8.3 Прототипи
- •8.3 Функції перетворення буферів
- •8.4 Функції перевірки літер
- •8.5 Операції з рядками
- •9 Структури, об’єднання, перерахування
- •9.1 Структури
- •9.2 Бітові поля
- •9.3 Ключове слово typedef
- •9.4 Об’єднання
- •9.5 Перераховуваний тип
- •10 Введення та виведення даних
- •10.1 Функція виведення printf
- •10.2Функція введення scanf
- •10.3 Введення та виведення у файл
- •11 Динамічне виділення пам'яті
6.4 Операції порівняння
Крім раніше розглянутих операцій адресної арифметики, до покажчиків можна застосувати операції порівняння == , і! =. Навіть операції відношення <,> = і т.п. працюють правильно, якщо покажчики посилаються на елементи одного і того ж масиву. Можливе навіть віднімання посилань. Наприклад, u і s посилаються на елементи одного масиву, то us є число елементів між u і s. Спочатку u вказує на перший символ рядка (char * u = s). Потім у циклі по черзі перевіряється кожен символ, поки зрештою не буде виявлений "\ 0". Різниця us дає саме довжину рядка.
Приклад 6.9. Функція length (рис. 6.9)
int length (char * s) { /* довжина рядка */
char * u = s;
while (* u! = '\ 0')
u++;
return (u – s);
}
Рисунок 6.9 – Ілюстрація функції length
Для даного випадку u-s = 3 (останній нуль-символ не рахується).
Приклад 6.10. Збільшення поточного значення покажчика на одиницю.
int length (char * s)
{
int i;
for (i = 0; * s! = '\ 0'; s++)
i++;
return i;}
6.5 Копіювання рядка
Приклад 6.11. Копіювання рядка s1 в рядок s2 звичайним способом.
void copy (char s1 [],char s2){
int i = 0;
while ((s2[i] = s1[i])!='\0')
i ++;
}
Приклад 6.12. Копіювання рядка s1 в рядок s2 із використанням покажчиків.
void copy (char * s1, char * s2){
while ((* s2 =* s1)! = '\ 0')
s2 + +; s1 + +;
}
В даному прикладі операція копіювання поміщена безпосередньо в умові: ((* s2 =* s1)! = '\ 0'). Просування вздовж масивів до тих пір, поки не зустрінеться "\ 0", забезпечують оператори s2++ та s1++. Їх теж можна помістити в умову.
Приклад 6.13. Копіювання рядка s1 в рядок s2 із використанням циклу while.
void copy (char * s1, char* s2){
while ((*s2 + + = *s1 + +)! = ' \ 0 ');
}
Унарні операції типу *і++ виконуються справа наліво. Значення *s++ вважається символ, на який вказує s до його збільшення. Так як значення "\ 0" є нуль, а цикл while перевірить, чи не нуль вираз в дужках. Так поступово функція копіювання стає все більш компактною.
У мові С символьний рядок, фактично розглядається як покажчик на нульовий елемент масиву .
Приклад 6.14. Вираження символьної стрічки як "рядок".
char * ptr; ptr = "Калейдоскоп";
Останній оператор присвоює покажчиком адресу нульового елемента рядка, тобто символу "К". Може вииникнути запитання, де знаходиться масив, що містить символи "Калейдоскоп"? Ми його ніде не описували. Відповідь така: цей рядок ― константа.
Приклад 6.15. Друкування рядка символів у зворотному порядку.
# include <stdio.h>
int main ()
{
char * ptr1, * ptr2;
ptr1 = ptr2 = "Калейдоскоп";
while (* ptr! = '\ 0')
putchar (* ptr2 + +);
putchar ('\ n');
while (--ptr2> = ptr1)
putchar (* ptr2);
putchar ('\ n');
}
На самому початку покажчиками ptr1 і ptr2 присвоюється початкові адреси рядка "Калейдоскоп". Потім рядок посимвольно друкується і одночасно покажчик ptr2 зміщується вздовж рядка. В кінці ptr2 вказує на останній символ вихідного рядка. У другому циклі while все той же покажчик ptr2 починає змінюватися в зворотному напрямку, зменшуючись до тих пір, поки він не буде вказувати на нульовий елемент масиву, забезпечуючи видачу рядка в зворотному порядку.