Почему 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 *.
В результате выражение типа *"abc" эквивалентно *someArrayOfCharName, что в свою очередь эквивалентно *&firstCharInArray, что приводит к firstCharInArray. А sizeof(firstCharInArray) - sizeof(char), который 1.
Кроме того, поведение вашего кода undefined, потому что вы использовали неверный спецификатор формата.
Итак, используйте %zu вместо %lu, потому что sizeof() возвращает size_t и size_t is unsigned.
Стандарт C11: §7.21.6.1: Пункт 9:
Если спецификация преобразования недействительна, поведение undefined.225) Если какой-либо аргумент не является правильным типом для соответствующая спецификация преобразования, поведение undefined.