Тема: Массивы и строки.
Цель: получение навыков обработки числовой и символьной информации, текстов с использованием стандартных функций языка С, а также закрепить знания и умения инициализации массивов.
Теоретическая часть
Массив – одна из наиболее простых и известных структур данных. Под массивом в языке C понимают набор данных одного и того же типа, собранных под одним именем. Каждый элемент массива определяется именем массива и порядковым номером элемента, который называется индексом. Индекс в языке C всегда целое число.
Форма объявления одномерного массива:
тип <имя массива>[размер];
где тип – базовый тип элементов массива,
размер – количество элементов одномерного массива.
Размер массива в языке C может задаваться константой или константным выражением. Нельзя задавать массив переменного размера. Для этого существует отдельный механизм, называемый динамическим выделением памяти.
В языке C индекс всегда начинается с нуля. Когда мы говорим о первом элементе массива, то имеем в виду элемент с индексом 0. Если мы объявили массив int a[100] - это значит, что массив содержит 100 элементов от a[0] до a[99].
Однако массивы типа char – символьные массивы – занимают в языке особое место. Во многих языках есть специальный тип данных – строка символов (string). В языке C отдельного типа строки символов нет, а реализована работа со строками путем использования одномерных массивов типа char. В языке C символьная строка – это одномерный массив типа char, заканчивающийся нулевым байтом. Нулевой байт – это байт, каждый бит которого равен нулю. Для нулевого байта определена специальная символьная константа '\0'. Это следует учитывать при описании соответствующего массива символов. Так, если строка должна содержать N символов, то в описании массива следует указать N+1 элемент.
Например, описание
char str[11];
предполагает, что строка содержит 10 символов, а последний байт зарезервирован под нулевой байт. Конечно, мы задали обычный одномерный массив, но если мы хотим трактовать его как строку символов, то это будет строка максимум из 10 элементов.
Хотя в языке C нет специального типа строки, язык допускает строковые константы. Строковая константа – это список литер, заключенных в двойные кавычки.
Например,
“Borland C++”, ”Это строковая константа”.
В конец строковой константы не надо ставить символ '\0', это сделает компилятор.
Есть два способа ввести строку с клавиатуры. Первый способ – воспользоваться функцией scanf() со спецификатором ввода %s. Надо помнить, что функция scanf() вводит символы до первого пробельного символа. Второй способ – воспользоваться специальной библиотечной функцией gets(), объявленной в файле stdio.h. Функция gets() позволяет вводить строки, содержащие пробелы. Ввод оканчивается нажатием клавиши Enter. В качестве параметра в этих функциях используется просто имя массива.
Вывод строк производится функциями printf() и puts(). Функция puts() добавляет в конце выводимой строки символ новой строки. В функции printf() переход на новую строку надо предусматривать в строке формата самим.
Рассмотрим пример.
# include <stdio.h>
/* Ввод строки с клавиатуры */
Void main()
{
char str[80]; /* Зарезервировали место для строки */
printf("Введите строку длиной менее 80 символов: ");
gets(str); /* читает строку с клавиатуры, пока не нажмете клавишу Enter */
printf("Вы ввели строку %s \n", str);
printf("Введите еще одну строку длиной менее 80 символов: ");
scanf("%s", str); /* читает строку с клавиатуры, пока не встретится пробел */
printf("Вы ввели строку ");
puts(str);
}
Для работы со строками существует специальная библиотека, описание которой находится в файле string.h.
Наиболее часто используются функции strcpy(), strcat(), strlen(), strcmp().
Рассмотрим их подробнее.
Вызов функции strcpy() имеет вид
strcpy(s1, s2);
Функция strcpy() используется для копирования содержимого строки s2 в строку s1. Массив s1 должен быть достаточно большим, чтобы в него поместилась строка s2. Если места мало, компилятор не выдает указания на ошибку или предупреждения; это не прервет выполнение программы, но может привести к порче других данных или самой программы и неправильной работе программы в дальнейшем.
Вызов функции strcat() имеет вид
strcat(s1, s2);
Функция strcat() присоединяет строку s2 к строке s1 и помещает ее в массив, где находилась строка s1,при этом строка s2 не изменяется. Нулевой байт, который завершал строку s1, будет заменен первым символом строки s2. И в функции strcpy(), и в функции strcat() получающаяся строка автоматически завершается нулевым байтом.
Рассмотрим простой пример использования этих функций.
# include <stdio.h>
# include <string.h>
Void main()
{
char s1[20], s2[20];
strcpy(s1,"Hello, ");
strcpy(s2,"World !");
puts(s1);
puts(s2);
strcat(s1,s2);
puts(s1);
puts(s2);
}
Вызов функции strcmp() имеет вид
Strcmp(s1,s2);
Функция strcmp() сравнивает строки s1 и s2 и возвращает значение 0, если строки равны, т.е. содержат одно и тоже число одинаковых символов. Под сравнением строк мы понимаем сравнение в лексикографическом смысле, так как это происходит, например, в словаре. Конечно, в функции происходит посимвольное сравнение кодов символов. Код первого символа одной строки сравнивается с кодом символа второй строки. Если они равны, рассматриваются вторые символы, и т.д. Если s1 лексикографически (в смысле словаря) больше s2, то функция strcmp() возвращает положительное значение, если меньше – отрицательное значение.
Вызов функции strlen() имеет вид
strlen(s);
Функция strlen() возвращает длину строки s, при этом завершающий нулевой байт не учитывается. Вызов length("Hello") вернет значение 5.
Рассмотрим применение этой функции для вычисления длины строки, вводимой с клавиатуры.
# include <stdio.h>
# include <string.h>
Void main()
{
char s[80];
printf("Введите строку: ");
gets(s);
printf("Строка \n %s \n имеет длину %d символов \n", s, strlen(s));
}
Инициализация массивов
Очень важно уметь инициализировать массивы, т.е. присваивать элементам массива некоторые значения. В языке C для этого имеются специальные возможности. Самый простой способ инициализации следующий: в процессе объявления массива указать в фигурных скобках список инициализаторов:
float farr[6]={1.1, 2.2, 3.3, 4.0, 5, 6};
Символьные массивы могут инициализироваться как обычный массив:
char str[15]={'B','o','r','l','a','n','d',' ','C','+','+'};
а могут – как строка символов:
char str[15]= "Borland C++";
Отличие этих двух способов состоит в том, что во втором случае будет добавлен еще и нулевой байт. К тому же второй способ короче.
Допускается также объявление и инициализация массива без явного указания размера массива. Например, для выделения места под символьный массив обычным способом
char str[80]="Это объявление и инициализация массива символов";
где мы должны считать количество символов в строке или указать заведомо, больший размер массива.
При инициализации массива без указания его размера
char str[ ]="Это объявление и инициализация массива символов";
где компилятор сам определит необходимое количество элементов массива, включая нулевой байт.
Можно объявить таким же способом массивы любого типа:
int mass[ ]={1, 2, 3, 1, 2, 3, 4};