2016-03-30 13 views
1

私が言うのコードが午前##使用:コードへオペレータ

#include<stdio.h> 

typedef struct string{ 
    char *ch_ptr; 
}str_t; 

#define newdef(a,b) \ 
    char a ## sumthing[b * sizeof(str_t)]; \ 
    str_t *a = (str_t *)a ## sumthing 

main(){ 
    newdef(input,5); 
    /*  some lines of code */ 
} 

オプションの変更:

#include<stdio.h> 

typedef struct string{ 
    char *ch_ptr; 
}str_t; 

#define newdef(a,b) \ 
    char a ## sumthing[b * sizeof(str_t)]; \ 
    str_t *var1 = (str_t *)a ## sumthing 

main(){ 
    newdef(input,5)="Hello"; 
    printf("%s\n",input); 
    /*  some lines of code */ 
} 

誰もがこのコードセグメントが何を意味するのか説明できますか?このコードのinputは文字列(希望ではない)か変数ですか?変数の場合、なぜコンパイラは宣言されていない変数エラーをスローしないのですか?

+1

'#define'の難読化であるように思わプリプロセッサマクロを作成する(ことを見てそれが何であるかわからない場合は、アップ)。この場合、マクロは 'newdef'と呼ばれ、2つのパラメータをとります。 'a'と' b'です。 'newdef(input、5)'はマクロ定義( 'char a ## [...]')に展開され、 'a'が全て' input'に展開され、全て 'b'が' 5'に展開されます。 '##'は連結演算子なので、 '## ## sumthing'は' inputsumthing'(この場合)になります。 – Biffen

+0

##プリプロセッサの連結演算子です。 –

答えて

3

inputに置き換えられます、それは前処理トークンですが、文字列でも変数でもありません。

##は「トークンペースト」演算子です。

最初のマクロはnewdef(input,5);すなわち

char inputsumthing[5 * sizeof(str_t)]; str_t *input = (str_t *) intputsumthing; 

に、それは最初のパラメータのような名前付き変数の宣言に展開膨張します。

"オプションの変更"は、宣言されたポインタ変数 "var1"の名前を無条件に指定し、マクロを同じスコープ内で複数回使用することを不可能にします。
また 、newdef(input,5)="Hello";がエラーに拡大する:

側の注意点として
char inputsumthing[5 * sizeof(str_t)]; 
str_t *var1 = (str_t *)inputsumthing = "Hello"; 

は、元のマクロはほとんど

str_t inputs[5]; 
str_t* input = inputs; 
5

プリプロセッサ連結演算子で、プリプロセッサマクロを定義するときにのみ使用できます。

は、単純な例に上記のコードで

#define CONCAT(a, b) a ## b 

int CONCAT(foo, bar); 

を取ることができます、CONCAT(foo, bar)の呼び出しは

int foobar;