Лекции Булатицкий Дмитрий Иванович (во многом по материалам Прасолова А. Н.)
![]()
|
Пример использования динамической памятиВ следующем примере динамическая память используется для хранения элементов массива заранее неопределенного размера, ввод которого прекращается при появлении во входном потоке числа больше или равного 1e300. При этом, вначале под массив выделяется сегмент памяти, максимального размера, затем размер блока памяти устанавливается соответствующим фактическому размеру массива. #include #include #include #include #include void * Malloc( size_t size ) { void *p = malloc(size); if( !p ) { printf("Недостаточно памяти!\n"); exit(1); } return p; } void * Realloc ( void *block, size_t size ) { void *p = realloc(block, size); if( !p ) { printf("Недостаточно памяти!\n"); exit(1); } return p; } void main(void) { double *A, temp; unsigned i, n, maxN, goodIO; A = (double *) Malloc( maxN = UINT_MAX ); maxN /= sizeof(double); for(goodIO = n = 0; n < maxN; n++) { printf("A[%d] = ", n); scanf("%lf", &temp); if(temp >= 1e300) { goodIO = 1; break; } A[n] = temp; } if(goodIO) { A = (double *) Realloc(A, n * sizeof(double)); /* Обработка массива. Для примера - печать. */ for(i = 0; i < n; i++) { printf("%10.3lf ", A[i]); if( (i + 6) % 5 == 0 ) printf("\n"); if( (i + 121) % 120 == 0 ) { getch(); clrscr(); } } printf("\n"); } free(A); } Максимальный размер сегмента в байтах всегда равен величине наибольшего беззнакового целого числа, значение которого определяет константа UINT_MAX из заголовочного файла В программе используются вспомогательные функции Malloc() и Realloc() для обеспечения контроля выделения памяти. В них функция exit() с прототипом в файле Модульное программированиеМногофайловый проектБольшинство современных программных продуктов невозможно разработать и отладить, размещая все функции проекта в одном файле. Ранние версии компиляторов даже имели ограничение на размер файла исходного текста в 64 килобайта. Поэтому, компиляторы всех фирм без исключения имеют средства модульного программирования, позволяющие разрабатывать, тестировать и отлаживать проект по частям, разбивая его на модули. Модуль представляет собой наименьшую неделимую часть программы. Модуль только целиком может быть добавлен к программе и только целиком из нее удален, даже в тех случаях, когда он содержит функции, к которым нет обращений. Каждый файл исходного текста программы на языке СИ после компиляции образует отдельный модуль. Программа собирается из отдельных модулей, находящихся на диске, и библиотечных модулей с помощью специальной программы, называемой компоновщиком или редактором связей. Компоновщик можно вызвать явно из командной строки MS DOS, или неявно из интегрированной среды разработки программ. Имена всех модулей и библиотек функций, используемых в проекте, заносятся в файл проекта с помощью средств конкретной системы программирования и, в дальнейшем, среда разработки программ автоматически отслеживает все изменения в исходных файлах проекта, автоматически компилирую и собирая новые версии программы. Библиотеки функцийПри разработке программных проектов, состоящих из большого числа модулей, целесообразно пользоваться библиотеками модулей. Каждая такая библиотека обычно имеет расширение *.lib и может быть включена в проект с помощью средств поддержки проекта. Особенностью использования библиотек является тот факт, что компоновщик будет обращаться к библиотеке и выбирать оттуда необходимые модули только по мере необходимости, то есть, если имеются ссылки к функциям библиотечного модуля. Следует помнить, что модуль будет выбран из библиотеки и подключен к программе всегда целиком, даже если на самом деле программе требуется всего лишь одна функция. Для создания библиотек функций используются программы, называемые библиотекарями. В системе программирования фирмы Borland библиотекарь имеет имя tlib и может быть вызван из командной строки следующим образом: БНФ: "tlib " имя_библ ["/C"] ["/E"] команды [, файл_огл] где имя_библиотеки - имя файла с создаваемой или модифицируемой библиотекой; команды - последовательность команд модифицирующих библиотеку; файл_огл - имя файла, в который будет помещено оглавление библиотеки; /C - ключ, при наличии которого библиотекарь различает прописные и строчные буквы в именах внешних функций; /E - клич, при наличии которого библиотекарь создает расширенный словарь. Каждая команда модификации библиотеки имеет следующую форму: БНФ: ("+" | "-" | "*" | "-+" | "-*") имя_модуля где имя_модуля - имя скомпилированного модуля без расширения. Символ "+" добавляет новый модуль в библиотеку, символ "-" удаляет модуль из библиотеки, символ "*" извлекает модуль из библиотеки без его удаления, символы "-+" или "+-" заменяют модуль в библиотеке, символы "-*" или "*-" извлекают и удаляют модуль из библиотеки. Например, следующий вызов библиотекаря tlib graph +line +draw +point, graph создаст в текущем каталоге новую библиотеку с именем graph.lib, в которую будут добавлены модули line.obj, draw.obj и point.obj. Кроме того будет создан файл с оглавлением библиотеки, имеющий имя graph.lst. |