web-dev-qa-db-ja.com

64ビットシステムでsizeof(* "327")が8ではなく1を返すのはなぜですか。

 printf("%lu \n", sizeof(*"327"));

ポインターのサイズは64ビットシステムでは8バイトだといつも思っていましたが、この呼び出しは1を返し続けます。

22
lordgabbith

_*_を文字列リテラルの前に置くと、リテラルが逆参照されます(文字列リテラルは文字の配列であり、このコンテキストの最初の要素へのポインターに減衰するため)。声明

_printf("%zu \n", sizeof(*"327")); 
_

に等しい

_printf("%zu \n", sizeof("327"[0]));  
_

_"327"[0]_は、文字列リテラル_"327"_の最初の要素を提供します。これは、文字_'3'_です。減衰後の_"327"_の型は_char *_であり、逆参照後はchar型の値を与え、最終的にsizeof(char)は_1_になります。

62
haccks

ステートメント:

printf("%lu \n", sizeof(*"327"));

*を使用すると文字列327の最初の文字が逆参照されるため、実際にはcharのサイズが出力されます。次のように変更します。

char* str = "327";
printf("%zu \n", sizeof(str));

ここでは、%zuの代わりに%luを使用する必要があることに注意してください。これは、 size_t値を出力している であるためです。

19
Marievi

文字列リテラルは、文字の匿名の静的配列であり、最初の文字へのポインター、つまり_char *_型のポインター値に減衰します。

結果として、_*"abc"_のような式は_*someArrayOfCharName_と同等であり、これは_*&firstCharInArray_と同等であり、結果としてfirstCharInArrayになります。 sizeof(firstCharInArray)sizeof(char)であり、これは_1_です。

4
CiaPan

haccks による適切な回答。

また、間違った書式指定子を使用したため、コードの動作はundefinedです。

したがって、sizeof()%zuを返し、%luunsignedであるため、size_tの代わりにsize_tを使用します。

C11標準:§7.21.6.1:パラグラフ9:

変換仕様が無効な場合、動作は未定義です。225)引数が対応する変換仕様の正しいタイプでない場合、動作は未定義です。

0
msc