Вопрос по c – Почему #define не требует точки с запятой?

17

Я писал тестовый код вC, По ошибке я вставил; после#define, который дал мне ошибки. Почему точка с запятой не требуется для#defines?

Более конкретно:

Method 1: works

const int MAX_STRING = 256;

int main(void) {
    char buffer[MAX_STRING];
}

Method 2: Does not work - compilation error.

#define MAX_STRING 256;

int main(void) {
    char buffer[MAX_STRING];
}

В чем причина различного поведения этих кодов? Эти MAX_STRING не являются константами?

Посмотрите на вывод препроцессора, и ответ будет смотреть вам в лицо. Michael Foukarakis
@MichaelFoukarakis да, это самый простой способcpp prog_name.c | tail скажи все user51390233
C не имеет символьных констант (кромеenum-constants). const квалифицированныйvariables нет констант в C. А#defineИмена также не являются константами. too honest for this site
Удалить ; в методе 2 Bjorn A.
Трюк: скомпилировать с-E -dD флаги.-E флаг останавливает компиляторafter фаза предварительной обработки (не компилируется).-dD Флаг указывает, что препроцессор оставляет директивы препроцессора в файле, хотя их использование все еще обрабатывается. Jorge Bellón

Ваш Ответ

7   ответов
17

define это директива препроцессора, и это простая замена, это не декларация.

Кстати, в качестве замены он может содержать некоторые; как часть этого:

// Ugly as hell, but valid 
#define END_STATEMENT ;

int a = 1 END_STATEMENT // preprocessed to -> int a = 1;
11

Вторая версия не определяет константу в том, что касается языка, а просто правило замены для блока текста. Однаждыpreprocessor сделал свою работу,compiler видит

char buffer [256;];

что не является синтаксически допустимым.

Мораль этой истории: предпочитаюconst int MAX_STRING = 256; Как это помогает вам, компилятору и отладчику.

Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededconstError: User Rate Limit Exceeded
Error: User Rate Limit Exceededconst int MAX_STRING = 256;Error: User Rate Limit ExceedednotError: User Rate Limit ExceededMAX_STRINGError: User Rate Limit ExceededconstantError: User Rate Limit Exceeded
Error: User Rate Limit Exceededconst intError: User Rate Limit Exceededconst intError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
39
#define MAX_STRING 256;

средства:

всякий раз, когда вы обнаружите MAX_STRING при предварительной обработке, замените его на256;, В вашем случае это сделает способ 2:

#include <stdio.h>
#include <stdlib.h>
#define MAX_STRING 256;

int main(void) {
    char buffer [256;];
}

который не является допустимым синтаксисом. замещать

#define MAX_STRING 256;

с

#define MAX_STRING 256

Разница между вашими двумя кодами заключается в том, что в первом методе вы объявляете константу, равную256 но во втором коде вы определяетеMAX_STRING стоять за256; в вашем исходном файле.

The #define directive is used to define values or macros that are used by the preprocessor to manipulate the program source code before it is compiled. Because preprocessor definitions are substituted before the compiler acts on the source code, any errors that are introduced by #define are difficult to trace.

Синтаксис:

#define CONST_NAME VALUE

если есть; в конце он рассматривается как частьVALUE.

чтобы понять, как именно#defines работа, попробуйте определить:

#define FOREVER for(;;)
...
    FOREVER {
         /perform something forever.
    }

Интересное замечаниеДжон Хэскол:

Most compilers will give you a way to see the output after the preprocessor phase, this can aid with debugging issues like this.

Вgcc это можно сделать с флагом-E.

Error: User Rate Limit Exceeded
1

Эта директива препроцессора:

#define MAX_STRING 256;

говорит препроцессору заменить всеMAX_STRINGс256; - а такжеwith the semicolon, Заявления препроцессора не должны заканчиваться точкой с запятой. Если вы поставите один, препроцессор на самом деле думает, что вы имеете в виду точку с запятой.

Если вас смущают#defines для констант,const int было бы легче понять.

Если вы хотите узнать больше о том, как правильно использовать эти директивы препроцессора, попробуйте посмотреть наэтот сайт.

21

#define этоpreprocessor directiveнеstatement или жеdeclaration как определено грамматикой C (оба они должны заканчиваться точкой с запятой). Правила для синтаксиса каждого из них разные.

13

Обе константы? Нет.

Первый метод не даетconstant на языке Си. Переменные с константой не считаются константами в C. Ваш первый метод работает только потому, чтоpast-C99 C компиляторы поддерживают массивы переменной длины (VLA). Вашbuffer это VLA в первом случае именно потому, чтоMAX_STRING являетсяnot постоянная. Попробуйте объявить один и тот же массив в области видимости файла, и вы получите ошибку, поскольку VLA не разрешены в области видимости файла.

Второй метод можно использовать для присвоения имен постоянным значениям в C, но вы должны сделать это правильно.; в макросе определения не должно быть. Макросы работают через текстовую замену, и вы не хотите заменять эту дополнительную; в вашем объявлении массива. Правильный способ определить этот макрос будет

#define MAX_STRING 256

В языке Си, когда речь идет об определении именованных констант, вы в основном ограничены макросами и перечислениями. Не пытайтесь использоватьconst & quot; константы & quot ;, если вы действительно не знаете, что это будет работать для ваших целей.

Error: User Rate Limit Exceededmalloc).
10

Потому что так был определен синтаксис дляprecompiler directives.

Толькоstatements конец с; в с / с ++,#define is a pre-processor directive and not a statement.

Похожие вопросы