C что такое короткая форма для длинного без знака int - PullRequest
6 голосов
/ 20 февраля 2012

при компиляции моей программы с GCC я получаю следующее предупреждение:

format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int

Теперь, просто играя, я понимаю, что% lo исправляет предупреждение.Однако я не очень понимаю, что я делаю.

Существует ли соглашение об именах для получения краткой формы типа?Например, int это% d, почему ??

Спасибо!

Ответы [ 5 ]

22 голосов
/ 20 февраля 2012
long unsigned int = unsigned long

Вы используете %lu для их печати. ​​

И, аналогично, %llu для unsigned long long.


%d    -   int
%u    -   unsigned
%ld   -   long
%lld  -   long long
%lu   -   unsigned long
%llu  -   unsigned long long
3 голосов
/ 20 февраля 2012

Определения int, long и т. Д. Относятся к конкретной цели.Если размер int и long совпадают, то

printf("%d",var); 

не будут жаловаться, но если long, скажем, 64 бита, а int, например, 32 бита, то вы получите предупреждение / ошибку, которую вы описали.Одно из двух решений:

printf("%ld",var);
or
printf("%d",(int)var);

Для последнего, конечно, вы должны убедиться, что компилятор связывает int с размером% d, если вы получите еще одно предупреждение, то отрегулируйте соответствующим образом.

РЕДАКТИРОВАТЬ:

Компилятор пытается помочь вам, заботясь о вещах библиотеки C, которые на самом деле не бизнес компилятора.printf () использует переменное количество аргументов, которое, как мы надеемся, вы правильно сопоставили со строкой формата.Когда printf видит% d на 32-битной системе, он, вероятно, получит только следующий 32-битный аргумент.Но если вы ввели в качестве параметра 64-битное целое число, оно может захватить половину этого целого числа и использовать другую половину в качестве следующего элемента в строке формата.Например,

unsigned long ul;
float f;

f=3.4;
ul=0x3F9DF3B612345678;
...
printf("%X %f\n",ul,f);

В зависимости от вашей системы, порядкового номера и т. Д., 32-битной системы вы не должны удивляться, если приведенный выше код выдаст такой вывод:

12345678 1.234000

, потому что этоэто то, что вы сказали.вы сказали, что нужно взять младшие 32 бита ul и вывести его как шестнадцатеричный (% X), а верхние 32 бита ul и вывести его как float (% f), а в вызове функции ввести f - пустая трата, которую вы не предоставили.форматирование для использования значения с плавающей запятой.

Теперь, в зависимости от компилятора в целевой системе в конкретный день, приведенный выше код может работать по желанию, возьмите систему / компилятор, где unsigned long интерпретируется как 32бит и% X интерпретируются как 32-битные, тогда вы получите предупреждение о 64-битном назначении, но printf имеет немного больше смысла.

Из-за этой боли компиляторы, такие как gcc, пытаются заставить вашжизнь лучше, если предположить, что когда вы используете функцию с именем printf (), вы используете стандартную C, и они анализируют строку формата в поисках этих типов распространенных ошибок.

3 голосов
/ 20 февраля 2012

Нет, есть соглашение, вам просто нужно посмотреть документацию .

И спецификаторы форматирования не являются отображением 1: 1 типа, они управляют форматом вывода (отсюда и название). Для одного типа входного значения может быть много форматов вывода.

Например, %d является «десятичным», поскольку печатает целое число в виде десятичного числа. Также есть %i ("целое число"), которое делает то же самое.

Для значений unsigned int у вас есть и %x (печать в шестнадцатеричном формате) и %u (печать в восьмеричном).

1 голос
/ 20 февраля 2012

Однако я не очень понимаю, что делаю.

То, что вы делаете, говорит функции printf, как отображать данные, которые вы предоставляете после строки формата. Вы, вероятно, обнаружите, что %lo на самом деле не печатает ожидаемые результаты - он печатает правильные данные, но в восьмеричном (основание 8) формате.

Существует ли соглашение об именах для получения краткой формы типа? Например, int это% d, почему ??

«Краткая форма» называется спецификатором формата. Нет соглашения, позволяющего получить соответствующий спецификатор формата printf. Вам просто нужно посмотреть их в соответствующей справке .

0 голосов
/ 20 февраля 2012

% lo = длинное целое число без знака, напечатанное в восьмеричных цифрах.да, документы - хорошее место для начала ... но у некоторых есть шаблон, например, o для восьмеричного, x для шестнадцатеричного, l для любого длинного и т. д. Использование многих таких спецификаторов формата поможет вам получить шаблон везде, где он есть.

...