あなたが持っているとしましょう:
char[5] = "March";
ただし、これはCでは機能しません。
char[0]='M'
char[1]='a'
char[2]='r'
char[3]='c'
char[4]='h'
char[5]='\0'
どういうわけか、私はCにそれを言わなければchar[6]="March"
なりませんchar [5]
。
どうしてこれなの?何が入りchar[6]
ますか?
まず最初に、char
は C では有効な変数ではありません。これはkeywordです。あなたはおそらく意味した
char xyzzy[6];
と呼ばれる文字配列を作成しますxyzzy
。しかし、それが修正されると、 には何も入りませんxyyzy[6]
。このステートメントは、 6文字char xyzzy[6];
の配列を意味し、そのインデックスはinclusive:までであり、6 つの要素です。0
5
{0,1,2,3,4,5}
いずれにせよ、配列を大きくする必要がない限り、通常はコンパイラに次のようにサイズを選択させる方がよいでしょう:
char xyzzy[] = "March";
この場合、文字列リテラルに"March"
は暗黙的な null ターミネータがあるため、char[]
配列には6
それを格納するための要素が必要です。C99 標準のセクション6.4.5 文字列リテラルから関連するポイントを引用するには、次のようにします。
文字列リテラルは、"xyz" のように、二重引用符で囲まれた 0 個以上のマルチバイト文字のシーケンスです。
変換フェーズ 7 では、値ゼロのバイトまたはコードが、文字列リテラルまたはリテラルから生じる各マルチバイト文字シーケンスに追加されます。
どちらの場合も、コードは配列の末尾をオーバーランしています。コードには現在未定義の動作があります。
への変更:
char a[6] = "March";
2 番目のコード スニペットは、インデックスが から0
まで実行されるため、配列の末尾を超えてアクセスしますN - 1
。ここN
で、 は配列内の要素の数です。配列char a[5];
の場合、有効なインデックスは0, 1, 2, 3, 4
.
Char
は変数名ではなくキーワードなので、変数名として使用しないでください。
配列のインデックス付け: 配列内の文字数を 0 から数えます (つまり a[0])。
配列に 5 文字 (例: tiger) があり、a[0] = 't' および a[4] = 'r' であり、すべての文字列リテラルがこの場合、文字の配列は '\0 で終わるとします。 ' つまり、EOF
文字です。したがって、n 文字の配列を格納するには、[n] コンパイラを使用して、その配列の末尾に '\0' を追加します。
ヌル ターミネータ \0 は最後のスロットに入ります。そうしないと、文字列の長さを確認する方法がないためです。
0から5まで数えると6つの要素が含まれています。
したがって、 to を使用するには、 a を宣言する必要がchar[6]
ありstr[0]
ますstr[5]
。
char [5]
つまり、sizeof(char) の 5 倍のメモリがあります。0 ~ 5 は sizeof(char) の 6 倍です: 最初に 0、1 秒、2 番目、3 番目に 3、4 番目に 4、5 番目に 5 です。したがって、 sizeof(char): の 6 倍のセグメントが必要ですchar [6]
。最初のセルであるゼロもスペースを消費します。
char[6] には何も入りませんが、null ターミネータ バイトを含む 6 文字を保持するには、サイズ 6 の char[] が必要です。これらは char[0] から char[5] に入ります。char[6] は未定義のままです。
char array[n]
は、最後のインデックスが である配列ではなく、n 要素の長さの配列を意味しますn
。C では、配列は 0 から始まるため、n 要素配列の最後の有効なインデックスは ですn - 1
。文字列にはゼロターミネータがあり、「March」は 5 文字なので、合計 6 文字なので、 と書く必要がありますchar str[6] = "March";
。今のところ混乱している場合は、配列の長さを含めないでください。初期化された配列の場合、コンパイラは自動的にそれを埋めるので、char str[] = "March";
代わりに書くことができます。