2012-05-24 19 views
16

Stavo scrivendo del codice di prova in C. Per errore avevo inserito uno ; dopo un #define, che mi ha dato errori. Perché non è necessario un punto e virgola per #define s?Perché #define non richiede un punto e virgola?

In particolare:

Metodo 1: funziona

const int MAX_STRING = 256; 

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

Metodo 2: Non funziona - errore di compilazione.

#define MAX_STRING 256; 

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

Qual è la ragione del diverso comportamento di quei codici? Quelli di entrambi i MAX_STRING non sono costanti?

+35

Rimuovere la; nel metodo 2 –

+7

Visualizza l'output del preprocessore e la risposta ti guarderà in faccia. –

+0

@MichaelFoukarakis sì, è il modo più semplice per cpp prog_name.c | la coda dice tutto. – user51390233

risposta

20

#define è un preprocessor directive, non un dichiarazione o dichiarazione come definito dalla grammatica C (entrambi di questi sono tenuti a conclude con una virgola). Le regole per la sintassi di ognuna sono diverse.

10

perché è così che la sintassi è stata decisa per i direttive pre-compilatore.

Solo dichiarazioni finali un ; in C/C++, #define è una direttiva di pre-processore e non una dichiarazione.

17

define è una direttiva preprocessore ed è una semplice sostituzione, non è una dichiarazione.

proposito, come sostituzione può contenere alcuni ; come parte di essa:

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

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

La seconda versione non definisce una costante per quanto riguarda la lingua è interessato, solo una regola di sostituzione per un blocco di testo. Una volta che il preprocessore ha fatto il suo lavoro, il compilatore vede

char buffer [256;];

che non è sintatticamente valido.

La morale della trama: preferisci il modo const int MAX_STRING = 256; che ti aiuta, il compilatore e il debugger.

+0

Non sono sicuro, in che modo aiuta il debugger? – saeleko

+3

Hai mai provato a eseguire il debug di un carico di codice con macro al suo interno? – Bathsheba

+5

In generale caso 'const int MAX_STRING = 256;' non * è * un approccio praticabile in linguaggio C, poiché tale 'MAX_STRING' non sarebbe una * costante * in C e non sarebbe permesso di essere usato dove è presente un'espressione costante necessario. – AnT

38
#define MAX_STRING 256; 

significa:

ogni volta che si trovano MAX_STRING quando pre-elaborazione, sostituirlo con 256;. Nel tuo caso verrà applicato il metodo 2:

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

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

che non è una sintassi valida.Sostituire

#define MAX_STRING 256; 

con

#define MAX_STRING 256 

La differenza tra le due codici è che in primo metodo si dichiara una costante pari a 256 ma nel secondo codice si definisce MAX_STRING riposare per 256; nel file sorgente .

La direttiva #define viene utilizzata per definire valori o macro che vengono utilizzati dal preprocessore per manipolare il codice sorgente del programma prima che venga compilato. Poiché le definizioni del preprocessore vengono sostituite prima che il compilatore agisca sul codice sorgente, gli errori introdotti da #define sono difficili da tracciare.

La sintassi è:

#define CONST_NAME VALUE 

se c'è un ; alla fine, è considerato come una parte di VALUE.

per capire come esattamente #define s lavoro, provare a definire:

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

Interessante osservazione di John Hascall:

maggior parte dei compilatori vi darà un modo per vedere l'uscita dopo la fase di preprocessore, questo può aiutare con problemi di debug come questo.

In gcc può essere fatto con la bandiera -E.

+5

Molti compilatori ti daranno un modo per vedere l'output dopo la fase del preprocessore, questo può aiutare con problemi di debug come questo. –

13

Entrambe le costanti? No.

Il primo metodo non produce una costante in linguaggio C. Le variabili qualificate Const non si qualificano come costanti in C. Il primo metodo funziona solo perché i compilatori -C99 C supportano array di lunghezza variabile (VLA). Il tuo buffer è un VLA nel primo caso in particolare perché MAX_STRING è non è una costante. Prova a dichiarare lo stesso array nell'ambito del file e riceverai un errore, dal momento che gli VLA non sono consentiti nell'ambito del file.

Il secondo metodo può essere utilizzato per assegnare nomi a valori costanti in C, ma è necessario farlo correttamente. Lo ; nella definizione della macro non dovrebbe essere lì. Le macro funzionano attraverso la sostituzione testuale e non si desidera sostituire quello extra ; nella dichiarazione dell'array. Il modo corretto per definire la macro sarebbe

#define MAX_STRING 256 

Nel linguaggio C, quando si tratta di definire le costanti corretta con nome, si sono fondamentalmente limitati a macro e enumerazioni. Non tentare di utilizzare le "costanti" const, a meno che tu non sappia davvero che funzionerà per i tuoi scopi.

+0

Inoltre, i VLA non sono ammessi allo scope del file poiché devono essere allocati dinamicamente (stack o 'malloc'). –

1

Questa direttiva del preprocessore:

#define MAX_STRING 256; 

dice al preprocessore per sostituire tutte le MAX_STRING s con 256; - e con il punto e virgola. Le istruzioni di preprocessore non hanno bisogno di un punto e virgola alla fine. Se ne metti uno, il preprocessore pensa davvero che tu lo intenda con un punto e virgola.

Se si è confusi con le virgole #define per le costanti, è probabile che const int sia più facile da comprendere.

Se volete saperne di più su come usare correttamente queste direttive del preprocessore, prova a guardare this website.

Problemi correlati