|
Программирование >> Процедурные приложения
Глава 8. Массивы Что такое массивы Свойства массивов Объявления массивов Инициализация массивов o Инициализация по умолчанию o Явная инициализация o Инициализация безразмерных массивов Доступ к элементам массива Вычисление размера массива в байтах Выход за пределы массива Массивы символов Многомерные массивы Массивы как аргументы функций o Передача массивов функциям в языке С o Передача массивов функциям в языке C++ Функции работы со строками и массивы символов o Функции gets(), puts(), fgets(), fputs() и sprintf() o Функции strcpy(), strcat(), strncmp() и strlen() В этой главе вы узнаете, как создавать массивы данных и работать с ними. В C/C++ темы массивов, указателей и строк взаимосвязаны, во многих книгах они даже рассматриваются в одной главе. С нашей точки зрения, это не лучший подход, поскольку часто для работы с массивами не требуется глубокого знания указателей. Кроме того, с массивами в целом связан достаточно большой объем материала, и параллельное изучение указателей может совершенно запутать дело. В то же время, без уяснения принципов использования указателей вы не сможете полноценно работать с массивами. Поэтому главу Указатели можно рассматривать как завершение дискуссии о массивах. Что такое массивы Массив можно представить как переменную, содержащую упорядоченный набор данных одного типа. К каждому элементу массива можно получить доступ по его адресу. В языках C/C++ массив не является стандартным типом данных. Напротив, он сам имеет тип: char, int, float, doubleи т.д. Допускается создавать массивы массивов, указателей, структур и др. Принципы построения массивов и работы с ними в основе своей одинаковы в С и C++. Свойства массивов Ниже перечислены четыре основных принципа, определяющих свойства массивов: в массиве хранятся отдельные значения, которые называются элементами; все элементы массива должны быть одного типа; все элементы массива сохраняются в памяти последовательно, и первый элемент имеет нулевое смещение адреса, т.е. нулевой индекс; имя массива является константой и содержит адрес первого элемента массива. Поскольку все элементы массива имеют одинаковый, заранее установленный размер, а имя массива содержит адрес первого его элемента, то нетрудно вычислить адрес любого другого элемента. Но при этом должен соблюдаться еще один принцип - строгой последовательности хранения в памяти всех элементов массива, от нулевого до последнего, причем первый элемент имеет наименьший адрес, а последний - наибольший. Имя массива представляет собой константное значение, которое не изменяется в ходе выполнения программы, поэтому оно не может размещаться слева от оператора присваивания, т.е. не является левосторонним значением. Если бы этого ограничения не существовало, программа могла бы изменять содержимое имени, а смысл подобного изменения состоял бы в замене адреса нулевого элемента массива. На первый взгляд кажется, что данное ограничение малозначительно, но на самом деле определенные выражения, выглядящие вполне корректными, оказываются недопустимыми. Объявления массивов Ниже даны примеры объявления массивов: intiarray[12]; /* массив из двенадцати целых чисел */ charcarray[20]; /* массив из двадцати символов */ Как и в случае обычных переменных, объявление массива начинается с указания типа данных, после чего следует имя массива и пара квадратных скобок, заключающих константное выражение, которое определяет размер массива. Внутри квадратных скобок может стоять только константа, но не имя переменной, чтобы компилятор точно знал, какой объем памяти резервировать. Таким образом, размер массива должен быть известен заранее и не может быть изменен в ходе выполнения программы. Вот как устанавливаются размеры массивов с помощью констант: #define iARRAY MAX 20 #define fARRAY MAX 15 int iarray[iARRAY MAX]; char farray[fARRAY MAX]; Подобное использование макроконстант позволяет избежать ошибок, связанных с обращением к несуществующим элементам массива. Например, последовательный доступ к массиву часто организуется с помощью цикла for: #include <stdio.h> #define iARRAY MAX 20 int iarray[iARRAY MAX]; main (} { int i; for(i= 0; i < iARRAY MAX; i++) { } return(-0); } Инициализация массивов Массив можно инициализировать одним из трех способов: при создании массива - используя инициализацию по умолчанию (этот метод применяется только для глобальных и статических массивов); при создании массива - явно указывая начальные константные значения; в процессе выполнения программы - путем записи данных в массив. При создании в массив могут быть занесены только константные значения. Впоследствии в массив можно записывать и значения переменных. Инициализация по умолчанию В соответствии со стандартом ANSI глобальные массивы (расположенные вне любой функции), а также массивы, объявленные статическими внутри функции, по умолчанию заполняются нулями, если не заданы начальные значения элементов массива. Массивы указателей заполняются значениями null. Проверить вышесказанное можно на следующем примере: .* initar.c * Эта программа на языке С демонстрирует инициализацию массивов, * выполняемую по умолчанию. #include <stdio.h> #define iGLOBAL ARRAY SIZE 10 #define iSTATIC ARRAY SIZE 20 int iglobal array[iGLOBAL ARRAY SIZE]; /* глобальный массив */ main () { static int istatic array[iSTATIC ARRAY SIZE]; /* статический массив */ int i; for (i = 0; i < iGLOBAL ARRAY SIZE; i++) printf ( iglobal array [%d].:%d\n ,i, iglobal array [i] ) for(i= 0; i < iSTATIC ARRAY SIZE; i++) printf( istatic array[%d]: %d\n , i, istatic array[i]); return(0); } После запуска программы на экран будут выведены нулевые значения, присвоенные элементам массива по умолчанию. Данная программа выявляет еще один существенный момент работы с массивами: первый элемент массива всегда имеет нулевой индекс. Это связано с тем, что создатели языка С стремились максимально приблизить его к ассемблерным языкам, где первый элемент таблицы всегда имеет нулевое смещение. Явная инициализация Согласно стандарту ANSI элементам как глобальных, так и локальных массивов можно явно присваивать начальные значения. В следующем фрагменте программы содержится объявление четырех массивов, инициализируемых явно: int iarray[3] = {-1,0, 1}; static float fpercent[4] = {1.141579,0.75,55E0,-.33E1); static int ideoimal[3] = {0,1, 2, 3, 4, 5, 6, 7, 8, 9}; char cvowels[] = {A,a,E,e,I,i,O,o,U,u}; В первой строке создается массив iarray, содержащий три целочисленных элемента, значения которых, разделенные запятыми, указаны в фигурных скобках. В результате еще при запуске программы резервирование ячеек памяти для массива iarrayбудет сопровождаться одновременной записью значений в эти ячейки. Обратите внимание не только на удобство этого метода, но и на то, что инициализация массива выполняется еще до начала выполнения программы. Некоторые компиляторы позволяют проводить инициализацию только глобальных и статических массивов, как, например, во второй строке программы. В третьей строке показан пример задания большего числа элементов массива, чем в нем на самом деле содержится. Многие компиляторы рассматривают подобную ситуацию как ошибку, тогда как другие автоматически увеличивают размер массива, чтобы вместить дополнительные элементы. Компилятор MicrosoftVisualC++ выдаст ошибку вида too many initializers (слишком много инициализаторов). В противоположной ситуации, когда при инициализации указано меньше значений, чем элементов массива, оставшиеся элементы по умолчанию примут нулевые значения. С учетом этого можно вообще не задавать размер массива, как в четвертой строке программы. Количество значений, указанных в фигурных скобках, автоматически определит размер массива. Инициализация безразмерных массивов
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |