2015-05-08 3 views
1
#include<stdio.h> 
main() 
{ 
    char *str[]= {"Frogs","do","not","die","they","croak"}; 
    printf("%d %d %d",sizeof(str),sizeof(str[0]),sizeof(char)); 
} 

выход:Как отличается sizeof (char *) и sizeof (char)?

По размеру char быть 1 байт и есть шесть символов переменных так, общий размер массива должен быть 6 вместо 48!

+0

Да, я использую 64-битную систему –

+0

Как вы на 64-битных, вы не должны печатать 'size_t' введите «значения», используя спецификатор преобразования «d», поскольку это ожидает 'int', который, вероятно, имеет ширину 32 бит, в отличие от' size_t', который, как ожидается, будет иметь ширину 64 бит. – alk

+0

Почему вы ожидаете, что 'sizeof (T)' совпадает с 'sizeof (T *)'? Они разные, почему их размер должен быть равным? –

ответ

10

Точка 1

sizeof Retruns в размере типа данных, а не количество памяти, выделенное для переменных.

Для чего это стоит, если вы хотите измерить длину в виде строки (т.е. число элементов внутри строки), вы можете использовать strlen()

Пункт 2

Не путайте с типами данных.

  • str - массив указателей. Он содержит 6 указателей, поэтому sizeof даст 6 * sizeof(<pointer type>), что равно 6 * 8 или 48 на 64-битных системах.
  • str[0] является указателем, поэтому sizeof str[0] соответствует sizeof(char *), который является 8 на 64-разрядных системах.
  • C Стандартные гарантии sizeof(char) должно быть равно 1.

Пункт 3

sizeof оператор возвращает size_t. Вам нужно использовать спецификатор формата %zu, чтобы печатать его с возможностью их переносимости и надежности.

3

str - массив указателей длины-6 до char. Его общий размер в 6 раз превышает размер указателя, который дает 48 на вашей платформе.

3

Кажется, вы на 64-битной системе, где sizeof (char *) равно 8.

Это объясняет первое значение, так как sizeof str является размер объекта str, который имеет тип char *[6]. Таким образом, вы получаете размер как 48, которая, конечно, 6 * 8.

Кроме того, правильный путь к printf() значений типа size_t, что и sizeof возвращается, это с %zu.

2

Формат printf спецификатор %d не подходит для значений аргумента sizeof(str) и sizeof(str[0]), тип которого size_t.

Вы должны либо использовать %zu, либо указать аргументы как (int).

Есть больше проблем с вашим кодом:

  • тип возвращаемого значения для main должны быть указаны в качестве int.
  • Тип str должен быть const char *str[].
  • Вы должны добавить \n в формат printf, чтобы убедиться, что выходной идентификатор правильно покрашен во все системы.

Вот улучшенная версия:

#include <stdio.h> 
int main(void) { 
    const char *str[] = { "Frogs", "do", "not", "die", "they", "croak" }; 
    printf("%zu %zu\n", sizeof(str), sizeof(str[0])); 
} 

Это должен выводить 24 4 или 48 8 на соответственно 32 бит и 64-битных систем, а также потенциально других значений на более экзотических систем. Первое число - это 6 указателей на const char, а во втором - размер одного такого указателя.

Размер самих строк может быть определен при компиляции для постоянных непосредственных строк и определенных массивов только как прямые аргументы sizeof. В других случаях вы должны использовать strlen() для вычисления длины строки, если они не содержат встроенных NUL, и добавить 1 для окончательного '\0'.

0

Массив объявлен как

char *str[]={"Frogs","do","not","die","they","croak"}; 

имеет тип char *[6]. то есть он представляет собой 6 указателей на персонажей. Следовательно, str[0] имеет тип char *, то есть это указатель.

Таким образом

sizeof(str[0]) 

эквивалентно

sizeof(char *) 

и в вашей системе, равно 8.

В свою очередь

sizeof (str) 

эквивалентно

6 * sizeof(char *) 

и равным 48.

Примите во внимание, что в этом списке инициализатора

char *str[]={"Frogs","do","not","die","they","croak"}; 

строковые литералы неявно преобразуются в указатели на их первые символы.

С другой стороны, если вы будете писать, например

sizeof("Frogs") 

то выражение будет равно 6 becuase 1) строковых литералов являются символьные массивы, которые включают в себя согласующие нулю и 2) в пределах оператора SizeOf они неявно преобразованные в указатели на их первые символы, они считаются массивами.

Вы можете определить двумерный массив строк следующим образом

char str[][6] = { "Frogs", "do", "not", "die", "they", "croak" }; 

В этом случае

sizeof(str[0]) 

будет равно 6 и

sizeof(str) 

будет равна 36, потому что в этом случае str представляет собой массив элементов типа char [6]

Обратите внимание на то, что в последнем случае вы можете изменить элементы массива следующим образом

str[0][0] = 'f'; 

времени, когда у вас есть массив указателей на строковые литералы (как в исходном посте) вы можете не писать

str[0][0] = 'f'; 

потому что строковые литералы неизменяемы.

И еще один об операторе sizeof. В соответствии со стандартом C (6.5.3.4 SizeOf и alignof операторов)

2 Оператор SizeOf дает размер (в байтах ) своего операнда, который может быть выражение в скобках или имя тип. Размер определяется по типу операнда. Результатом является целое число . Если тип операнда - это тип массива переменной длины, то оценивается операнд; в противном случае операнд не оценивается и результат представляет собой целочисленную константу.

Таким образом, при применении к массиву оператор выводит количество байтов, которое занимает массив. Он не дает количество элементов в массиве. Если вы хотите, чтобы получить количество элементов в массиве следует использовать выражение:

sizeof(array)/sizeof(array[0]) 

или

sizeof(array)/sizeof(*array) 
+0

@Sourav Ghosh Спасибо, это была опечатка. –

Смежные вопросы