Перейти к содержимому

Ifndef c что это

  • автор:

#ifdef и #ifndef директивы (C/C++)

Директивы #ifdef и препроцессоры имеют тот же эффект, что #if и #ifndef директива, когда она используется с оператором defined .

Синтаксис

#ifdef identifier
#ifndef identifier

Эти директивы эквивалентны следующим:

#if defined identifier
#if !defined identifier

Замечания

Вы можете использовать #ifdef директивы и #ifndef директивы в любом месте #if . Оператор #ifdef identifier эквивалентен #if 1 определению identifier . Это эквивалентно #if 0 тому, когда identifier не определено или не определено директивой #undef . Эти директивы проверяют наличие или отсутствие только идентификаторов, определенных с директивой #define , а не идентификаторов, объявленных в исходном коде C или C++.

Эти директивы предназначены только для совместимости с предыдущими версиями языка. Выражение defined( identifier ) константы, используемое #if с директивой, предпочтительнее.

Директива #ifndef проверка для противоположности условия проверка. #ifdef Если идентификатор не определен или его определение было удалено с #undef , условие имеет значение true (nonzero). В противном случае условие не выполняется (false, значение равно 0).

Блок, относящийся только к системам Майкрософт

Идентификатор можно передать из командной строки с помощью /D параметра. Можно указать /D до 30 макросов.

Директива #ifdef полезна для проверка, существует ли определение, так как определение можно передать из командной строки. Например:

// ifdef_ifndef.CPP // compile with: /Dtest /c #ifndef test #define final #endif 

Завершение блока, относящегося только к системам Майкрософт

#ifdef u #ifndef

Другой метод условной компиляции состоит в использовании директив #ifdef и #ifndef, что соответ­ственно означает «если определено» и «если не определено». Стандартный вид #ifdef следующий:

#ifdef имя_макроса
последовательность операторов
#endif

Если имя макроса определено ранее в операторе #define, то последовательность операторов, сто­ящих между #ifdef и #endif, будет компилироваться. Стандартный вид #ifndef следующий:

#ifndef имя_макроса
последовательность операторов
#endif

Если имя макроса не определено ранее в операторе #define, то последовательность операторов, стоящих между #ifdef и #endif, будет компилироваться.

Kaк #ifdef, так и #ifndef могут использовать оператор #else, но нe #elif. Например:

#include
#define TED 10
int main(void)
#ifdef TED
printf(«Hi Ted\n»);
#else
printf(«Hi anyone\n»);
#endif
#ifndef RALPH
printf(«RALPH not defined\n»);
#endif
return 0;
>

выводит «Hi Ted» и «RALPH not defined». Если TED не определен, то выведется «Hi anyone», a за ним «RALPH not defined».

#ifdef и #ifndef можно вкладывать друг в друга так же, как и #if.

Директивы #ifndef и #endif

Рассмотрим пример программы из раздела Классы в С++. Программа использует простейший класс, объект которого печатает сообщение. Заметьте, что раньше класс был объявлен в одном файле с главной функцией, но такой способ утилизации классов не эффективен, почему, было рассмотрено в разделе Классы в С++. Так вот, теперь объявление класса находится в файле message.h , а реализация методов класса определена в файле message.cpp , а classes.cpp — файл с main() функцией.

// интерфейс класса, файл: message.h class CppStudio // имя класса < public: // спецификатор доступа void message(); // функция (метод класса) выводящая сообщение на экран >; // конец объявления класса CppStudio

В h-файл помещен только лишь интерфейс класса, далее h-файл будет модифицирован с целью предотвращения ошибки многократного включения заголовочных файлов.

// реализация класса CppStudio, файл: message.cpp #include «stdafx.h» // связываем интерфейс класса с его реализацией #include «message.h» // подключаем прототип оператора cout #include void CppStudio::message() // функция (метод класса) выводящая сообщение на экран

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

// classes.cpp: определяет точку входа для консольного приложения. #include "stdafx.h" #include using namespace std; #include "message.h" int main(int argc, char* argv[]) < CppStudio objMessage; // объявление объекта objMessage.message(); // вызов функции класса message system("pause"); return 0; >
// classes.cpp: определяет точку входа для консольного приложения. #include using namespace std; #include "message.h" int main(int argc, char* argv[]) < CppStudio objMessage; // объявление объекта objMessage.message(); // вызов функции класса message return 0; >

