Директивы #if, #elif, #else и #endif (C/C++)
Директива #if с директивами #elif, #else и #endif управляет компиляцией частей исходного файла. Если написанное выражение (после #if) имеет ненулевое значение, группа строк сразу после директивы #if хранится в модуле перевода.
грамматики
if-line :
#if констант-выражение
идентификатор #ifdef
идентификатор #ifndef
elif-parts :
текст с элифовой линией
текст elif-parts elif-line
elif-line :
#elif констант-выражение
else-part :
Текст в другой строке
else-line :
#else
endif-line :
#endif
Замечания
Каждая директива #if в исходном файле должна соответствовать закрывающей директиве #endif . Любое количество директив #elif может отображаться между директивами #if и #endif , но в большинстве случаев допускается одна директива #else . Директива #else, если она присутствует, должна быть последней директивой перед #endif.
Директивы #if, #elif, #else и #endif могут вложены в текстовые части других директив #if. Каждая вложенная директива #else, #elif или #endif принадлежит ближайшей предыдущей директиве #if.
Все директивы условной компиляции, такие как #if и #ifdef, должны соответствовать закрывающей директиве #endif до окончания файла. В противном случае создается сообщение об ошибке. Если директивы условной компиляции содержатся во включаемых файлах, они должны удовлетворять одинаковым условиям: в конце включаемого файла не должно оставаться непарных директив условной компиляции.
Замена макросов выполняется в части строки, которая следует #elif команде, поэтому вызов макроса можно использовать в констант-выражении.
Препроцессор выбирает один из указанных вхождения текста для дальнейшей обработки. Блок, указанный в тексте , может быть любой последовательностью текста. Он может занимать несколько строк. Обычно текст — это программный текст , который имеет значение для компилятора или препроцессора.
Препроцессор обрабатывает выделенный текст и передает его компилятору. Если текст содержит директивы препроцессора, препроцессор выполняет эти директивы. Компилируются только текстовые блоки, выбранные препроцессором.
Препроцессор выбирает один текстовый элемент, оценивая константное выражение после каждой #if или директивы #elif, пока не находит истинное (ненулевое) константное выражение. Он выбирает весь текст (включая другие директивы препроцессора, начиная с#) до связанного #elif, #else или #endif.
Если все вхождения констант-выражения являются ложными или если директивы #elif не отображаются, препроцессор выбирает блок текста после предложения #else. Если нет предложения #else, а все экземпляры константного выражения в блоке #if имеют значение false, текстовый блок не выбран.
Константное выражение — это целочисленное константное выражение с этими дополнительными ограничениями:
- Выражения должны иметь целочисленный тип и могут включать только целые константы, константы символов и определенный оператор.
- Выражение не может использовать sizeof или оператор приведения типа.
- Целевая среда может не представлять все диапазоны целых чисел.
- Перевод представляет тип так же, как и тип intlong , и тот же способ, что unsigned long и unsigned int .
- Транслятор может преобразовывать символьные константы в набор кодовых значений, отличающийся от набора для целевой среды. Чтобы определить свойства целевой среды, используйте приложение, созданное для этой среды, для проверка значений LIMITS. Макросы H.
- Выражение не должно запрашивать среду и оставаться изолированным от сведений о реализации на целевом компьютере.
Операторы препроцессора
архитектура
Определяемый оператор препроцессора можно использовать в специальных константных выражениях, как показано в следующем синтаксисе:
defined(identifier)
определенныйидентификатор
Это константное выражение считается истинным (ненулевое), если идентификатор определен в данный момент. В противном случае условие не выполняется (false, значение равно 0). Идентификатор, определенный как пустой текст, считается определенным. Определенный оператор можно использовать в #if и директиве #elif, но нигде.
В следующем примере директивы #if и #endif управляют компиляцией одного из трех вызовов функций:
#if defined(CREDIT) credit(); #elif defined(DEBIT) debit(); #else printerror(); #endif
Вызов функции credit компилируется, если определен идентификатор CREDIT . Если определен идентификатор DEBIT , компилируется вызов функции debit . Если ни один из этих идентификаторов не определен, компилируется вызов функции printerror . Оба CREDIT и credit являются уникальными идентификаторами в C и C++, так как их варианты отличаются.
В следующем примере в операторах условной компиляции используется ранее определенная символьная константа с именем DLEVEL .
#if DLEVEL > 5 #define SIGNAL 1 #if STACKUSE == 1 #define STACK 200 #else #define STACK 100 #endif #else #define SIGNAL 0 #if STACKUSE == 1 #define STACK 100 #else #define STACK 50 #endif #endif #if DLEVEL == 0 #define STACK 0 #elif DLEVEL == 1 #define STACK 100 #elif DLEVEL > 5 display( debugptr ); #else #define STACK 200 #endif
В первом блоке #if показаны два набора вложенных #if, #else и директив #endif. Первый набор директив обрабатывается только в том случае, если выполняется условие DLEVEL > 5 . В противном случае операторы после обработки #else .
Директивы #elif и #else во втором примере используются для выбора одного из четырех вариантов на основе значения DLEVEL . Константе STACK присваивается значение 0, 100 или 200 в зависимости от определения константы DLEVEL . Если DLEVEL больше 5, то компилируется оператор
#elif DLEVEL > 5 display(debugptr);
компилируется и STACK не определен.
Условная компиляция обычно используется для предотвращения нескольких включений одного и того же файла заголовка. В C++, где классы часто определяются в файлах заголовков, такие как этот, можно использовать для предотвращения нескольких определений:
/* EXAMPLE.H - Example header file */ #if !defined( EXAMPLE_H ) #define EXAMPLE_H class Example < //. >; #endif // !defined( EXAMPLE_H )
Предыдущий код проверяет, определена ли символьная константа EXAMPLE_H . Если да, файл уже включен и не нуждается в повторной обработке. Если нет, константа EXAMPLE_H определяется, чтобы пометить файл EXAMPLE.H как уже обработанный.
__has_include
Visual Studio 2017 версии 15.3 и более поздних версий: определяет, доступен ли заголовок библиотеки для включения:
#ifdef __has_include # if __has_include() # include # define have_filesystem 1 # elif __has_include() # include # define have_filesystem 1 # define experimental_filesystem # else # define have_filesystem 0 # endif #endif
Когда перед ELSE не нужно ставить точку с запятой, а когда нужно?
Нужно исключить ситуацию, когда cos(x)=0
Здравствуйте! Нужно исключить ситуацию, когда cos(x)=0, вроде как написал все правильно, но не.

