Подтвердить что ты не робот

Почему sizeof (* "327" ) возвращает 1 вместо 8 в 64-битной системе?

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

Я всегда думал, что размер указателя был 8 байтов в 64-битной системе, но этот вызов продолжает возвращаться 1. Может ли кто-нибудь дать объяснение?

4b9b3361

Ответ 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.