Структура данной программы совсем простая, чего не скажешь о программах с большим объёмом кода. В таких программах, как правило, код расположен не в одном файле. И подключение заголовочных файлов выполняется не обязательно в главном файле. Поэтому существует вероятность многократного включения в программу заголовочного файла, что в свою очередь приводит к ошибке компиляции. В случае с нашей программой, заголовочный файл подключен в главном файле в строке 7 и программа нормально работает без всяких ошибок. А если же заголовочный файл message.h , по ошибке, был подключён не только в главном файле программы, но, и ,например, в файле stdafx.h . В таком случае при компиляции программы появится следующая ошибка:

//Ошибка 1 error C2011: CppStudio: переопределение типа "class"

То есть, компилятор сообщает о многократном включении заголовочного файла с классом CppStudio . В таком случае придется потратить своё время и убрать лишнее включение в программу заголовочного файла. Чтобы не возникало такого рода ошибок, в С++ существует специальная структура кода, которую ещё называют препроцессорная обёртка.

// препроцессорная обёртка, файл: message.h с интерфейсом класса #ifndef CPPSTUDIO_H // если имя CPPSTUDIO_H ещё не определено #define CPPSTUDIO_H // определить имя CPPSTUDIO_H // определить класс CPPSTUDIO_H class CppStudio // имя класса < public: // спецификатор доступа void message(); // функция (метод класса) выводящая сообщение на экран >; // конец объявления класса CppStudio #endif CPPSTUDIO_H // если имя CPPSTUDIO_H уже определено, повторно не определять

Данная препроцессорная обёртка предотвращает попытку многократного включения заголовочных файлов. Препроцессорные директивы обрабатываются до этапа компиляции, программой-препроцессором. Который, в свою очередь не допускает многократного определения одного и того же класса. Препроцессорная обёртка похожа на оператор условного выбора if . Директива #ifndef проверяет, определено ли имя CPPSTUDIO_H , если нет, то управление передаётся директиве #define и определяется интерфейс класса. Если же имя CPPSTUDIO_H уже определено, управление передаётся директиве #endif . Таким образом, исключается возможность многократного определения класса CPPSTUDIO_H .
Обратите внимание на то, как написано имя класса, используемое в сочетании с директивами препроцессорной обёртки — CPPSTUDIO_H . Берётся имя заголовочного файла, в котором объявлен класс, причём имя принято записывать буквами верхнего регистра, а вместо точки ставить символ нижнего подчёркивания. Конечно же, имя может быть любым другим, но оно должно быть одинаковым во всех трёх директивах. Итак, структура препроцессорной обёртки такова:

// структура препроцессорной обёртки #ifndef /*ИМЯ ЗАГОЛОВОЧНОГО ФАЙЛА_H*/ #define /*ИМЯ ЗАГОЛОВОЧНОГО ФАЙЛА_H*/ // определение класса #endif /*ИМЯ ЗАГОЛОВОЧНОГО ФАЙЛА_H*/

С использованием препроцессорной обёртки, попытки подключения одного и того же файла, ошибки переопределения не вызовут. Этот же приём применяется и для предотвращения многократного определения функций, только если функции вынесены в отдельный файл.

К сожалению, для данной темы пока нет подходящих задач. Если у вас есть таковые на примете, отправте их по адресу: admin@cppstudio.com. Мы их опубликуем!

Что такое ifndef в C++?

#ifndef (или If Not Defined) — это директива препроцессора в языке программирования C++, используемая для предотвращения многократного включения кода, который уже был включен ранее. Это особенно важно при работе с заголовочными файлами.

// myheader.h #ifndef MYHEADER_H #define MYHEADER_H // Содержимое заголовочного файла class MyClass < public: void myFunction(); >; #endif // MYHEADER_H

Преимущества использования #ifndef:

  1. Предотвращение двойного включения: Директива #ifndef в сочетании с #define и #endif обеспечивает эффективный способ предотвращения многократного включения кода.
  2. Защита от конфликтов имен: Использование уникальных макросов в #ifndef устраняет возможные конфликты имен при включении нескольких заголовочных файлов.
  3. Улучшение производительности: Минимизация дублирования кода при многократном включении способствует повышению производительности компиляции.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *