Вопрос по unsigned-long-long-int, syntax, printf, c – Печать без знака long long int Тип значения возвращает странные результаты

10

У меня проблема при использованииprintf функция для печати значений типаunsigned long long int

Я понятия не имею, что не так. Я использую Dev-Cpp 4.9.9.2 и Visual Studio 2010 Professional (я знаю, что это не компилятор C, но все равно хотел попробовать) на 64-битной Windows 7 Professional. Для отображения я использовал%llu модификатор (согласноКак вы печатаете unsigned long long int (спецификатор формата для unsigned long long int)?) но я тоже пробовал I64d безрезультатно ...

Во-первых, я просто хотел напечатать минимальное и максимальное значениеunsigned long long int (с помощьюULONG_MAX отlimits.h)

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);

Возвращает:

unsigned long long int: 18446744069414584320 to 1580552164021 (Dev-Cpp)

unsigned long long int: 18446744069414584320 to 0 (Visual Studio)

Тогда я попытался с помощьюprintf напечатать два нуля

printf("unsigned long long int: \n%llu to %llu \n\n", 0, 0);

Возвращает:

unsigned long long int: 0 to 1580552164021 (Dev-Cpp)

unsigned long long int: 0 to 0 (Visual Studio)

Также попробовал дваULONG_MAX ценности

printf("unsigned long long int: \n%llu to %llu \n\n", ULONG_MAX, ULONG_MAX);

Возвращает:

unsigned long long int: 18446744073709551615 to 1580552164021 (Dev-Cpp)

unsigned long long int: 18446744073709551615 to 0 (Visual Studio)

Почему он так себя ведет? Не могли бы вы объяснить это мне?

Ваш Ответ

4   ответа
11

printf("unsigned long long int: \n%llu to %llu \n\n", 0, ULONG_MAX);

Вы используетеunsigned long long спецификатор формата, но вы передаетеint иunsigned long значение. Правила продвижения означают, что вы можете быть небрежным для всегоintили меньше, что делаетnot применить кlong long.

Используйте броски:

printf("unsigned long long int: \n%llu to %llu \n\n",
       0ULL, (unsigned long long) ULONG_MAX);

Explanation: При передаче аргументовprintfлюбой тип, который может вписаться вint повышен доint, а затем любой тип, который может вписаться вunsigned int повышен доunsigned int, Также можно передавать тип без знака в спецификатор формата со знаком или наоборот, еслиvalue переданный может быть представлен с использованием типа, указанного спецификатором формата.

Так что вы должны быть осторожны сlong а такжеlong long, но вы можете быть неряшливым сint, short, а такжеchar.

Most compilers иметь настройки, чтобы предупредить вас об этом типе ошибки, так как она может быть обнаружена во время компиляции довольно легко; GCC и Clang имеют-Wformat что приводит к следующим предупреждениям:

test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 2 has type ‘int’
test.c:5: warning: format ‘%llu’ expects type ‘long long unsigned int’, but argument 3 has type ‘long unsigned int’
Это было небрежно.
0 это int, не долго.
10

unsigned long longs, Вы передаетеint (0) иunsigned long (ULONG_MAX). Вы должны перейти кprintf() именно то, что вы обещаете передать в строке формата.

Попробуйте это вместо:

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, (unsigned long long)ULONG_MAX);
4

ULONG_MAX относится кunsigned long и неunsigned long long, Для последнего используйтеULLONG_MAX (обратите внимание на дополнительныеL).

Вам нужно изменитьprintf() звонки так:

printf("unsigned long long int: \n%llu to %llu \n\n", 0ULL, ULLONG_MAX);
printf("unsigned long long int: \n%llu to %llu \n\n", ULLONG_MAX, ULLONG_MAX);

Это гарантирует, что аргументыprintf() соответствовать спецификаторам формата.

0

MSVC не поддерживает это. Возьмите компилятор с поддержкой C99 (например, MinGW для Windows), и он будет работать.

MSVC поддерживаетlong long несмотря на то, что не полностью поддерживает C99.

Похожие вопросы