Нужно, чтобы когда вводишь число, выдавалось это же число строчными буквами
Только четырехзначные числа.
Когда нужно использовать структуры, когда классы, а когда словарь?
Хеллоу. Не могу понять, когда, что, нужно использовать. Допустим мне нужно получить объект.
6044 / 2159 / 753
Регистрация: 10.12.2010
Сообщений: 6,005
Записей в блоге: 3
Точка с запятой не ставится если else является частью условного перехода (if).
Точка с запятой ставится если else является частью оператора выбора (case).
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Когда нужно ставить 0.0f в передаче переменной
Давно пишу на DirectX и уже забыл для чего я использую 0.0f (имеется ввиду только буква f после.
Удалённые хуки. Когда для них нужно создавать *.dll, а когда необязательно?
Друзья! В туториалах Iczelion’а сказано просто: То тут то там вижу утверждения, что *.dll.

Когда нужно использовать ссылку с out, а когда с ref
Не давно начал учить С# но не могу понять когда надо использовать оut или ref , я так понимаю что.
Когда перед else не ставится знак
страницы: 1 2 3
Операторы ветвления: if и case. Массивы: описание и использование. Операторы цикла: for, while и repeat. Прерывание циклов: break, continue и goto.
Операторы ветвления
К операторам, позволяющим из нескольких возможных вариантов выполнения программы (ветвей) выбрать только один, относятся if и case .
Условный оператор if
Оператор if выбирает между двумя вариантами развития событий:
if then [else ];
Обратите внимание, что перед словом else (когда оно присутствует, конечно же) символ «;» не ставится — ведь это разорвало бы оператор на две части.
Условный оператор if работает следующим образом:
- Сначала вычисляется значение — это может быть любое выражение, возвращающее значение типа Boolean .
- Затем, если в результате получена «истина» (True), то выполняется оператор, стоящий после ключевого слова then, а если «ложь» (False) — без дополнительных проверок выполняется оператор, стоящий после ключевого слова else . Если же else –ветвь отсутствует, то не выполняется ничего.
Что же произойдёт, если написать несколько вложенных операторов if ?
В случае, когда каждый оператор if имеет собственную else –ветвь, всё будет в порядке. А вот если некоторые из них этой ветви не имеют, может возникнуть ошибка. Компилятор языка Pascal всегда считает, что else относится к самому ближнему оператору if . Таким образом, если написать
if i > 0 then
if s > 2 then
s := 1
else
s := — 1 ;
подразумевая, что else –ветвь относится к внешнему оператору if , то компилятор всё равно воспримет эту запись как
if i > 0 then
if s > 2 then
s := 1
else s := — 1 ;
Ясно, что таким образом правильного результата получить не удастся.
Для того чтобы избежать подобных ошибок, стоит всегда (или, по крайней мере, при наличии нескольких вложенных условных операторов) вкладывать внутренние операторы в блок begin .. end . Так вы застрахуетесь от одной из частых «ошибок по невнимательности», которые очень сложно найти в процессе отладки программы.
Итак, исходный вариант нужно переписать следующим образом:
if i > 0 then
begin
if s > 2 then
s := 1 ;
end
else
s := — 1 ;
Вообще же, если есть возможность переписать несколько вложенных условных операторов как один оператор выбора , это стоит сделать.
Оператор выбора case
Оператор case позволяет сделать выбор между несколькими вариантами:
case of : ; [ : ;] [ : ;] [else ;] end;
Замечание: Обратите внимание, что после else двоеточие не ставится.
Существуют дополнительные правила, относящиеся к структуре этого оператора:
- Переключатель должен относиться только к порядковому типу данных , но не к типу LongInt .
- Переключатель может быть переменной или выражением.
- Список констант может задаваться как явным перечислением, так и интервалом или их объединением.
- Повторение констант не допускается.
- Тип переключателя и типы всех констант должны быть совместимыми 1 .
Пример оператора выбора:
case symbol (* : Char *) of
‘a’ .. ‘z’ , ‘A’ .. ‘Z’ : WriteLn ( ‘Это латинская буква’ ) ;
‘а’ .. ‘я’ , ‘А’ .. ‘Я’ : WriteLn ( ‘Это русская буква’ ) ;
‘0’ .. ‘9’ : WriteLn ( ‘Это цифра’ ) ;
‘ ‘ , #10 , #13 , #26 : WriteLn ( ‘Это пробельный символ’ ) ;
else WriteLn ( ‘Это служебный символ’ ) ;
end ;
Выполнение оператора case происходит следующим образом:
- вычисляется значение переключателя;
- полученный результат проверяется на принадлежность к тому или иному списку констант;
- если такой список найден, то дальнейшие проверки уже не производятся, а выполняется оператор, соответствующий выбранной ветви, после чего управление передаётся оператору, следующему за ключевым словом end , которое закрывает всю конструкцию case .
- если подходящего списка констант нет, то выполняется оператор, стоящий за ключевым словом else . Если else –ветви нет, то не выполняется ничего.
Иллюстрация if и case
В качестве примера, иллюстрирующего использование операторов ветвления , приведём несколько различных реализаций функции Sgn(x) 2 — знак числа х. Из математики известно, что эта функция имеет следующие значения:
Sgn(x) = -1, если x < 0; Sgn(x) = 0, если x = 0; Sgn(x) = 1, если x >0.
Реализовать эту функцию для случая, когда х вещественное, можно следующими способами (при условии, что x : Real ; Sgn : -1 .. 1;):
Пунктуация в программах на Паскале
Слова begin и end не являются операторами – они служат знаками пунктуации. Слово begin выступает в качестве левой, а end – правой скобки. Так как они сами знаки пунктуации, то точка запятой после begin и перед end не обязательна. В программах на Паскаль слова begin и end используются преимущественно для образования составных операторов. Составной оператор может быть использован в любом месте, где мог бы быть использован простой оператор. Пример составного оператора:
begin t := a; a := b; b := t end;
Слова в других операторах также действуют как знаки пунктуации.
if ab > bd then write(‘yes’) else write(‘no’);
Слова if , then , else выступают внутри оператора в качестве знаков пунктуации.
Операторы разделены знаками пунктуации, поэтому расположение программы на странице с точки зрения компилятора значения не имеет. Вполне достаточно придерживаться двух правил:
- Не писать слова вместе;
- Не разрывать слово пробелами или переходом на новую строку.
В остальном компилятору все равно, как будет расположена программа, однако, это совсем не безразлично для программиста. Польза отступов в прояснении структуры программы. Взгляды на выбор отступов весьма различны, но все согласны в одном – отступы должны делать структуру программы максимально наглядной.
Слова program , const , var , begin , end , а также множество других называются зарезервированными словами. Зарезервированные слова нельзя расширять (например, constant будет ошибкой) и сокращать (например, prog также будет ошибкой).
Использовать в программном коде на Pascal можно как прописные, так и строчные буквы, а также их чередовать. Однако в строках (тип данных) разница между прописными и строчными буквами существует.
