Рядки, як символьні масиви
В мові С++ немає спеціального типу даних, який можна було б використовувати для опису рядків. Замість цього рядки представляються у вигляді масиву елементів типу char. Це означає, що символи рядка розташовуються в пам'яті в сусідніх комірках, по одному символу в комірці. Необхідно відмітити, що останнім елементом масиву є символ '\0'. Це нульовий символ (байт, кожний біт якого рівний нулю). У мові Сі він використовується для того, щоб визначати кінець рядка.
Примітка. Нульовий символ - це не цифра 0; він не виводиться на друк і в таблиці символів ASCII має номер 0. Наявність нульового символу передбачає, що кількість комірок масиву повинна бути принаймні на одну більше, ніж число символів, які необхідно розміщувати в пам'яті.
char str[10];
передбачає, що рядок може містити максимум 9 символів.
Основні методи ініціалізації символьних рядків.
char str1[]= "ABCdef";
char str2[]={'A', 'B', 'C', 'd', 'e', 'f',0};
char str3[100];
gets(str3);
char str4[100];
scanf("%s",str4);
Строкова константа - це послідовність символів, вкладена в подвійні лапки. У рядку можуть перебувати будь-які символьні константи, наприклад,
"Дзвінок наприкінці повідомлення\007\n".
Сусідні строкові константи транслятором "склеюються". Наприклад, "АБВ" "ДЕ" означає те ж, що "АБВДЕ".
Усі константи-рядки в тексті програми, навіть ідентично записані, розміщуються за різними адресами в статичній пам'яті. З кожним рядком пов'язується сталий покажчик на його перший символ. Власне, рядок-константа є виразом типу "покажчик на char" зі сталим значенням - адресою першого символу.
Так, присвоювання *p="ABC" (p - покажчик на char) встановлює покажчик p на символ 'A'; значенням виразу *("ABC"+1) є символ 'B'.
Елементи рядків доступні через покажчики на них, тому будь-який вираз типу "покажчик на char" можна вважати рядком.
Адреса першого символа рядка може використовуватися по-різному:
- якщо рядок застосовується при ініціюванні масиву типу char, адреса його першого елемента стає синонімом імені масиву. Наприклад, ідентичними є такі описи масиву:
char st [ ] = "Слово";
char st[6] = "Слово";
char st [6] = {'C','л','о','в','о'};
Якщо рядок використовується для ініціювання покажчика типу char*, адреса першого символа рядка буде початковим значенням покажчика, наприклад:
char *pst = "Слово";.
Тут описується змінна-покажчик pst, яка одержує початкове значення, що дорівнює адресі першого елемента (символа 'C).
Слід звернути увагу на те, що при описі символьного масиву його ім'я - не змінна, а покажчик-константа на початок рядка, тому її не можна використовувати в деяких операціях адресної арифметики. Зокрема, не можна здійснювати операцію присвоювання вигляду:
char st [20];
st = "Петренко"; - запис неправильний, тому що не можна змінювати значення st.
Необхідно мати також на увазі те, що рядок вигляду "х" - не те ж саме, що символ 'x'. Перша відмінність : 'x' - об'єкт одного з основних типів даних мови С (char), в той час, як "х" - об'єкт похідного типу (масиву елементів типу char). Друга різниця : "х" насправді складається з двох символів - символу 'x' і нуль-символу.
Виконання дій з елементами символьного масиву здійснюється через індекси або через покажчики. Для доступу до будь-якого символа рядка використовується індекс масиву char. Тобто, якщо описана змінна
char str [3];
то третім елементом масиву можна скористатися, записавши:
str [2] або *(str+2).
В процесі роботи з елементами двовимірного масиву застосовують або індекси масиву, або індекси покажчиків. Якщо описаний список прізвищ
char spis [5] [15];,
то для використання символа масиву слід записати:
spis [i][j] або *(spis [i]+j).
Аналогічно, якщо оголошений масив покажчиків
char *str [5],
що містить 5 елементів, кожний з яких вказує на рядок, то доступ до символа рядка можна здійснити з використанням запису
*(str [і] + j).
Приклад 1. Задано рядок. Скопіювати його в символьний масив. Для контролю вивести в стандартний вихідний потік рядок і масив.
#іnclude <іostream.h>
voіd maіn()
{
char s1[ ]="1234567890", s2[11];
int i;
for ( і = 0; s1[і]; і++)
s2[і] = s1[і];
s2[і] ='\0';
cout << s1 << ' = ' << s2 << '\n';
}
Програму можна зробити трохи коротше, переписавши оператор циклу:
for (іnt і = 0; s2[і]=s1[і]; і++);.
Якщо згадати про покажчики на символи, можна написати й так:
for (char *p1 = s1, *p2 = s2; *p2++=*p1++;);.
Оператор s2[і] ='\ 0'; можно переписати s2[i]=0;, що означає одно й те саме.