Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
YAZbIki.doc
Скачиваний:
8
Добавлен:
16.03.2015
Размер:
758.78 Кб
Скачать

Вопрос 15

15. Массивы в языке C, одномерные и многомерные. Инициализация массивов. Связь массивов с указателями. Передача массивов в качестве параметров в функцию. Строки как массивы символов.

Массивы и строки

Массив— это набор переменных одного типа, имеющих одно и то же имя. Доступ к конкретному элементу массива осуществляется с помощью индекса. В языке С все массивы располагаются в отдельной непрерывной области памяти. Первый элемент массива располагается по самому меньшему адресу, а последний — по самому большому. Массивы могут быть одномерными и многомерными.Строкапредставляет собой массив символьных переменных, заканчивающийся специальным нулевым символом, это наиболее распространенный тип массива.

Одномерные массивы

Общая форма объявления одномерного массива имеет следующий вид:

тип имя_переменной[размер];

Как и другие переменные, массив должен быть объявлен явно, чтобы компилятор выделил для него определенную область памяти (т.е. разместил массив). Здесь типобозначает базовый тип массива, являющийся типом каждого элемента.Размерзадает количество элементов массива. Например, следующий оператор объявляет массив из 100 элементов типа double под именем balance:

double balance[100];

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

Доступ к элементу массива осуществляется с помощью имени массива и индекса. Индекс элемента массива помещается в квадратных скобках после имени. Например, оператор

balance[3] = 12.23;

присваивает 3-му элементу массива balance значение 12.23.

Объем памяти, необходимый для хранения массива, непосредственно определяется его типом и размером. Для одномерного массива количество байтов памяти вычисляется следующим образом:

количество_байтов = sizeof(базовый_тип) × длина_массива

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

Создание указателя на массив

Указатель на 1-й элемент массива можно создать путем присваивания ему имени массива без индекса. Например, если есть объявление

int sample[10];

то в качестве указателя на 1-й элемент массива можно использовать имя sample. В следующем фрагменте программы адрес 1-го элемента массива sample присваивается указателю р:

int *p;

int sample[10];

p = sample;

В обеих переменных (р и sample) хранится адрес 1-го элемента, отличаются эти переменные только тем, что значение sample в программе изменять нельзя. Адрес первого элемента можно также получить, используя оператор получения адреса &. Например, выражения sample и &sample[0] имеют одно и то же значение. Тем не менее, в профессионально написанных программах вы не встретите выражения &sample[0].

Передача одномерного массива в функцию

В языке С нельзя передать весь массив как аргумент функции. Однако можно передать указатель на массив, т.е. имя массива без индекса. Например, в представленной программе в func1() передается указатель на массив i:

Если в функцию передается указатель на одномерный массив, то в самой функции его можно объявить одним из трех вариантов: как указатель, как массив определенного размера и как массив без определенного размера. Например, чтобы функция func1() получила доступ к значениям, хранящимся в массиве i, она может быть объявлена как

Эти три объявления тождественны, потому что каждое из них сообщает компилятору одно и то же: в функцию будет передан указатель на переменную целого типа. В первом объявлении используется указатель, во втором — стандартное объявление массива. В последнем примере измененная форма объявления массива сообщает компилятору, что в функцию будет передан массив неопределенной длины. Как видно, длина массива не имеет для функции никакого значения, потому что в С проверка границ массива не выполняется. Эту функцию можно объявить даже так:

И при этом программа будет выполнена правильно, потому что компилятор не создает массив из 32 элементов, а только подготавливает функцию к приему указателя.

Строки

Одномерный массив наиболее часто применяется в виде строки символов. Строка— это одномерный массив символов, заканчивающийся нулевым символом. В языке С признаком окончания строки (нулевым символом) служит символ '\0'. Таким образом, строка содержит символы, составляющие строку, а также нулевой символ. Это единственный вид строки, определенный в С.

На заметку

В C++ дополнительно определен специальный класс строк, называющийся String[1], который позволяет обрабатывать строки объектно-ориентированными методами. Стандарт С не поддерживает String.

