ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.12.2020
Просмотров: 4311
Скачиваний: 28
Часть III. Стандартная библиотека языка программирования C
286
Память под многомерные динамические массивы выделяется по
строкам, начиная с первого индекса. Это делается для того, чтобы
обеспечить применение оператора индексирования
[]
столько
раз, какова размерность многомерного массива. В этом случае
тип динамического массива объявляется как указатель, который
содержит оператор обращения по адресу
*
столько раз, какова
размерность массива. Например, указатель на двумерный цело-
численный массив объявляется следующим образом:
int **a; /* указатель на двумерный массив */
В качестве примера в листингах 21.3 и 21.4 приведены тексты
функций
alloc_matr
и
free_matr
, которые соответственно дина-
мически выделяют и освобождают память для двумерной цело-
численной матрицы.
Листинг 21.3. Динамическое выделение памяти
под двумерную матрицу
#include <stdlib.h>
int** alloc_matr(int n, int m) /* n, m - диапазоны индексов */
{
int **a; /* указатель на матрицу */
int i, j;
/* захватываем память для указателей на строки */
a = (int**)malloc(n * sizeof(int*));
if (!a) /* если ошибка, то выходим из функции */
return NULL;
for (i = 0; i < n; ++i) /* захватываем память для строк */
{
a[i] = (int*)malloc(m * sizeof(int));
if (!a[i]) /* если ошибка, то освобождаем память */
{
for (j = 0; j < i; ++j)
free(a[j]);
free(a);
return NULL;
}
}
return a;
}
Глава 21. Стандартные функции <stdlib.h>
287
Листинг 21.4. Освобождение памяти, занятой двумерной матрицей
#include <stdlib.h>
/* a - адрес строк, n - количество строк */
void free_matr(int **a, int n)
{
int i;
for (i = 0; i < n; ++i)
free(a[i]);
free(a);
}
21.3. Стандартные функции
сортировки и поиска
На практике при работе с данными часто встречаются задачи
сортировки массива и поиска элементов в отсортированном мас-
сиве. Причем эти задачи нужно решать для массивов разных ти-
пов. Для решения таких задач в стандартной библиотеке языка
программирования C предназначены специальные функции
qsort
и
bsearch
.
Функция
qsort
выполняет сортировку массива, элементы которо-
го имеют произвольный тип. Эта функция реализует "быстрый
алгоритм" сортировки массивов и имеет следующий прототип:
void qsort(void *base, size_t n, size_t size,
int (*cmp)(const void *e1, const void *e2));
Параметры этой функции имеют следующее назначение:
base
— адрес массива;
n
— количество элементов в массиве;
size
— длина элемента массива;
cmp
— указатель на функцию сравнения.
Функция сравнения пишется программистом и предназначена для
сравнения элементов массива. Эту функцию стандартная функ-
ция сортировки вызывает через указатель, который задан пара-
Часть III. Стандартная библиотека языка программирования C
288
метром
cmp
. Функция сравнения должна возвращать одно из сле-
дующих значений:
отрицательное число, если элемент
e1
меньше элемента
e2
;
0, если элемент
e1
равен элементу
e2
;
положительное число, если элемент
e1
больше элемента
e2
.
Для поиска элемента в отсортированном массиве используется
функция
bsearch
, которая выполняет бинарный поиск элемента.
Эта функция имеет следующий прототип:
void* bsearch(const void *key, const void *base,
size_t n, size_t size,
int (*cmp)(const void *e1, const void *e2);
Первый параметр
key
этой функции является указателем на эле-
мент, который нужно найти. Остальные параметры повторяют
параметры функции
qsort
. В случае успешного завершения поис-
ка функция
bsearch
возвращает адрес найденного элемента, а в
случае неудачи
NULL
.
В листинге 21.5 приведена программа, в которой функции
qsort
и
bsearch
используются для сортировки целочисленного массива и
дальнейшего поиска элементов в этом отсортированном массиве.
Листинг 21.5. Сортировка целочисленного массива
и поиск элемента в этом массиве
#include <stdio.h>
#include <stdlib.h>
/* функция для сравнения элементов массива */
int comp_int(const int* e1, const int* e2)
{
return *e1 - *e2;
}
int main()
{
int n; /* размер массива */
int* a; /* массив */
int i; /* индекс */
Глава 21. Стандартные функции <stdlib.h>
289
int k; /* число для поиска */
int* s; /* индекс найденного числа */
/* введите размерность массива: */
printf("Input an array size: ");
scanf("%d", &n);
a = (int*)malloc(n*sizeof(int));
/* проверяем на нормальное завершение */
if (!a)
{
printf("Memory allocation failed.");
return 0;
}
/* вводим массив */
printf("Input elements: ");
for (i = 0; i < n; ++i)
scanf("%d", &a[i]);
/* сортируем массив */
qsort(a, n, sizeof(int),
(int (*)(const void*, const void*))comp_int);
/* выводим отсортированный массив */
printf("The sorted array: ");
for (i = 0; i < n; ++i)
printf("%d ", a[i]);
printf("\n");
/* вводим число для поиска */
printf("Input a number to search.\n>");
scanf("%d", &k);
/* поиск числа в отсортированном массиве */
if(!(s = (int*) bsearch(&k, a, n, sizeof(int),
(int (*)(const void*, const void*))comp_int)))
printf("There is no such an integer.\n");
else
printf("The integer index = %d.\n", s-a);
free(a);
return 0;
}
Часть III. Стандартная библиотека языка программирования C
290
21.4. Взаимодействие с системой
Для установки функций, которые вызываются при нормальном
завершении программы, используется функция
atexit
. Под нор-
мальным завершением программы здесь понимается выход из
функции
main
посредством выполнения инструкции
return
или
выход из программы посредством вызова функции
exit
. Функция
atexit
имеет следующий прототип:
int atexit(void (*f)(void));
Единственный параметр
f
этой функции является указателем на
функцию, которая не имеет параметров и не возвращает значе-
ние. В случае успешного завершения функция
atexit
возвраща-
ет
0
. Возможна установка до 32-х функций. Установленные функ-
ции вызываются системой в порядке, обратном их установке.
В листинге 21.6 приведен пример установки функции
fun
при
помощи функции
atexit
.
Листинг 21.6. Установка функции, исполняемой
перед завершением программы
#include <stdio.h>
#include <stdlib.h>
void fun(void)
{
printf("fun\n");
}
int main()
{
if (atexit(&fun)) /* устанавливаем функцию fun */
{
printf("atexit failed.\n");
return 1;
}
return 0; /* печать fun */
}
Для нормального завершения программы используется функция
exit
, которая имеет следующий прототип:
void exit(int status);