Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015

Тут можно читать онлайн Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - бесплатно полную версию книги (целиком) без сокращений. Жанр: Прочая старинная литература, издательство Вильямс, год 0101. Здесь Вы можете читать полную версию (весь текст) онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.

Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - описание и краткое содержание, автор Стивен Прата, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)

Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать книгу онлайн бесплатно, автор Стивен Прата
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Определение этой функции ограничено; она будет работать только с массивами типа int, содержащими 10 элементов. Более гибкий подход предполагает передачу во втором аргументе размера массива:

int sumlint * ar, int n) // более общий подход

{

int i;

int total = 0;

for ( i = 0; i < n; i++) // используются n элементов

total += ar [i]; // ar [i] - то же самое, что и *(ar + i)

return total;

}

Здесь первый параметр сообщает функции, где находится массив и какой тип данных он содержит, а второй параметр уведомляет функцию о том, сколько элементов имеется в массиве.

Есть еще один момент, который необходимо отметить касательно параметров функции. В контексте прототипа или заголовка определения функции, и только в этом контексте, вместо int * ar можно подставить int ar[]:

int sum (int ar[] , int n);

Массивы и указатели 385

Форма int * ar всегда означает, что ar является типом указателя на int. Форма int ar[] также означает, что ar — тип указателя на int, но лишь тогда, когда он применяется для объявления формальных параметров. Вторая форма напоминает читателю кода о том, что ar не только указывает на int, но указывает на значение int, которое представляет собой элемент массива.

НА ЗАМЕТКУ! Объявление параметров массива

Поскольку имя массива — это адрес его первого элемента, фактический аргумент в виде имени массива требует, чтобы соответствующий формальный аргумент был указателем. В этом и только в этом контексте С интерпретирует int ar[] как int * ar, т.е. ar является типом указателя на int. Поскольку в прототипах разрешено опускать имя, все четыре приведенных ниже прототипа эквивалентны: int sumlint *ar, int n); int sum(int *, int); int sumlint ar[], int n); int sum(int[], int);

В определениях функций имена опускать нельзя, поэтому следующие две формы определения эквивалентны:

int sumlint *ar, int n)

{

// здесь находится код

}

int sum(int ar[], int n);

{

// здесь находится код

}

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

В листинге 10.10 показана программа, в которой применяется функция sum(). Чтобы отразить интересный факт, касающийся аргументов типа массива, в ней также выводится размер исходного массива и размер параметра функции, представляющего массив. (Если ваш компилятор не поддерживает спецификатор %zd, для вывода значений функции sizeof используйте спецификатор %u или, возможно, %lu.)

Листинг 10.10. Программа sum_arr1.c

386 Глава 10 Вывод в нашей системе имеет следующий вид Размер ar составляет - фото 296

386 Глава 10

Вывод в нашей системе имеет следующий вид Размер ar составляет 8 байтов Общая - фото 297

Вывод в нашей системе имеет следующий вид:

Размер ar составляет 8 байтов.

Общая сумма элементов массива marbles равна 190.

Объем памяти, отведенной под массив marbles, составляет 40 байтов.

Обратите внимание, что размер массива marbles равен 40 байтов. Это имеет смысл, т.к. массив marbles содержит 10 значений типа int, каждое из которых занимает 4 байта, что в сумме составляет 40 байт. Но размер ar равен всего 8 байтов. Причина в том, что ar — это не сам массив, а указатель на первый элемент marbles. В нашей системе для хранения адресов применяются 8 байтов, поэтому размером переменной типа указателя будет 8 байтов. (В других системах может использоваться другое количество байтов.) Короче говоря, в листинге 10.10 имя marbles — это массив, ar — указатель на первый элемент массива marbles, а связь между массивами и указателями в языке С позволяет применять форму записи массива вместе с указателем ar.

Использование параметров типа указателей

Функция, работающая с массивом, должна знать, где начинать и где заканчивать свое действие. В функции sum() используется параметр типа указателя для идентификации начала массива и целочисленный параметр, отражающий количество элементов массива, которые нужно обработать. (Параметр типа указателя также описывает тип данных в массиве.) Но это не единственный способ сообщения функции того, что она должна знать. Другой способ описания массива предусматривает передачу функции двух указателей, первый из которых отмечает, где массив начинается (как и раньше), а второй — где он заканчивается. Этот подход иллюстрируется в листинге 10.11. Здесь также задействован тот факт, что параметр типа указателя является переменной, так что вместо применения индекса для сообщения о том, к какому элементу массива обращаться, в функции можно изменять значение самого указателя, заставляя его по очереди указывать на каждый элемент массива.

Листинг 10.11. Программа sum arr2.c

Массивы и указатели 387 Указатель start начинает со ссылки на первый элемент - фото 298

Массивы и указатели 387

Указатель start начинает со ссылки на первый элемент marbles поэтому выражение - фото 299

Указатель start начинает со ссылки на первый элемент marbles, поэтому выражение присваивания total + = *start добавляет к total значение первого элемента (20). Затем выражение start++ инкрементирует переменную start, в результате чего она указывает на следующий элемент в массиве. Поскольку start указывает на тип int, ее значение увеличивается на размер типа int.

Обратите внимание, что для завершения цикла суммирования в функции sump() используется метод, отличающийся от применяемого в sum(). В качестве второго аргумента функции sum() выступает количество элементов, и это значение используется как часть проверки конца цикла:

for ( i = 0; i < n; i + +)

Однако в sump() для проверки окончания цикла применяется второй указатель:

while (start < end)

Поскольку производится проверка на предмет неравенства, последним обработанным элементом массива будет элемент, находящийся непосредственно перед элементом, на который указывает end. Это означает, что end в действительности указывает на ячейку, расположенную после финального элемента массива. В языке С гарантируется, что при выделении пространства памяти под массив указатель на первую ячейку после конца массива будет допустимым. Благодаря этому, конструкция подобного рода является допустимой, т.к. последним значением, которое start получает в цикле, будет end. Обратите внимание, что использование такого указателя на место “за пределами конца массива”, делает вызов функции лаконичным:

answer = sump(marbles, marbles + SIZE);

Из-за того, что индексация начинается с 0, marbles + SIZE указывает на элемент, следующий за концом массива. Если бы end указывал на последний элемент, а не на следующий за концом массива, пришлось бы применять такой код:

answer = sump(marbles, marbles + SIZE - 1);

Подобный код не только внешне менее элегантен, его еще и труднее запомнить, поэтому с большей вероятностью можно допустить ошибку. Между прочим, хотя язык С гарантирует допустимость указателя marbles + SIZE, нет никаких гарантий в отношении marbles [SIZE], т.е. значения, хранящегося в этой ячейке, поэтому программа не должна пытаться получить доступ к ней.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Стивен Прата читать все книги автора по порядку

Стивен Прата - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




Язык программирования C. Лекции и упражнения (6-е изд.) 2015 отзывы


Отзывы читателей о книге Язык программирования C. Лекции и упражнения (6-е изд.) 2015, автор: Стивен Прата. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x