Я использую Ubuntu 16.04.5 и GCC версии 5.4.0.
Я играл с оператором sizeof()
, написал код ниже:
#include <stdio.h>
int main(int argc, char *argv[]){
long int mylint = 31331313131.1313;
printf("size of long int is %d\n", sizeof(mylint));
printf("size of long int is %d\n", sizeof(long int));
return 0;
}
Я пытался скомпилировать с помощью команды gcc -o ... ...
и ожидал:
size of long int is 8
size of long int is 8
Но я получил следующую ошибку:
fl_double_lint.c: In function ‘main’:
fl_double_lint.c:11:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("size of long int is %d\n", sizeof(mylint));
^
fl_double_lint.c:12:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("size of long int is %d\n", sizeof(long int));
Когда я вместо этого использую %ld
, он работает должным образом. Почему sizeof()
не работает с %d
? (Почему «long unsigned int
», а не «int
»?)
Изменить: Я знаю, что было задано много вопросов относительно вывода оператора sizeof () (как это было предложено в комментариях). Однако они не отвечают на вопрос, почему использование %d
не работает (т.е. не дает никакого результата). Я знаю, что это неправильный формат, но всякий раз, когда у нас есть переменная типа char
с использованием %d
, мы можем получить эквивалентный int
результат, это также относится к коротким, uint8_t, uint16_t, uint32_t (обычно для типов с равным или менее 32 бит) . Следующий код работает:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char *argv[]){
char mychar = 'd';
uint32_t myuint32 = 32;
uint16_t myuint16 = 16;
uint8_t myuint8 = 8;
short myshort = 26945;
int myint = 100;
printf("integer equivalent of mychar is %d\n", mychar);
printf("integer equivalent of myuint8 is %d\n", myuint8);
printf("integer equivalent of myuint16 is %d\n", myuint16);
printf("integer equivalent of myuint32 is %d\n", myuint32);
printf("character equivalent of myint is %c\n", myint);
printf("integer equivalent of myshort is %d\n", myshort);
return 0;
}
Результат:
integer equivalent of mychar is 100
integer equivalent of myuint8 is 8
integer equivalent of myuint16 is 16
integer equivalent of myuint32 is 32
character equivalent of myint is d
integer equivalent of myshort is 26945
И теперь я обнаружил, что %d
не работает ни с одной переменной, размер которой превышает 32 бита. После рассмотрения этого вопроса у меня есть некоторое представление о зависимости реализации size_t
, возможно, в моей системе это было unsigned long
(%ld
также дает результат, подтверждающий это). Так что, может быть, если бы size_t
был unsigned int
в моей системе, я бы получил результат, это правда?
Как видно из приведенного выше кода, %c
декодирует последние 8 бит int
как символ, почему %d
не делает то же самое (т.е. декодирует последние 32 бита содержимого size_t
переменной, как это было int
? сделал бы так, чтобы мы могли получить тот же результат для достаточно малых чисел, и именно это я имел в виду, когда изначально задал вопрос).
long unsigned int
», а не «int
»? Какой смысл в отрицательном значении, возвращаемом изsizeof
? - person Algirdas Preidžius   schedule 31.01.2019sizeof
- это оператор, а не функция. Это результат типаsize_t
, а правильный спецификатор формата -%zu
. - person Eugene Sh.   schedule 31.01.2019"%ld"
тоже неверно. Операторsizeof
возвращает значение типаsize_t
, и для его печати с помощьюprintf
(и семейства) следует использовать"%zu"
. Или, поскольку вы также отметили этот вопрос совсем другим языком C ++, просто используйтеstd::cout << sizeof(something)
. - person Some programmer dude   schedule 31.01.2019size_t
выглядитlong unsigned int
в вашей системе, но это не обязательно. Может быть unsigned short или unsigned int или любым другим, если он может представлять размер объектов на этой платформе. - person phuclv   schedule 01.02.2019myuint32
- этоuint32_t
, который должен быть напечатан с использованиемPRIu32
. Помните, что int не всегда 32 бита, и печать беззнакового типа со спецификатором формата со знаком по-прежнему UB. спецификаторы формата printf для uint32_t и size_t - person phuclv   schedule 01.02.2019why %d does not do the same (i.e. decode the last 32 bits of content of size_t variable as it was int?)
C так не работает. Размеры типов не фиксированы, и функции vararg не знают, какой размер у параметра. На платформах, где они находятся в стеке, если вы укажете другой тип, отличный от того, который вы ему дали, вы можете испортить стек, когда printf выдает другое количество байтов для этого аргумента. Как сказано, используйте правильный спецификатор и не удивляйтесь, почему он работает здесь, а не там - person phuclv   schedule 01.02.2019