Для следующего фрагмента кода:
char a[] = "Apple";
char *s[] = {"Apple"};
printf("%d %d\n", sizeof(a), sizeof(s[0]));
Выход:
6 4
Может кто-нибудь сказать мне, почему sizeof()
дает разные результаты?
EDIT: Я намеревался сначала набрать sizeof()
, но вместо этого набрал strlen()
. Я прошу прощения за то же самое. Я сейчас редактировал выражение.
sizeof(a)
- это размер массива, который содержит терминатор, а также 5 печатных символов.
strlen(s[0])
дает длину строки, исключая терминатор, так как это указано для strlen
.
UPDATE: sizeof(s[0])
- размер указателя. Невозможно определить размер массива, заданный только указателем на него.
sizeof
дает количество char
выделенного a
то время как strlen
дает вам длину полезной строки в. a
Массив символов, объявленный следующим образом:
char a[] = "Apple";
имеет, согласно спецификации языка, нуль-терминатор. Следовательно, длина массива равна 6. Существует 5 символов, а затем нулевой ограничитель.
С другой стороны, strlen()
возвращает количество символов, предшествующих нулевому терминатору. Это 5.
\0
считается частью размера в памяти строки, но длина самой строки, заданной параметром strlen()
, задается только символами до того, как встречается \0
.
Оператор sizeof
дает размер (в байтах) своего операнда.
В этом утверждении
char a[] = "Apple";
array a инициализируется символами строкового литерала "Apple", который включает завершающий нуль. Фактически эта запись эквивалентна
char a[] = { 'A', 'p', 'p', 'l', 'e', '\0'; };
Таким образом, размер в байтах a равен 6.
Функция Standard C strlen
подсчитывает символы в строке до тех пор, пока не встретит нулевой нуль. Так
strlen (a)
будет возвращать 5, то есть количество символов в массиве, которое находится до нулевого окончания.
Учтите, что вы могли бы писать, например
char a[100] = "Apple";
В этом случае sizeof( a )
даст 100, потому что вы явно указали количество байтов, которые будет занимать массив. Однако он был инициализирован только с 6 символами строкового литерала. Итак, как узнать, сколько фактических данных в массиве символов? Для этой цели была введена функция strlen
, чтобы различать размер массива символов и количество фактических данных в массиве символов.
Когда вы определяете:
char a [] = "Apple";
Это означает массив символов, который равен следующему определению:
char a [] = {'A', 'p', 'p', 'l', 'e', '\ 0'}; //'\ 0' - символ окончания строки, который равен 0
Поскольку размер типа char равен 1, sizeof (a) возвращает 6, который является размером всего массива.
Тем не менее, когда вы определяете:
char * s [] = {"Apple"};
Это означает массив указателя char. Следовательно sizeof (s [0]) возвращает размер его первого элемента, который равен sizeof (char *). Для 32-битной платформы sizeof (char *) = 4. Если вы делаете это на 64-битной платформе, 8 - ожидаемое значение.
a
- массив char
s, который содержит 6 элементов, поэтому sizeof
возвращает 6 (длина строки, включая нулевое завершение).
s
- массив указателей на char
. Размер указателя - 4 байта. sizeof(s[0])
возвращает размер первого элемента, который является указателем, т.е. его размер равен 4.
Потому что в C нет строкового типа. String - это массив символов, который заканчивается NULL. strlen() подсчитывает символы до символа NULL, тогда как sizeof() фактически возвращает объем памяти, используемый массивом charater.
strlen
дляs[0]
(который не считает 0-терминатор)… (sizeof s[0]
, однако, дастsizeof(char *)
)