まず、あなたの質問の要点:コンパイラは sizeof を宣言サイズに関して厳密に扱います。次のコードでは、ポインター変数が 32 ビット (4 バイト) アドレスを保持していると仮定します。
char str1[] = "abcd";
char *pstr = str1;
// str1 is declared to be a fixed array of 5 chars (4+nul)
size_t str1size = sizeof(str1); // str1size = 5;
// pstr is declared to be a 32 bit pointer to a memory address.
size_t pstrSize = sizeof(pstr) // size of a 32 bit pointer; 4.
表示されている結果を把握するには、配列とポインター変数の違いを確認してください (ほとんどの人が考えているよりも少ないものです)。
C における配列とポインター変数の主な違いは次のとおりです。
- ポインター変数はアドレスを保持します。宣言された配列はアドレスです。
- したがって、宣言された配列の「アドレス」を変更することはできません(これらはアドレスであるため、ポインター変数のようにアドレスを保持しません)。
これらのうちの最初のものは、C の配列とポインターに頭を悩ませたいのであれば、十分に強調することはできません。それ以外は、それらの関係はせいぜい近親相姦です。ポインター変数は、配列 (またはその他の変数) のようなアドレスにあります。ただし、配列とは異なり、値としてアドレスも保持します。配列はまさにそれらのアドレスです。
1つ目は、次の例で最もよく示されています。
char str1[] = "abcd";
char *pstr = NULL;
pstr = str1; // ok. pstr holds the address *at* str1.
str1[0] = *pstr; // ok. copies 'a' on to 'a'.
pstr++; // ok. increment the address held in pstr by one item (char) size.
str1[0] = *pstr; // ok. copies 'b' over 'a'.
pstr = str1+1; // ok. pstr holds the address *at* str1 + one item (char) size.
str1 = pstr; // does not compile. str1's address cannot be changed.
ポインター変数自体がアドレスを保持するのに対し、固定配列はアドレスであることに注意してください。したがって、逆の最後のステートメントは完全に問題ありません。
pstr = str1; // ok. put the str1 address in pstr, a pointer variable.