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

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

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

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Язык программирования C. Лекции и упражнения (6-е изд.) 2015»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

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

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

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Например, операция

_Pragma("nonstandardtreatmenttypeB on") является эквивалентом следующего указания:

#pragma nonstandardtreatmenttypeB on

Поскольку в этой операции не используется символ #, она может выступать в качестве части расширения макроса:

#define PRAGMA(X) _Pragma(#X)

#define LIMRG(X) PRAGMA(STDC CX_LIMITED_RANGE X)

После этого можно применять код вроде показанного ниже:

LIMRG ( ON )

Кстати, следующее определение не работает, хотя выглядит вполне корректным:

#define LIMRG(X) _Pragma(STDC CX_LIMITED_RANGE #X)

Проблема в том, что оно полагается на конкатенацию строк, но компилятор не выполняет конкатенацию до тех пор, пока не завершится работа препроцессора.

Оператор _Pragma выполняет всю работу по превращению из строк, т.е. управляющие последовательности в строке преобразуются в представляющие их символы. Таким образом, вызов операции

_Pragma("use_bool \"true \"false") принимает следующий вид:

#pragma use_bool "true "false

Обобщенный выбор (C11)

Термин обобщенное программирование относится к коду, который не является специфичным для конкретного типа, но после указания типа может транслироваться в код для этого типа. Например, язык C++ позволяет создавать обобщенные алгоритмы в форме шаблонов, которые компилятор затем использует при автоматическом создании экземпляра кода для указанного типа. В языке С нет ничего близко похожего на это. Тем не менее, в СИ появился новый вид выражения, называемого выражением обобщенного выбора, которое можно применять для выбора значения на основе типа выражения, т.е. базируясь на том, является ли типом выражения int, double и т.д. Выражение обобщенного выбора — это не оператор препроцессора, но обычно оно используется как часть определения макроса #define, обладающего определенными чертами обобщенного программирования.

Выражение обобщенного выбора выглядит следующим образом:

_Generic(x, int: 0, float: 1, double: 2, default: 3)

Здесь _Generic — новое ключевое слово С11. Круглые скобки после _Generic содержат несколько элементов, разделенных запятыми. Первый элемент представляет собой выражение, а каждый из оставшихся элементов — тип, за которым следует значение, наподобие float: 1. Тип первого элемента соответствует одной из меток, и значением всего выражения будет значение, указанное после давшей совпадение метки.

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

Например, предположим, что х в показанном выше выражении является переменной типа int. Тогда тип х соответствует метке int:, приводя к тому, что все выражение получает значение 0. Если тип не соответствует ни одной метке, значением всего выражения становится то, что указано после метки default:. Оператор обобщенного выбора немного похож на оператор switch за исключением того, что сопоставление с метками производится для типа выражения, а не его значения.

Давайте рассмотрим пример объединения оператора обобщенного выбора с определение макроса:

#define MYTYPE(X) _Generic((X),\ int: "int",\ float : "float",\ double: "double",\ default: "other"\

)

Вспомните, что макрос должен быть определен в одной логической строке, но с помощью символа \ одну логическую строку можно разбивать на несколько физических строк. В данном случае выражение обобщенного выбора оценивается как строка. Скажем, вызов макроса MYTYPE (5) оценивается как строка "int", поскольку тип значения 5 соответствует метке int:. В листинге 16.13 приведена дальнейшая иллюстрация этого макроса.

Листинг 16.13. Программа predef .с

Вот вывод программы int double другой другой В последних двух обращениях к - фото 507

Вот вывод программы:

int

double

другой

другой

В последних двух обращениях к MYTYPE() используются типы, не имеющие соответствующих меток, поэтому выбирается строка с меткой default:. Мы могли бы предусмотреть большее число меток, расширив возможности макроса, но этот пример задуман только в качестве демонстрации особенностей работы макросов, основанных

на _Generic.

688 глава 16

При оценке выражения обобщенного выбора программа не вычисляет первый элемент: она только выясняет его тип. Единственным вычисляемым выражением являет ся то, которое указано в совпадающей метке.

Средство _Generic можно применять для определения макросов, которые действуют подобно функциям, не зависящим от типа (“обобщенным”). В разделе, посвященном библиотеке math, далее в главе будет приведен пример.

Встраиваемые функции (С99)

Обычно с вызовом функции связаны накладные расходы. Это означает, что подготовка вызова, передача аргументов, переход к коду функции и возврат требуют време ни на выполнение. Как вы уже видели, макрос можно использовать для встраивания кода, тем самым избегая таких накладных расходов. В стандарте С99 был позаимствован у C++ (но не во всем точно) другой подход — встраиваемые функции. Исходя из его названия, вы могли бы ожидать, что встраиваемая функция заменяет вызов функции встраиваемым кодом, но это не так. В стандартах С99 и C11 на самом деле указано так: “превращение функции во встраиваемую предполагает, что ее вызов будет настолько быстрым, насколько это возможно. Степень, до которой подобные предположения эффективны, зависит от реализации”. Таким образом, преобразование функции во встроенную может привести к тому, что компилятор заменит вызов функции встраиваемым кодом и/или предпримет оптимизации другого рода либо вообще не окажет никакого воздействия.

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

Интервал:

Закладка:

Сделать

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

Представляем Вашему вниманию похожие книги на «Язык программирования C. Лекции и упражнения (6-е изд.) 2015» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


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

Обсуждение, отзывы о книге «Язык программирования C. Лекции и упражнения (6-е изд.) 2015» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x