19

私はCでいくつかのテストコードを書いていました。;誤ってアフターを挿入したため#define、エラーが発生しました。sにセミコロンが不要なのはなぜ#defineですか?

すなわち :

方法1:機能する

const int MAX_STRING = 256;

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

方法2:機能しない-コンパイルエラー。

#define MAX_STRING 256;

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

これらのコードの動作が異なる理由は何ですか?それらは両方ともMAX_STRINGが定数ではありませんか?

4

7 に答える 7

42
#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

2つのコードの違いは、最初のメソッドで定数を宣言します256が、2番目のコードでソースファイルでMAX_STRING表すように定義することです。256;

#defineディレクティブは、プリプロセッサがコンパイル前にプログラムのソースコードを操作するために使用する値またはマクロを定義するために使用されます。コンパイラがソースコードに作用する前にプリプロセッサ定義が置き換えられるため、#defineによって発生したエラーを追跡するのは困難です。

構文は次のとおりです。

#define CONST_NAME VALUE

;末尾にが付いている場合は、の一部と見なされVALUEます。

がどのように機能するかを正確に理解するには#define、次のように定義してみてください。

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

ジョン・ハスコールによる興味深い発言:

ほとんどのコンパイラは、プリプロセッサフ​​ェーズの後に出力を確認する方法を提供します。これは、このようなデバッグの問題に役立ちます。

でそれgccはフラグで行うことができます-E

于 2016-11-07T08:29:18.453 に答える
24

#defineプリプロセッサディレクティブであり、C文法で定義されているステートメントまたは宣言ではありません(どちらもセミコロンで終了する必要があります)。それぞれの構文の規則は異なります。

于 2012-05-24T09:53:15.913 に答える
17

defineはプリプロセッサディレクティブであり、単純な置換であり、宣言ではありません。

ところで、代わりにそれはそれの一部;としていくつかを含むかもしれません:

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

int a = 1 END_STATEMENT // preprocessed to -> int a = 1;
于 2012-05-24T09:53:34.643 に答える
13

両方の定数?いいえ。

最初の方法では、C言語で定数を生成しません。Const修飾変数は、Cでは定数として修飾されません。最初の方法は、過去のC99 Cコンパイラが可変長配列(VLA)をサポートしているためにのみ機能します。が定数ではないため、最初のケースではあなたbufferはVLAです。ファイルスコープで同じ配列を宣言してみてください。VLAはファイルスコープで許可されていないため、エラーが発生します。MAX_STRING

2番目の方法は、Cの定数値に名前を割り当てるために使用できますが、適切に行う必要があります。inマクロ定義はそこ;にあるべきではありません。;マクロはテキスト置換を介して機能するため、配列宣言にその余分なものを代入する必要はありません。そのマクロを定義する適切な方法は次のとおりです。

#define MAX_STRING 256

C言語では、適切な名前付き定数を定義する場合、基本的にマクロと列挙型に制限されます。「定数」を使用しようとしないでくださいconst。ただし、目的に合ったものであることが本当にわかっている場合を除きます。

于 2016-11-07T08:29:19.883 に答える
11

これが、プリコンパイラディレクティブの構文が決定された方法だからです。

c / c ++ではステートメントのみがaで終わり、プリプロセッサディレクティブであり、ステートメントではありません;#define

于 2012-05-24T09:53:23.450 に答える
11

2番目のバージョンでは、言語に関する限り定数を定義せず、テキストブロックの置換ルールのみを定義します。プリプロセッサがその仕事を終えると、コンパイラ

char buffer [256;];

これは構文的に有効ではありません。

const int MAX_STRING = 256;話の教訓:それがあなた、コンパイラー、そしてデバッガーを助ける方法を好む。

于 2016-11-07T08:28:00.387 に答える
1

このプリプロセッサディレクティブ:

#define MAX_STRING 256;

MAX_STRINGすべてのsを256;-およびセミコロンに置き換えるようにプリプロセッサに指示します。プリプロセッサステートメントの最後にセミコロンは必要ありません。1つ置くと、プリプロセッサは実際にはセミコロンでそれを意味していると見なします。

#define定数のsと混同している場合は、const intおそらく理解しやすいでしょう。

これらのプリプロセッサディレクティブを適切に使用する方法について詳しく知りたい場合は、このWebサイトを参照してください。

于 2016-11-13T22:06:56.493 に答える