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

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

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

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

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

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

Интервал:

Закладка:

Сделать

• Объявить массив, используя константные выражения для размерностей, и применять для доступа к элементам имя массива. Такой массив может быть создан с использованием либо статической, либо автоматической памяти.

• Объявить массив переменной длины, применяя переменные выражения для размерностей, и использовать для доступа к элементам имя массива. (Вспомните, что эта возможность предусмотрена стандартом С99.) Такой вариант доступен только для автоматической памяти.

• Объявить указатель, вызвать malloc(), присвоить возвращаемое значение указателю и применять для доступа к элементам указатель. Этот указатель может быть либо статическим, либо автоматическим.

Второй и третий методы можно использовать для выполнения того, что не получится сделать с обычным объявленным массивом — создать динамический массив, память под который выделяется во время выполнения программы и тогда же есть возможность выбрать его размер. Предположим, например, что n — целочисленная переменная. До выхода стандарта С99 нельзя было поступать так:

double item[n]; /* до С99: не разрешено, если n является переменной */

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

ptd = (double *) malloctn * sizeof(double)); /* нормально */

Этот прием работает и, как вы вскоре убедитесь, он обладает несколько большей гибкостью, чем массив переменной длины.

Обычно вы должны компенсировать каждый случай вызова malloc() вызовом free(). Функция free() принимает в качестве аргумента адрес, возвращенный ранее

Классы хранения, связывание и управление памятью 511

функцией malloc(), и освобождает память, которая была выделена. Таким образом, продолжительность существования выделенной памяти рассчитывается с момента, когда была вызвана функция malloc() для выделения памяти, и до момента, когда вызывается функция free() с целью освобождения памяти для ее повторного использования. Функции malloc() и free() можно рассматривать как инструменты для управления пулом памяти. Каждый вызов malloc() выделяет память для применения программой, а каждый вызов free() восстанавливает память в пуле, так что она может повторно использоваться. Аргументом free() должен быть указатель на блок памяти, выделенный malloc(); функцию free() нельзя применять для освобождения памяти, выделенной другими средствами, такими как объявление массива. Функции malloc() и free() имеют прототипы в заголовочном файле stdlib.h.

За счет использования malloc() программа может решать, массив какого размера требуется, и создавать его во время выполнения. Эта возможность демонстрируется в листинге 12.14. В нем указателю ptd присваивается адрес блока памяти, после чего ptd применяется, как если бы это было имя массива. Если выделить нужную память не удалось, для прекращения работы программы вызывается функция exit(), прототип которой содержится в stdlib.h. Значение EXIT_FAILURE определено в этом же заголовочном файле. Стандарт предоставляет два возвращаемых значения, которые гарантированно распознают все операционные системы: EXIT_SUCCESS (эквивалентно значению 0) для указания на нормальное завершение программы и EXIT FAILURE для указания на аварийное завершение. Некоторые операционные системы, включая Unix, Linux и Windows, могут принимать дополнительные целочисленные значения, обозначающие конкретные формы отказа.

Листинг 12.14. Программа dyn arr.с

512 глава 12 Ниже показаны результаты пробного запуска Мы ввели шесть - фото 400

512 глава 12

Ниже показаны результаты пробного запуска Мы ввели шесть чисел но программа - фото 401

Ниже показаны результаты пробного запуска. Мы ввели шесть чисел, но программа обработала только пять из них, поскольку размер массива был ограничен до 5.

Введите максимальное количество элементов типа double.

5

Введите значения (q для выхода) :

20 30 35 25 4 0 80

Введено 5 элементов:

20.00 30.00 35.00 25.00 40.00

Программа завершена.

Давайте рассмотрим код. Программа получает нужный размер массива с помощью следующих строк:

if (scanf ("%d", &max) != 1)

{

puts("Количество введено некорректно -- программа завершена."); exit(EXIT_FAILURE);

}

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

ptd = (double *) malloclmax * sizeof (double));

Приведение к (double * ) не обязательно в С, но требуется в C++, поэтому использование приведения типа упрощает перенос программы из С в C++.

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

if (ptd == NULL)

{

puts("Не удалось выделить память. Программа завершена."); exit(EXIT_FAILURE);

}

Если программа преодолеет это препятствие, она может трактовать ptd, как если бы оно было именем массива из max элементов, что и делается.

Обратите внимание на вызов функции free() ближе к концу программы. Она освобождает намять, выделенную malloc(). Функция free() освобождает только блок памяти, на который указывает ее аргумент. Некоторые операционные системы будут освобождать выделенную память автоматически при завершении программы, но другие могут этого не делать. Таким образом, применяйте free() и не полагайтесь на то, что операционная система выполнит очистку вместо вас.

Классы хранения, связывание и управление памятью 513

Какую пользу мы извлекли из того, что воспользовались динамическим массивом? В этом случае мы увеличили гибкость программы. Предположим, вы знаете, что большую часть времени программе будет требоваться не более 100 элементов, но иногда она будет нуждаться в 10 000 элементов. Если вы объявляете массив, то должны учитывать худший случай и объявить его с 10 000 элементов. Большую часть времени программа будет расходовать память понапрасну. К тому же, если наступит момент, когда понадобится иметь 10 001 элемент, программа потерпит отказ. Применение динамического массива позволяет программе подстраиваться под существующие обстоятельства.

Важность функции free()

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

Когда функция gobble вызывается в первый раз она создает указатель temp и - фото 402

Когда функция gobble() вызывается в первый раз, она создает указатель temp и применяет malloc() для выделения 16 000 байтов памяти (мы исходим из предположения, что тип double занимает 8 байтов). Представим, что мы не вызвали free(), как показано в коде. Когда gobble() завершится, указатель temp, будучи автоматической переменной, исчезает. Но 16 000 байтов памяти, на которые он указывал, по-прежнему существуют. Доступ к этой памяти невозможен, т.к. мы больше не располагаем ее адресом. Она не может использоваться повторно, потому что не была вызвана функция free().

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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