Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Например, 5 — литерал типа int, 81.3— литерал типа double, 1У — литерал типа char, a "elephant" — строковый литерал. В комитете, разрабатывающем стандарт С99, пришли к соглашению, что было бы удобно иметь составные литералы, которые могли бы представлять содержимое массивов и структур.
Для массивов составной литерал выглядит подобно списку инициализации массива, который предварен именем типа, заключенным в круглые скобки. Например, вот обычное объявление массива:
int diva[2] = {10, 20};
А вот составной литерал, который создает неименованный массив, содержащий те же два значения int:
(int [2]){10, 20} // составной литерал
Обратите внимание, что имя типа — это то, что остается после удаления diva из предыдущего объявления, т.е. int [2].
Точно так же, как размер массива можно не указывать во время инициализации именованного массива, его можно опускать в составном литерале, и компилятор подсчитает количество присутствующих элементов:
(int[]){50, 20, 90} // составной литерал с тремя элементами
Поскольку эти составные литералы не имеют имени, нельзя просто создать их в одном операторе и затем использовать их позже. Вместо этого они должны каким-то образом применяться при создании. Один из способов предусматривает использование указателя для отслеживания ячейки памяти. То есть вы можете поступить пример но так:
int * ptl;
ptl = (int [2]) {10, 20};
Как видите, эта литеральная константа идентифицируется как массив значений int. Подобно имени массива эта константа транслируется в адрес первого элемента, поэтому ее можно присвоить указателю на тип int. После этого указатель можно применять далее в коде. Например, *ptl в данном случае будет иметь значение 10, а
ptl [1] - 20.
Еще одним возможным действием с составным литералом будет его передача в качестве фактического аргумента функции с совпадающим формальным параметром:
int sum(const int ar[], int n);
int total3;
total3 = sum((int[]) {4,4,4,5,5,5}, 6);
Здесь первый аргумент представляет собой массив из шести элементов int, который действует как адрес первого элемента, т.е. так же, как имя массива. Такой вид использования, при котором информация передается функции без необходимости заранее создавать массив, типичен для составных литералов.
Массивы и указатели 411
Этот прием можно распространить на двумерные и многомерные массивы. Ниже приведен пример создания двумерного массива значений int и сохранения его адреса:
int (*pt2) [4]; // объявление указателя на массив из массивов с 4 значениями int pt2 = (int [2] [4]> { (1,2,3,-9}, {4,5,6,-8} };
В данном случае типом является int [2] [4] — массив 2x4 значений int.
В листинге 10.19 все эти примеры объединены в одну завершенную программу.
Листинг 10.19. Программа flc.c
Вам понадобится компилятор, принимающий данное дополнение стандарта С99 (не все компиляторы делают это). Вот вывод этой программы:
412 Глава Ю
Имейте в виду, что составной литерал — это средство для предоставления значений, которые нужны лишь временно. Его область действия ограничена блоком, как будет прояснено в главе 12. Это значит, что его существование не гарантируется после того, как поток выполнения программы покинет блок, в котором определен составной литерал, т.е. самую внутреннюю пару фигурных скобок, содержащую определение.
Ключевые понятия
Когда возникает необходимость хранить множество значений одного вида, решением может быть массив. В языке С массивы считаются производными типами, поскольку они построены на основе других типов. Другими словами, вы объявляете не просто массив, а массив значений int, float или какого-то другого типа. Такой тип сам но себе может быть типом массива, что дает в итоге массив из массивов, или двумерный массив.
Часто полезно создавать функции для обработки массивов; это содействует модульности программы за счет размещения специфических задач в специализированных функциях. Важно понимать, что когда вы используете имя массива в качестве фактического аргумента, то функции не передается весь массив целиком, а только его адрес (следовательно, соответствующий формальный параметр является указателем). Чтобы обработать этот массив, функция должна знать, где хранится массив и сколько элементов он содержит. Адрес массива сообщает о том, где он находится, а данные о количестве элементов должны либо быть встроенными в функцию, либо передаваться ей в отдельном аргументе. Второй подход более универсален, поэтому одна и та же функция может работать с массивами разных размеров.
Связь между массивами и указателями настолько тесная, что часто одну и ту же операцию можно представить с применением либо формы записи с массивами, либо формы записи с указателями. Именно эта связь позволяет использовать внутри функции, обрабатывающей массивы, форму записи с массивами даже в случае, когда формальный параметр является указателем, а не массивом.
В языке С размер обычного массива должен быть задан с помощью константного выражения, поэтому он определяется на этапе компиляции. Стандарты С99/С11 предлагают альтернативу в виде массивов переменной длины, когда спецификатором размера может быть переменная. Это позволяет откладывать установку размера массива переменной длины до времени выполнения программы.
Резюме
Массив — это набор элементов, которые имеют один и тот же тип данных. Элементы массива хранятся в памяти последовательно, а доступ к ним осуществляется с применением целочисленного индекса (или смещения). В языке С первый элемент массива имеет индекс 0, поэтому последний элемент в массиве из n элементов имеет индекс п-1. Ответственность за обеспечение допустимости используемых индексов возлагается на программиста, поскольку ни компилятор, ни выполняющаяся программа не должны ее проверять.
Для объявления простого одномерного массива применяется следующая форма:
тип имя [размер];
Здесь тип — это тип данных каждого элемента массива, имя — имя массива, а размер — количество элементов. Традиционно язык С требовал, чтобы размер был константным целочисленным выражением. Стандарт С99/С11/С11 разрешает ис-
Массивы и указатели 413
пользовать неконстантное целочисленное выражение; в таком случае массив называется массивом переменной длины.
В С имя массива интерпретируется как адрес первого элемента этого массива. Другими словами, имя массива эквивалентно указателю на его первый элемент. В целом массивы и указатели тесно связаны друг с другом. Если ar — это массив, то выражения ar [1] и * (ar + i) эквивалентны.
Читать дальшеИнтервал:
Закладка: