3

以下のコードの意味は何ですか?コンパイルエラーかと思いました。しかし、コンパイルエラーは発生しません。

int main() 
{ 
    const int a=1; 
    printf("%c", ++a["Gyantonic"]); 
}

Linux a での出力はセグメンテーション違反です。a[1]の代わりに を指定すると、コンパイル エラーが発生します++a["Gyantonic"]

それはどのように機能しますか?

4

3 に答える 3

7
 ++a["Gyantonic"]

次と同等です。

++(a["Gyantonic"])

これはと同等です

++("Gyantonic"[a])

に相当

++("Gyantonic"[1])

"Gyantonic"[1]生成され、文字列リテラルに格納された値がインクリメントされ、結果が生成され'y'ます++'y'ただし"Gyantonic"、文字列リテラルであり、文字列リテラルは変更できません。これが、セグメンテーション違反が発生する理由です。

于 2012-07-15T14:16:42.620 に答える
1

C では、式x[y]は とまったく同じ*(x+y)です。足し算は可換なので、 と書くこともできますがy[x]、これは*(y+x)同じことです。

于 2012-07-15T14:12:01.320 に答える
1
++a["Gyantonic"]

は、「Gyantonic」の a 番目の文字(つまり、1 番目、つまり 1 番目ではなく2 番目の 0 から始まる C 文字列) をインクリメントしようとしていることを意味します。

また、「Gyantonic」は読み取り専用の定数文字列であるため、その文字をインクリメントすることはできず、セグメンテーション エラーが発生します。

警告を有効にした gcc では、次のようになります。

 warning: increment of read-only location ‘"Gyantonic"[a]’ [enabled by default]

意図した出力は明らかに「z」です (Gyantonic の「y」は 1 ずつ増加します)。これを行うには、次のように書く必要があります。

    char string[] = "Gyantonic";
    const int a=1;
    printf("%c", ++a[string]);

これは書き込みと同じではないことに注意してください

    char *string = "Gyantonic";

最初のバージョンでは、配列を作成し、この書き込み可能な配列で既存の読み取り専用文字列 "Gyantonic" を初期化 (COPIES) します。2 番目のバージョンは、既存の読み取り専用文字列 "Gyantonic" へのラベルであるpointerを作成します。

書き込み可能なコピー string[] への書き込みは許可されています。*string が指す readonly に書き込むと、segfault が発生します。

于 2012-07-15T14:16:02.060 に答える