Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

Операторы проверки особенно полезны для описания двух разновидностей инвариантов: предусловий и постусловий: условий, которые должны быть истинными соответственно перед и после исполнения сегмента кода. Простым примером предусловий и постусловий является линейный поиск:

/* lsearch --- возвратить индекс с данным значением в массиве или -1,

если не найдено */

int lsearch(int *array, size_t size, int value) {

 size_t i;

 /* предусловие: array != NULL */

 /*
предусловие: size > 0 */

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

if (array[i] == value)

return i;

 /* постусловие: i == size */

 return -1;

}

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

assert
:

#include <assert.h> /* ISO С */

void assert(/* скалярное выражение */);

Когда скалярное выражение ложно, макрос

assert
выводит диагностическое сообщение и завершает программу (с помощью функции
abort
; см. раздел 12.4 «Совершение самоубийства:
abort
»).
ch12-assert.c
снова предоставляет функцию
lsearch
, на этот раз с оператором проверки и функцией
main
:

1 /* ch12-assert.с --- демонстрация операторов проверки */

2

3 #include <stdio.h>

4 #include <assert.h>

5

6 /* lsearch --- возвращает индекс с данным значением в массиве или -1, если не найдено */

7

8 int lsearch(int *array, size_t size, int value)

9 {

10 size_t i;

11

12 assert(array != NULL);

13 assert(size > 0);

14 for (i = 0; i < size; i++)

15 if (array[i] == value)

16 return i;

17

18 assert(i == size);

19

20 return -1;

21 }

22

23 /* main --- проверить наши условия */

24

25 int main(void)

26 {

27 #define NELEMS 4

28 static int array[NELEMS] = { 1, 17, 42, 91 };

29 int index;

30

31 index = lsearch(array, NELEMS, 21);

32 assert(index == -1);

33

34 index = lsearch(array, NELEMS, 17);

35 assert(index == 1);

36

37 index = lsearch(NULL, NELEMS, 10); /* won't return */

38

39 printf("index = %d\n", index);

40

41 return 0;

42 }

После

компиляции и запуска оператор проверки в строке 12 «выстреливает»:

$ ch12-assert /* Запуск программы */

ch12-assert: ch12-assert.c:12: lsearch: Assertion 'array != ((void *)0)' failed.

Aborted (core dumped)

Сообщение от

assert
варьирует от системы к системе. Для GLIBC на GNU/Linux сообщение включает имя программы, имя файла с исходным кодом и номер строки, имя функции, а затем текст завершившегося неудачей условия. (В этом случае именованная константа
NULL
проявляется в виде своего макрорасширения '
((void*)0)'
.)

Сообщение '

Aborted (core dumped)
' означает, что
ch12-assert
создала файл
core
; т.е. снимок адресного пространства процесса непосредственно перед его завершением. [122] Этот файл может быть использован впоследствии с отладчиком; см. раздел 15.3 «Основы GDB». Создание файла
core
является намеренным побочным результатом
assert
; предполагается, что произошла решительная ошибка, и вы хотите исследовать процесс с помощью отладчика для ее определения.

122

Как упоминалось в разделе 10.2 «Действия сигналов», некоторые дистрибутивы GNU/Linux запрещают создание файлов

core
. Чтобы снова разрешить их, поместите в свой файл
~/.profile
строку '
ulimit -S -с unlimited
' — Примеч. автора.

Вы можете отменить оператор проверки, компилируя свою программу с помощью опции командной строки '

– DNDEBUG
'. Когда этот макрос определен до включения
<assert.h>
, макрос
assert
расширяется в код, который ничего не делает. Например:

$ gcc -DNDEBUG=1 ch12-assert.c -о ch12-assert /* Компиляция с -DNDEBUG */

$ ch12-assert /* Запуск */

Segmentation fault (core dumped) /* Что случилось? */

Здесь мы получили настоящий дамп ядра! Мы знаем, что операторы проверки были запрещены; сообщения «failed assertion» нет. Что же случилось? Рассмотрите строку 15

lsearch
при вызове из строки 37
main
. В этом случае переменная
array
равна
NULL
. Доступ к памяти через указатель
NULL
является ошибкой. (Технически различные стандарты оставляют «неопределенным» то, что происходит при разыменовывании указателя
NULL
. Наиболее современные системы делают то же, что и GNU/Linux; они завершают процесс, посылая ему сигнал
SIGSEGV
; это, в свою очередь, создает дамп ядра. Этот процесс описан в главе 10 «Сигналы».

Поделиться:
Популярные книги

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

Возвышение Меркурия. Книга 5

Кронос Александр
5. Меркурий
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 5