Описание массива типа

char string[80];
позволяет описывать и обрабатывать символьные данные, однако тип char[ ] относится к целому типу, поскольку имеет дело с ASCII-кодами символов.

Особым случаем массива является строковый литерал (строка-константа) – последовательность любых символов, заключенных в кавычки: “это строковый литерал”. Строковый литерал представляется в памяти как массив элементов типа char[ ], в конце которого помещен символ ‘\0’ (нулевой байт); его называют ACSIIZ-строкой. Как и с любым массивом, со строковым литералом связан указатель-константа на первый элемент строки.

Можно также описать указатель символьного типа

char *str;
который пока не связан ни с какой символьной информацией.

Символьные массивы можно инициировать, вводить и выводить поэлементно, как и числовые массивы, однако более рационально выполнять инициирование с помощью строковых литералов, а ввод-вывод по ссылке на имя символьного массива, которое является указателем-константой на первый элемент массива (с индексом 0).

Совершенно идентичны следующие описания с инициализацией:

char string [10] = {‘с’,’л’,’о’,’в’,’о’,’\0’};

char string [10] = ”слово”;

Последнее описание выглядит проще, а нулевой байт записывается в конце строки автоматически. Адрес первого элемента (‘с’) становится синонимом имени массива string. Строка в массиве ограничена нулевым байтом, а остальные элементы массива не используются. Можно не задавать размер массива, компилятор выделит нужное число элементов плюс нулевой байт при инициализации:

char string[ ]=”слово”;

Описание вида char * str;
выделит место в памяти только для указателя str, а место для отсутствующей строки не выделяется. Можно инициировать указатель строковым литератором, например,

char * str = “Иванов А.С.”;
или присваиванием определить указатель:

str = “Иванов А.С.”;
тогда указатель получит адрес первого символа литерала, который располагается в сегменте данных программы.

Стандартные функции ввода-вывода можно использовать для обработки символьных данных.

Пример. Ввести и вывести строку символов.

Программа.

void main ()

{ char name [25];

puts (“Введите Фамилию И.О.:”);

gets (name);

puts (“Вывести Фамилию И.О.:”);

puts (name); /* или printf(“%s”, name); */

}

Функция scanf (“%s”, name) менее удобна, поскольку вводит символы до первого пробела.

При использовании указателя для выделения памяти под любое содержимое строки необходимо использовать функции динамического выделения памяти, для чего в начале программы необходимо добавить команду препроцессора

#include <alloc.h>.

Пусть дано описание указателя

char * str;
тогда оператор вида

str = (char*) malloc (30);
выделит 30 байт в динамической памяти и запишет адрес начала этого блока в указатель str.

Можно также использовать другую функцию:

str = (char*) calloc (количество, размер элемента);
которая возвращает указатель (адрес) на выделенный блок памяти = количество * размер элемента (байт) и обнуляет выделенную память.

После использования блока динамической памяти его надо освободить функцией

free (указатель), например, free (str).

Пример. Ввод и вывод строк в динамической памяти.

Программа:

#include <alloc.h>

void main ()

{ char * pname;

pname = (char*) malloc (30); /* выделение динамической памяти */

printf (“Введите Фамилию И.О.:”);

gets (name);

printf (“Вывод Фамилии И.О.:”);

free (name); /* освобождение динамической памяти */

}

Особый случай – инициализация двухмерного массива строковыми литералами. Многомерные массивы могут инициироваться и без указания одной (самой левой) из размерностей массива в [ ]. Компилятор сам определяет число элементов по числу членов в списке инициализации.

Например,

char str [ ] [80] = { “Первая строка”,

“Вторая строка”,

“Третья строка” };

Как было показано выше, элементы массива str[0], str[1], str[2] являются указателями на строки двухмерного массива, что можно использовать при обработке таких массивов.

Пример. Ввод и вывод строковых данных.

Программа:

void main ()

{ int i;

char buffer [3][80];

puts (“Введите строки в буфер:”);

for (i=0; i<3; i++) gets (buffer[i]);

puts (“Вывод строк из буфера:”);

for (i=0; i<3; i++) puts (buffer[i]);

}

Пример. Скопировать символы из массива s1, на который ссылается указатель ps1, в массив s2, на который ссылается указатель ps2. Исходная строка заканчивается символом ‘\0’.

Программа:

void main ()

{ char s1[80], s2[80], *ps1=s1, *ps2=s2; /* инициализация указателей */

clrscr (); /* очистка экрана */

puts (“Введите строку и нажмите Enter:”);

gets (s1); /* чтение строки и запись нуль-байта */

while (*ps1!= ’\0’) /* цикл пока не конец строки */

{ *ps2 = *ps1; /* копирование символа */

ps1++; /* переход к следующему символу в s1 */

ps2++; /* переход к следующему символу в s2 */

}

*ps2 = ’\0’; / * запись нуль-байта в строку s2 */

printf (“Скопирована строка:\n%s”,s2); /* вывод строки s2 */

} /* конец программы */

С учетом старшинства и действий операций присваивания (=), разадресации (*) и увеличения (++) копирование символов можно выполнить одним оператором while () с пустым телом цикла с одновременной проверкой условия:

while (*ps2++ = *ps1++);

Язык Си (и Си++) одновременно и любят и не любят за возможность использования столь лаконичных конструкций, которые требуют высокой квалификации программистов, но затрудняют понимание алгоритма.

Проще выглядит копирование символов с помощью оператора цикла:

for (i=0; s2[i]=s1[i]; i++); /* тело цикла – пустой оператор */


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: