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

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

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

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

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

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

Интервал:

Закладка:

Сделать

#include

int comp(const void * p1, const void * p2) /* обязательная форма */

{

/* получение правильного типа указателя */ const struct names *psl = (const struct names *) p1; const struct names *ps2 = (const struct names *) p2; int res;

res = strcmp(psl->last, ps2->last); /* сравнение фамилий */

if (res |= 0) return res;

else /* фамилии одинаковы, поэтому сравнить имена */

return strcmp(psl->first, ps2->first);

)

В данной функции сравнение осуществляется с помощью функции strcmp(), которая возвращает значения, удовлетворяющие требованиям к функции сравнения. Обратите внимание, что для применения операции -> необходим указатель на структуру.

Библиотека утверждений

Библиотека утверждений, поддерживаемая заголовочным файлом assert.h — это небольшая библиотека, предназначенная для оказания содействия при отладке программы. Она состоит из макроса по имени assert(). Макрос принимает в качестве аргумента целочисленное выражение. Если выражение оценивается как ложное (ненулевое), макрос assert() выводит в стандартный поток ошибок (stderr) сообщение об ошибке и вызывает функцию abort(), которая прекращает выполнение программы. (Прототип функции abort() находится в заголовочном файле stdlib.h.) Идея состоит в том, чтобы идентифицировать критические места в программе, где должны быть истинными определенные условия, и с помощью оператора assert() завершать программу, если одно из указанных условий нарушается. Обычно аргументом служит выражение отношения или логическое выражение. Когда assert() прекращает выполнение программы, сначала отображается не прошедший проверку тест, имя файла, содержащего этот тест, и номер строки, где находится тест.

Использование assert()

В листинге 16.18 приведен простой пример применения assert(). В нем утверждается, что значение z должно быть больше или равно 0, прежде чем будет предпринята попытка извлечь из него квадратный корень. Кроме того, ошибочно выполняется вычитание значения вместо его сложения, делая возможным получение переменной z недопустимого значения.

Препроцессор и библиотека С 705

Листинг 16.18. Программа assert.с

Ниже показаны результаты пробного запуска Введите пару чисел 0 0 для - фото 520

Ниже показаны результаты пробного запуска:

Введите пару чисел (0 0 для завершения) :

4 3

результатом является 2.645751

Введите следующую пару чисел:

5 3

результатом является 4.000000

Введите следующую пару чисел:

3 5

Assertion failed: (z >= 0), function main, file /Users/assert.c, line 14.

Отказ утверждения: (z >= 0), функция main, файл /Users/assert. с, строка 14.

Точный текст в последней строке зависит от компилятора. Потенциально может сбивать с толку то, что в сообщении не говорится об условии z >= 0; вместо этого в нем уведомляется о том, что отказало утверждение z >= 0.

Чего-то похожего можно было бы добиться с помощью оператора if:

if (z < 0)

{

puts("z меньше 0"); abort();

}

Тем не менее, подход с assert() обладает рядом преимуществ. Он автоматически идентифицирует файл и номер строки, где возникла проблема. Наконец, существует механизм включения и отключения макроса assert() без необходимости в изменении кода. Если вы считаете, что устранили ошибки в программе, поместите следующее определение макроса

#define NDEBUG

перед местом включения файла assert .h, повторно скомпилируйте программу, и компилятор отключит в файле все операторы assert(). Если проблема возникнет снова, можете удалить директиву #define (или закомментировать ее) и провести повторную компиляцию, в результате чего все операторы assert() снова активизируются.

706 глава 16

_Static_assert (С11)

Выражение assert() проверяется во время выполнения. В С11 появилось новое средство в форме объявления _Static_assert, которое осуществляет проверку на этапе компиляции. Таким образом, assert() может привести к прерыванию выполняющейся программы, тогда как _Static_assert() может стать причиной того, что программа не компилируется. Объявление _Static_assert принимает два аргумента. Первым из них является целочисленное константное выражение, а вторым — строка. Если выражение оценивается в 0 (или _False), то компилятор отобразит строку, и не будет компилировать программу. Давайте рассмотрим короткий пример в листинге 16.19, после чего взглянем на отличия между assert() и _Static_assert().

Листинг 16.19. Программа statasrt.c

Ниже показана попытка проведения компиляции в командной строке clang - фото 521

Ниже показана попытка проведения компиляции в командной строке:

$ clang statasrt.c

statasrt.с:4:1: error: static_assert failed "Ошибочно предполагается 16битовый тип char"

_Static_assert(CHAR_BIT == 16, "Ошибочно предполагается 16-битовый тип char");

1 error generated.

$

statasrt.с;4;1; ошибка: отказ static_assert "Ошибочно предполагается 16битовый тип char"

_Static_assert (CHAR_BIT == 16, "Ошибочно предполагается 16-битовый тип char");

1 ошибка сгенерирована.

$

Синтаксически _Static_assert трактуется как оператор объявления. Следовательно, в отличие от большинства разновидностей операторов С, он может находиться либо в функции, либо (как в данном случае) быть внешним по отношению к функции.

Требование о том, что первым аргументом в _Static_assert должно быть целочисленное константное выражение, гарантирует возможность его оценки на этапе компиляции. (Вспомните, что выражения sizeof считаются целочисленными константами.) Поэтому в листинге 16.18 вы не можете подставить _Static_assert вместо assert(), т.к. для проверочного выражения в программе используется z > 0, которое является неконстантным и может быть вычислено только во время выполнения. В листинге 16.19 можно было бы применить assert (CHAR_BIT ==16) в теле main(), но это привело бы к выдаче предупреждения об ошибке лишь после компиляции и запуска программы, что менее эффективно.

Препроцессор и библиотека С 707

В заголовочном файле assert.h идентификатор static_assert определен как псевдоним для ключевого слова _Static_assert. Это делает С более совместимым с языком C++, в котором для рассмотренной возможности static assert используется в качестве ключевого слова.

Функции memcpy() И memmove()

ИЗ библиотеки string.h

Присваивать один массив другому нельзя, поэтому в таких случаях мы применяли циклы для поэлементного копирования одного массива в другой. Единственное исключение состоит в том, что для символьных массивов мы использовали функции strcpy() и strncpy(). Функции memcpy() и memmove() предлагают почти такие же услуги для других видов массивов. Рассмотрим прототипы этих функций:

void *memcpy(void * restrict si, const void * restrict s2, size_t n);

void *memmove (void *sl, const void *s2, size_t n);

Обе функции копируют n байтов из области, на которую указывает аргумент s2, в область, указанную аргументом si, и обе они возвращают значение si. Различие между этими двумя функциями, как указывает ключевое слово restrict, связано с тем, что memcpy() разрешено полагать, что две области памяти нигде не перекрываются друг с другом. Функция memmove() не делает такого предположения, поэтому копирование происходит так, как будто все байты сначала помещаются во временный буфер и только затем копируются в область назначения. Что произойдет, если применить memcpy() к перекрывающимся областям? В этом случае поведение функции не определено, т.е. она может как работать, так и не работать. Компилятор не запрещает использование функции memcpy(), когда этого делать не следует, поэтому именно вы несете ответственность за обеспечение того, что области памяти не перекрываются. Это еще одна часть тяжкой нощи программиста.

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

Интервал:

Закладка:

Сделать


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

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




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


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


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

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