C define как в c
Перейти к содержимому

C define как в c

  • автор:

C define как в c

Директива #define определяет идентификатор и последовательность символов, которые будут подставляться вместо идентификатора каждый раз, когда он встретится в исходном файле. Формальное определение директивы:

Используем директиву #define:

Здесь определен один идентификатор N. В программе, где встречается этот идентификатор, он будет заменяться на число 23. Например, строка

после обработки препроцессором будет иметь следующий код

Более сложный пример

Здесь определены три идентификатора BEGIN, END, N. В итоге все вхождения последовательности символов «BEGIN» будут заменяться на открывающую фигурную скобку, а «END» — на закрывающую, а символ «N» на число 23.

Таким образом, после обработки препроцессора функция main приобретет следующий вид:

#define также может определять более сложные выражения. Например:

В данном случае выражение ADD(a,b) будет заменяться операцией сложения двух чисел (a + b)

Особенно удобно использовать директиву #define для определения размеров массивов:

В данном случае если мы захотим глобально поменять размер массива, то достаточно изменить значение N в директиве define.

Следует учитывать, что директива препроцессор не заменяет последовательности символов в двойных и одинарных кавычках и в комментариях:

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

Директива #undef

В процессе работы мы можем многократно определять новое значение для одного идентификатора:

Но некоторые компиляторы, в частности, gcc, могут выдавать предупреждения при повторном определении идентификатора, и чтобы выйти из этой ситуации, мы можем использовать директиву #undef для отмены действия макроса. Эта директива имеет следующее определение:

Name already in use

cpp-docs / docs / preprocessor / hash-define-directive-c-cpp.md

  • Go to file T
  • Go to line L
  • Copy path
  • Copy permalink
  • Open with Desktop
  • View raw
  • Copy raw contents Copy raw contents

Copy raw contents

Copy raw contents

#define directive (C/C++)

The #define creates a macro, which is the association of an identifier or parameterized identifier with a token string. After the macro is defined, the compiler can substitute the token string for each occurrence of the identifier in the source file.

#define identifier token-stringopt
#define identifier ( identifieropt, . , identifieropt ) token-stringopt

The #define directive causes the compiler to substitute token-string for each occurrence of identifier in the source file. The identifier is replaced only when it forms a token. That is, identifier is not replaced if it appears in a comment, in a string, or as part of a longer identifier. For more information, see Tokens.

The token-string argument consists of a series of tokens, such as keywords, constants, or complete statements. One or more white-space characters must separate token-string from identifier. This white space is not considered part of the substituted text, nor is any white space that follows the last token of the text.

A #define without a token-string removes occurrences of identifier from the source file. The identifier remains defined and can be tested by using the #if defined and #ifdef directives.

The second syntax form defines a function-like macro with parameters. This form accepts an optional list of parameters that must appear in parentheses. After the macro is defined, each subsequent occurrence of identifier( identifieropt, . identifieropt ) is replaced with a version of the token-string argument that has actual arguments substituted for formal parameters.

Formal parameter names appear in token-string to mark the locations where actual values are substituted. Each parameter name can appear multiple times in token-string, and the names can appear in any order. The number of arguments in the call must match the number of parameters in the macro definition. Liberal use of parentheses guarantees that complex actual arguments are interpreted correctly.

The formal parameters in the list are separated by commas. Each name in the list must be unique, and the list must be enclosed in parentheses. No spaces can separate identifier and the opening parenthesis. Use line concatenation — place a backslash ( \ ) immediately before the newline character — for long directives on multiple source lines. The scope of a formal parameter name extends to the new line that ends token-string.

