私は概念的な疑問を持っています。
char ch[20]="some string";
chがどのように格納されているか、つまり20バイトが割り当てられているのか、それとも割り当てられている文字列の長さだけなのかを知りたいのですが。ここでch[18]のようなものにアクセスできますか?
ch
どのように保存されているのか、つまり20
バイトが割り当てられているのか、それとも割り当てられている文字列の長さだけなのかを知りたいのですが。
文字長の名前ch
で配列を作成し、 20
「文字列」で初期化します。
はい、配列のサイズは20バイトです。
ここでch[18]のようなものにアクセスできますか?
はいできます。また、内容を変更することもできます。
良い読み物:
char a [] =“ string”;の違いは何ですか。およびchar*p =“ string”;
コメントでQに答えるには:
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
ch:| s | o | m | e | | s | t | r | i | n | g | \0 | | | b | \0 |
+---+---+---+---+---+---+----+----+----+----+----+----+----+ +----+----+
0 1 2 3 4 5 6 7 8 9 10 11 12 ...... 18 19
あなたがそうするとき、
ch[18]='b';
あなたがそれを見ることができないということだけが変更されました。
printf
を検出して文字列の終わりを判別し\0
ます。初期化時に文字列の\0
最後に配置されました。初期化子が指定されるたびに配列を宣言するC/C ++のルールでは、初期化されていない要素は自動的に0に設定されます。上の図に示すように、変更された文字は次のようになります。文字列の終わりであると考えるものの後に配置されるprintf
ため、の出力では表示されませんprintf
。
文字列をforループで繰り返して出力すると、変更内容を確認できます。
20バイトが割り当てられているかどうか
はい、あなたがそうするように言ったので、20バイトが割り当てられます。配列の最初の12バイトは、文字列とその末尾のNULを使用して初期化され、残りのバイトはゼロで埋められます。ただし、配列の20バイトすべて、つまりfromからにアクセス(読み取りおよび書き込み)することはできch[0]
ますch[19]
。
あなたが書いたなら
char ch[] = "some string";
次にch
、12要素の配列として作成されます。
{ 's', 'o', m', 'e', ' ', 's', 't', 'r', 'i', 'n', 'g', 0 }
その場合にのみ、配列の境界を超えて読み取りまたは書き込みを試みるのは誤りでした。e。ch[12]
インデックスが高いと、未定義の動作が発生します。
あなたが書くなら
char *ch = "some string";
それは本当に悪いことであり、文字ポインタとして文字列リテラルが必要な場合は、実際に書く必要があります
const char *ch = "some string";
この場合、ポインタは12バイトの長さの文字列を指し、その文字は定数であるため、読み取り専用です。(範囲外の読み取りに加えて)それらを変更ch
しようとすると、やはり未定義の動作になります。 。
ch
20バイトを使用するように宣言したため、20バイトが割り当てられます。はい、ch[18]にアクセスできます。
の問題
char ch[20] = "some string";
ch[18] = 'b';
printf("%s",ch);
リテラルの「いくつかの文字列」はそのNULL
ターミネータを含めて格納されるため、それを印刷すると、文字列は最初のnullターミネータまでしか印刷されません。
はい、ch [18]にアクセスできます。配列を割り当てすぎて、定数文字列の後のバイトがまだそこにあり、初期化されていないデータでいっぱいです。メモリの場所を見てください。
`how ch is being stored` and `whether 20 bytes are allocated`
実際には20バイトが割り当てられ、割り当てられるメモリアドレスは一定です。ここでの「ch」は、割り当てられたメモリの最初のバイト(またはchar)へのポインタです。また、「ch + 1」は、割り当てられたメモリの2番目のバイトを指します。
Can we access something like ch[18] here?
文字列の長さが要求したメモリサイズ(この場合は20)よりも短い場合でも、要求されたサイズを取得でき、他のバイトの値は不明です(0かどうかは不明ですが、vc6では多くの場合0として初期化)。ch [18]にアクセスできますが、値が不明な場合があります。したがって、それらにアクセスしたい場合は、自分でそれらを0に初期化するための努力をしなければならない場合があります。