розмір символьного масиву та розмір покажчика символу

У мене є частина коду C, і я не розумію, як функціонує функція sizeof (...) :

#include 

int main(){
   const char  firstname[] = "bobby";
   const char* lastname = "eraserhead";
   printf("%lu\n", sizeof(firstname) + sizeof(lastname));
   return 0;
}

У наведеному вище коді розмір (перше ім'я) становить 6, а sizeof (прізвище) - 8.

Але bobby має дорівнювати 5 символів, а eraserhead - 11. Я очікую 16 .

Чому sizeof веде себе по-різному для масиву символів і покажчик на символ?

Чи може хто-небудь прояснити?

16
І sizeof , і strlen() дають результат типу size_t . Використовуйте % zu , а не % lu для друку значень size_t . Або, якщо ваш компілятор не підтримує % zu , конвертуйте в відомий тип і використовуйте відповідний формат для цього типу.
додано Автор Keith Thompson, джерело

9 Відповіді

firstname is a char array carrying a trailing 0-terminator. lastname is a pointer. On a 64bit system pointers are 8 byte wide.

24
додано
І кількість байтів, необхідних для збереження рядка s (або вказаний s ), є strlen (s) + 1 .
додано Автор Keith Thompson, джерело
@PHIfounder: оскільки рядок у C представлений послідовністю символів, завершених символом '\ 0' , використовуйте strlen() щоб отримати довжину "string". Це працює на "реальних" масивів символів, а також на покажках, що вказують на останню. У цьому контексті не має першорядного значення, як і де зберігаються символи. Фактично, змінна, що містить рядок, не обов'язково повинна відповідати довжині рядка. Якщо, з іншого боку, цікавить кількість байтів, яку призначено змінною, , скористайтеся оператором sizeof .
додано Автор alk, джерело
Зрозуміло, що ОП намагався з'ясувати розмір рядка, тобто довжину рядка, і додати їх обох, як він говорить "why not 5 + 10 = 15?" , чи це дійсно можливо отримати довжину рядка за допомогою sizeof або strlen() більше підходить? що ти сказав?
додано Автор 0decimal0, джерело

firstname is a char array carrying a trailing 0-terminator. lastname is a pointer. On a 64bit system pointers are 8 byte wide.

24
додано
І кількість байтів, необхідних для збереження рядка s (або вказаний s ), є strlen (s) + 1 .
додано Автор Keith Thompson, джерело
@PHIfounder: оскільки рядок у C представлений послідовністю символів, завершених символом '\ 0' , використовуйте strlen() щоб отримати довжину "string". Це працює на "реальних" масивів символів, а також на покажках, що вказують на останню. У цьому контексті не має першорядного значення, як і де зберігаються символи. Фактично, змінна, що містить рядок, не обов'язково повинна відповідати довжині рядка. Якщо, з іншого боку, цікавить кількість байтів, яку призначено змінною, , скористайтеся оператором sizeof .
додано Автор alk, джерело
Зрозуміло, що ОП намагався з'ясувати розмір рядка, тобто довжину рядка, і додати їх обох, як він говорить "why not 5 + 10 = 15?" , чи це дійсно можливо отримати довжину рядка за допомогою sizeof або strlen() більше підходить? що ти сказав?
додано Автор 0decimal0, джерело

sizeof an array is the size of the total array, in the case of "bobby", it's 5 characters and one trailing \0 which equals 6.

sizeof a pointer is the size of the pointer, which is normally 4 bytes in 32-bit machine and 8 bytes in 64-bit machine.

6
додано

sizeof an array is the size of the total array, in the case of "bobby", it's 5 characters and one trailing \0 which equals 6.

sizeof a pointer is the size of the pointer, which is normally 4 bytes in 32-bit machine and 8 bytes in 64-bit machine.

6
додано

Розмір вашого першого масиву - це розмір bobby \ 0 . \ 0 - це символ термінатора, тому це 6.

Другий розмір - це розмір покажчика, що становить 8 байт у вашій 64-бітній системі. Його розмір не залежить від довжини заданої рядки.

3
додано

Розмір вашого першого масиву - це розмір bobby \ 0 . \ 0 - це символ термінатора, тому це 6.

Другий розмір - це розмір покажчика, що становить 8 байт у вашій 64-бітній системі. Його розмір не залежить від довжини заданої рядки.

3
додано

firstname is an array of 6 chars, including the terminating '\0' character at the end of the string. That's why sizeof firstname is 6.

lastname is a pointer to char, and will have whatever size such a pointer has on your system. Typical values are 4 and 8. The size of lastname will be the same no matter what it is pointing to (or even if it is pointing to nothing at all).

2
додано

firstname[] is null-terminated, which adds 1 to the length.

sizeof(lastname) is giving the size of the pointer instead of the actual value.

2
додано
* lastname - це єдиний char , тому sizeof * Lastname завжди буде 1.
додано Автор caf, джерело

firstname[] is null-terminated, which adds 1 to the length.

sizeof(lastname) is giving the size of the pointer instead of the actual value.

2
додано
* lastname - це єдиний char , тому sizeof * Lastname завжди буде 1.
додано Автор caf, джерело