Почему sizeof (* "327" ) возвращает 1 вместо 8 в 64-битной системе?
printf("%lu \n", sizeof(*"327"));
Я всегда думал, что размер указателя был 8 байтов в 64-битной системе, но этот вызов продолжает возвращаться 1. Может ли кто-нибудь дать объяснение?
Ответы
Ответ 1
Поместите *
, прежде чем строковый литерал будет разыменовывать литерал (поскольку строковый литерал является массивом символов и будет распадаться на указатель на его первый элемент в этом контексте). Утверждение
printf("%zu \n", sizeof(*"327"));
эквивалентно
printf("%zu \n", sizeof("327"[0]));
"327"[0]
даст первый элемент строкового литерала "327"
, который является символом '3'
. Тип "327"
, после распада, имеет значение char *
и после разыменования дает значение типа char
и в конечном итоге sizeof(char)
равно 1
.
Ответ 2
Заявление:
printf("%lu \n", sizeof(*"327"));
на самом деле печатает размер char
, используя *
разыменования первого символа строки 327
. Измените его на:
char* str = "327";
printf("%zu \n", sizeof(str));
Обратите внимание, что здесь мы должны использовать %zu
вместо %lu
, потому что мы печатаем значение size_t
.
Ответ 3
Строковый литерал - это анонимный статический массив символов, который распадается на указатель на его первый символ - то есть на значение указателя типа char *
.
В результате выражение типа *"abc"
эквивалентно *someArrayOfCharName
, что в свою очередь эквивалентно *&firstCharInArray
, что приводит к firstCharInArray
. А sizeof(firstCharInArray)
- sizeof(char)
, который 1
.
Ответ 4
Хороший ответ hacce.
Кроме того, поведение вашего кода undefined, потому что вы использовали неверный спецификатор формата.
Итак, используйте %zu
вместо %lu
, потому что sizeof()
возвращает size_t
и size_t
is unsigned
.
Стандарт C11: §7.21.6.1: Пункт 9:
Если спецификация преобразования недействительна, поведение undefined.225) Если какой-либо аргумент не является правильным типом для соответствующая спецификация преобразования, поведение undefined.