When a macro has been defined in the second syntax form, subsequent textual instances followed by an argument list indicate a macro call. The actual arguments that follows an instance of identifier in the source file are matched to the corresponding formal parameters in the macro definition. Each formal parameter in token-string that is not preceded by a stringizing ( # ), charizing ( #@ ), or token-pasting ( ## ) operator, or not followed by a ## operator, is replaced by the corresponding actual argument. Any macros in the actual argument are expanded before the directive replaces the formal parameter. (The operators are described in Preprocessor operators.)

The following examples of macros with arguments illustrate the second form of the #define syntax:

Arguments with side effects sometimes cause macros to produce unexpected results. A given formal parameter may appear more than one time in token-string. If that formal parameter is replaced by an expression with side effects, the expression, with its side effects, may be evaluated more than one time. (See the examples under Token-Pasting Operator (##).)

The #undef directive causes an identifier’s preprocessor definition to be forgotten. See The #undef Directive for more information.

If the name of the macro being defined occurs in token-string (even as a result of another macro expansion), it is not expanded.

A second #define for a macro with the same name generates a warning unless the second token sequence is identical to the first.

Microsoft Specific

Microsoft C/C++ lets you redefine a macro if the new definition is syntactically identical to the original definition. In other words, the two definitions can have different parameter names. This behavior differs from ANSI C, which requires that the two definitions be lexically identical.

For example, the following two macros are identical except for the parameter names. ANSI C does not allow such a redefinition, but Microsoft C/C++ compiles it without error.

On the other hand, the following two macros are not identical and will generate a warning in Microsoft C/C++.

END Microsoft Specific

This example illustrates the #define directive:

The first statement defines the identifier WIDTH as the integer constant 80 and defines LENGTH in terms of WIDTH and the integer constant 10. Each occurrence of LENGTH is replaced by ( WIDTH + 10 ). In turn, each occurrence of WIDTH + 10 is replaced by the expression ( 80 + 10 ). The parentheses around WIDTH + 10 are important because they control the interpretation in statements such as the following:

After the preprocessing stage the statement becomes:

which evaluates to 1800. Without parentheses, the result is:

which evaluates to 280.

Microsoft Specific

Defining macros and constants with the /D compiler option has the same effect as using a #define preprocessing directive at the start of your file. Up to 30 macros can be defined by using the /D option.

Директивы препроцессора

В C# определен ряд директив препроцессора, оказывающих влияние на интерпретацию исходного кода программы компилятором. Эти директивы определяют порядок интерпретации текста программы перед ее трансляцией в объектный код в том исходном файле, где они появляются. Термин директива препроцессора появился в связи с тем, что подобные инструкции по традиции обрабатывались на отдельной стадии компиляции, называемой препроцессором. Обрабатывать директивы на отдельной стадии препроцессора в современных компиляторах уже не нужно, но само ее название закрепилось.

Все директивы препроцессора начинаются со знака #. Кроме того, каждая директива препроцессора должна быть выделена в отдельную строку кода. Принимая во внимание современную объектно-ориентированную архитектуру языка C#, потребность в директивах препроцессора в нем не столь велика, как в языках программирования предыдущих поколений. Тем не менее они могут быть иногда полезными, особенно для условной компиляции. В этой статье все директивы препроцессора рассматриваются по очереди.

Директива #define

Директива #define определяет последовательность символов, называемую идентификатором. Присутствие или отсутствие идентификатора может быть определено с помощью директивы #if или #elif и поэтому используется для управления процессом компиляции. Ниже приведена общая форма директивы #define:

Обратите внимание на отсутствие точки с запятой в конце этого оператора. Между директивой #define и идентификатором может быть любое количество пробелов, но после самого идентификатора должен следовать только символ новой строки. Так, для определения идентификатора EXPERIMENTAL служит следующая директива:

В C/C++ директива #define может использоваться для подстановки исходного текста, например для определения имени значения, а также для создания макрокоманд, похожих на функции. А в C# такое применение директивы #define не поддерживается. В этом языке директива #define служит только для определения идентификатора.

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

Обе директивы, #if и #endif, допускают условную компиляцию последовательности кода в зависимости от истинного результата вычисления выражения, включающего в себя один или несколько идентификаторов. Идентификатор считается истинным, если он определен, а иначе — ложным. Так, если идентификатор определен директивой #define, то он будет оценен как истинный. Ниже приведена общая форма директивы #if:

Если идентификаторное_выражение, следующее после директивы #if, истинно, то компилируется код (последовательность операторов), указываемый между ним и директивой #endif. В противном случае этот промежуточный код пропускается. Директива #endif обозначает конец блока директивы #if. Идентификаторное выражение может быть простым, как наименование идентификатора. В то же время в нем разрешается применение следующих операторов: !, ==, !=, && и ||, а также круглых скобок.

Ниже приведен пример применения упомянутых выше директив:

Пример использования директив #if #endif

Директивы #else и #elif

Директива #else действует аналогично условному оператору else языка C#, определяя альтернативный ход выполнения программы, если этого не может сделать директива #if.

Обозначение #elif означает «иначе если», а сама директива #elif определяет последовательность условных операций if-else-if для многовариантной компиляции. После директивы #elif указывается идентификаторное выражение. Если это выражение истинно, то компилируется следующий далее кодовый блок, а остальные выражения директивы #elif не проверяются. В противном случае проверяется следующий по порядку блок. Если же ни одну из директив #elif не удается выполнить, то при наличии директивы #else выполняется последовательность кода, связанная с этой директивой, а иначе не компилируется ни один из кодовых блоков директивы #if.

Ниже приведена общая форма директивы #elif:

Давайте добавим в предыдущий пример следующий код:

Директива #undef

С помощью директивы #undef удаляется определенный ранее идентификатор. Это, по существу, означает, что он становится «неопределенным». Ниже приведена общая форма директивы #undef:

Рассмотрим следующий пример кода

Директива #undef применяется главным образом для локализации идентификаторов только в тех фрагментах кода, в которых они действительно требуются.

Директива #error

Директива #error вынуждает компилятор прервать компиляцию. Она служит в основном для отладки. Ниже приведена общая форма директивы #error:

Когда в коде встречается директива #error, выводится сообщение об ошибке. Например, когда компилятору встречается строка кода « #error Это тестовая ошибка! » компиляция прерывается и выводится сообщение «Это тестовая ошибка!».

Директива #warning

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

Директива #line

Директива #line задает номер строки и имя файла, содержащего эту директиву. Номер строки и имя файла используются при выводе ошибок или предупреждений во время компиляции. Ниже приведена общая форма директивы #line:

Имеются еще два варианта директивы #line. В первом из них она указывается с ключевым словом default, обозначающим возврат нумерации строк в исходное состояние, как в приведенном ниже примере:

#line default

А во втором варианте директива #line указывается с ключевым словом hidden. При пошаговой отладке программы строки кода, находящиеся между директивой #line hidden и следующей директивой #line без ключевого слова hidden, пропускаются отладчиком.

Директивы #region и #endregion

С помощью директив #region и #endregion определяется область, которая разворачивается или сворачивается при структурировании исходного кода в интегрированной среде разработки Visual Studio. Ниже приведена общая форма этих директив:

где текст обозначает необязательную символьную строку.

Директива #pragma

С помощью директивы #pragma инструкции задаются компилятору в виде опций. Ниже приведена общая форма этой директивы:

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

В текущей версии C# предусмотрены две опции для директивы #pragma. Первая из них, warning, служит для разрешения или запрета отдельных предупреждений со стороны компилятора. Она принимает две формы:

где предупреждения обозначает разделяемый запятыми список номеров предупреждений. Для отмены предупреждения используется опция disable, а для его разрешения — опция restore.

Например, в приведенной ниже директиве #pragma запрещается выдача предупреждения №168, уведомляющего о том, что переменная объявлена, но не используется:

Второй для директивы #pragma является опция checksum. Она служит для формирования контрольной суммы в проектах ASP.NET. Ниже приведена ее общая форма:

где имя_файла обозначает конкретное имя файла; GUID — глобально уникальный идентификатор, с которым связано имя_файла; контрольная_сумма — шестнадцатеричное число, представляющее контрольную сумму. У этой контрольной суммы должно быть четное число цифр.

How to define constants in Visual C# like #define in C?

so that wherever NUMBER appears in the program it is replaced with 9. But Visual C# doesn’t do this. How is it done?

7 Answers 7

You’d need to put it in a class somewhere, and the usage would be ClassName.NUMBER

sunside's user avatar

You can’t do this in C#. Use a const int instead.

Kirtan's user avatar

In C# the #define preprocessor directive cannot be used to define constants in the way that is typically used in C and C++.

in c language: #define (e.g. #define counter 100)

in assembly language: equ (e.g. counter equ 100)

in c# language: according to msdn refrence: You use #define to define a symbol. When you use the symbol as the expression that’s passed to the #if directive, the expression will evaluate to true, as the following example shows:

The #define directive cannot be used to declare constant values as is typically done in C and C++. Constants in C# are best defined as static members of a class or struct. If you have several such constants, consider creating a separate «Constants» class to hold them.

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

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