char c[] = "Hello";
char *p = "Hello";
printf("%i", sizeof(c)); \\Prints 6
printf("%i", sizeof(p)); \\Prints 4
私の質問は:
これらが異なる結果を出力するのはなぜですか? c[]
配列の最初の文字を指すポインターも宣言しませんか(したがって、ポインターなのでサイズ 4 にする必要があります)。
ポインタと配列を混同しているようです。ポインターと配列 (この場合はchar *
とchar []
) は同じものではありません。
char a[SIZE]
は、の位置の値a
が長さの配列であることを示しますSIZE
char *a;
は、 の位置にある値がa
へのポインタであることを示しchar
ます。これをポインター演算と組み合わせて、配列のように振る舞うことができます (たとえば、任意のポイントをa[10]
過ぎた 10 エントリですa
) 。メモリ内では、次のようになります ( FAQ からの例):
char a[] = "hello"; // array
+---+---+---+---+---+---+
a: | h | e | l | l | o |\0 |
+---+---+---+---+---+---+
char *p = "world"; // pointer
+-----+ +---+---+---+---+---+---+
p: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
多くの場合、配列参照は最初の要素へのポインターに「減衰」するため、ポインターと配列の違いについて混乱するのは簡単です。これは、多くの場合 (関数呼び出しに渡される場合など)、配列がポインターになることを意味します。詳細については、C FAQ のこのセクションで違いを詳しく説明しています。
実際の大きな違いの 1 つは、コンパイラが配列の長さを認識していることです。上記の例を使用すると、次のようになります。
char a[] = "hello";
char *p = "world";
sizeof(a); // 6 - one byte for each character in the string,
// one for the '\0' terminator
sizeof(p); // whatever the size of the pointer is
// probably 4 or 8 on most machines (depending on whether it's a
// 32 or 64 bit machine)
sizeof
異なる型を持つ 2 つのオペランド。1 つは の配列でchar
、もう 1 つは へのポインタchar
です。
C 標準では、sizeof
演算子が配列に適用されると、結果は配列内の合計バイト数になるとされています。はターミネータを含めてc
6 個の配列で、 のサイズは1 と定義されているため、6 です。char
NUL
char
sizeof (c)
ただし、ポインターのサイズは実装に依存します。p
へのポインタchar
です。あなたのシステムでは、へのポインタのサイズはchar
たまたま 4 バイトです。これが で表示されsizeof (p)
ます。
ただし、 andを試すsizeof(*p)
とsizeof(*c)
、参照解除されたポインターと配列の最初の要素の両方が 型であるため、両方とも 1 に評価されますchar
。
「sizeof」はコンパイラの指令です。結果は、引数が占有するメモリのサイズを示します。コンパイラは、引数の型に従って結果を決定する責任があります。「配列」については、配列サイズを返します。さらに、ポインターは一般的に 32 ビット マシンで言えば "4" を返します。
配列とポインターが同じではないため、同じように出力されません。それらが同じでなければならない理由はありません。多くの場合、配列は暗黙的にポインターに変換されますが、これによって配列が同一になるわけではありません。
ポインタと配列は異なります。
char c[] = "Hello";
// c を配列として宣言します。sizeof(c) 配列のサイズを計算します 6.
char *p = "Hello";
//p をポインタとして宣言します。sizeof(p) ポインタのサイズを計算します。ほとんどのマシンでは、ポインタのサイズは 4 です。
< c トラップと落とし穴>も参照できます。