以下のコードの意味は何ですか?コンパイルエラーかと思いました。しかし、コンパイルエラーは発生しません。
int main()
{
const int a=1;
printf("%c", ++a["Gyantonic"]);
}
Linux a での出力はセグメンテーション違反です。a[1]
の代わりに を指定すると、コンパイル エラーが発生します++a["Gyantonic"]
。
それはどのように機能しますか?
以下のコードの意味は何ですか?コンパイルエラーかと思いました。しかし、コンパイルエラーは発生しません。
int main()
{
const int a=1;
printf("%c", ++a["Gyantonic"]);
}
Linux a での出力はセグメンテーション違反です。a[1]
の代わりに を指定すると、コンパイル エラーが発生します++a["Gyantonic"]
。
それはどのように機能しますか?
++a["Gyantonic"]
次と同等です。
++(a["Gyantonic"])
これはと同等です
++("Gyantonic"[a])
に相当
++("Gyantonic"[1])
"Gyantonic"[1]
生成され、文字列リテラルに格納された値がインクリメントされ、結果が生成され'y'
ます++
。'y'
ただし"Gyantonic"
、文字列リテラルであり、文字列リテラルは変更できません。これが、セグメンテーション違反が発生する理由です。
C では、式x[y]
は とまったく同じ*(x+y)
です。足し算は可換なので、 と書くこともできますがy[x]
、これは*(y+x)
同じことです。
++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 が発生します。