7

この単純な 3 項演算が C でコンパイルされない理由を誰かが説明できますか?

void main(int argc, char *argv[]){
    int a = atoi(argv[1]);
    char foo[] = (a == 1) ? "bar1" : "bar2";
}

特に文字列に問題があるようです。

4

2 に答える 2

14

文字列リテラルは"bar"(この場合は三項演算子内) で使用される場合、事前に割り当てられたメモリへのポインターです。データへのポインターを使用して配列を初期化することはできません。リテラル ("..."または{...}) のみを使用してください。

代わりに、次のように割り当てることができますchar *

const char *foo = (a == 1) ? "bar1" : "bar2";

これはリテラルのコピーを作成するのではなく、リテラルを指すため、 の要素を変更しないでくださいfoo。コピーが必要な場合はmemcpy、配列を宣言する大きさがわかっていれば、 を使用できます。

char foo[5];
memcpy(foo, (a == 1) ? "bar1" : "bar2", sizeof foo);

特にコンテンツを割り当てたい場合は、それを行うためのトリックがあります。に含まれるものに関係なく、 using 代入の内容を暗黙的にコピーすることができますstruct(関数から返すなども同様です) 。structstruct

typedef struct { 
  char contents[5];
} mystring;

mystring foo = (a == 1) ? (mystring){"bar1"} : (mystring){"bar2"};
// You can also use assignments.
foo = (mystring){"baz"};

2 番目のオプションと同様に、これを行う場合、struct宣言で配列の固定サイズを選択する必要があります。無制限の長さの文字列がある場合は、ポインターを使用する必要があります。

于 2012-10-02T16:18:36.110 に答える
2

三項演算は問題ありませんが、「bar1」と「bar2」が存在する結果の事前割り当てメモリで配列を初期化することはできません。

int a = atoi(argv[1]);
char foo[5];
memcpy(foo,((a == 1) ? "bar1" : "bar2"), 5); 

あなたがしていることをやり続けるための可能な方法でしょう。

于 2012-10-02T16:29:38.963 に答える