Объявляя массив символов, предназначенный для хранения строки, необходимо предусмотреть место для нуля, т.е. указать его размер в объявлении на один символ больше, чем наибольшее предполагаемое количество символов. Например, объявление массива str, предназначенного для хранения строки из 10 символов, должно выглядеть так:

char str[11];

Последний, 11-й байт предназначен для нулевого символа.

Записанная в тексте программы строка символов, заключенных в двойные кавычки, является строковой константой, например,

"некоторая строка"

В конец строковой константы компилятор автоматически добавляет нулевой символ.

Для обработки строк в С определено много различных библиотечных функций. Чаще всего используются следующие функции:

Имя функции

Выполняемое действие

strcpy(s1,s2)

Копирование s2вs1

strcat(s1,s2)

Конкатенация (присоединение) s2в конецs1

strlen(s1)

Возвращает длину строки s1

strcmp(s1,s2)

Возвращает 0, если s1иs2совпадают, отрицательное значение, еслиs1<s2и положительное значение, еслиs1>s2

strchr(s1,ch)

Возвращает указатель на первое вхождение символа chв строкуs1

strstr(s1,s2)

Возвращает указатель на первое вхождение строки s2в строкуs1

Эти функции объявлены в заголовочном файле <string.h>. Применение библиотечных функций обработки строк иллюстрируется следующим примером:

Двухмерные массивы

Стандартом С определены многомерные массивы. Простейшая форма многомерного массива — двухмерный массив. Двухмерный массив — это массив одномерных массивов. Объявление двухмерного массива d с размерами 10 на 20 выглядит следующим образом:

int d[10][20];

Во многих языках измерения массива отделяются друг от друга запятой. В языке С каждое измерение заключено в свои квадратные скобки.

Аналогично обращению к элементу одномерного массива, обращение к элементу с индексами 1 и 2 двухмерного массива d выглядит так:

d[1][2]

Двухмерные массивы размещаются в матрице, состоящей из строк и столбцов. Первый индекс указывает номер строки, а второй — номер столбца. Это значит, что когда к элементам массива обращаются в том порядке, в котором они размещены в памяти, правый индекс изменяется быстрее, чем левый. Если двухмерный массив используется в качестве аргумента функции, то в нее передается только указатель на начальный элемент массива. В соответствующем параметре функции, получающем двухмерный массив, обязательно должен быть указан размер правого измерения[1], который равен длине строки массива. Размер левого измерения указывать не обязательно. Размер правого измерения необходим компилятору для того, чтобы внутри функции правильно вычислить адрес элемента массива, так как для этого компилятор должен знать длину строки массива. Массивы строк

В программах на языке С часто используются массивы строк. Например, сервер базы данных сверяет команды пользователей с массивом допустимых команд. В качестве массива строк в языке С служит двухмерный символьный массив. Размер левого измерения определяет количество строк, а правого — максимальную длину каждой строки. Например, в следующем операторе объявлен массив из 30 строк с максимальной длиной 79 символов:

char str_array[30][80];

Чтобы обратиться к отдельной строке массива, нужно указать только левый индекс. Например, вызов функции gets() с третьей строкой массива str_array в качестве аргумента можно записать так:

Многомерные массивы

В языке С можно пользоваться массивами, размерность которых больше двух. Общая форма объявления многомерного массива следующая:

тип имя_массива[Размер1][Размер2]...[РазмерN];

Массивы, у которых число измерений больше трех, используются довольно редко, потому что они занимают большой объем памяти. Например, четырехмерный массив символов размерностью 10x6x9x4 занимает 2160 байтов. Если бы массив содержал 2-байтовые целые, потребовалось бы 4320 байтов. Если бы элементы массива имели тип double, причем каждый элемент (вещественное число двойной точности) занимал бы 8 байтов, то для хранения массива потребовалось бы 17280 байтов. Объем требуемой памяти с ростом числа измерений растет экспоненциально. Например, если к предыдущему массиву добавить пятое измерение, причем его толщину по этому измерению сделать равной всего 10, то его объем возрастет до 172800 байтов.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]