Intereting Posts
Ошибка: управление может достигать конца не-void функции в C Объект enums установлен в значение, не равное любой из его соответствующих констант enums Об общем указателе на char и строгом псевдониме сокращенный указатель typedef на константу struct C: Почему неназначенные указатели указывают на непредсказуемую память и НЕ указывают на NULL? typedef тип указателя функции Двоичный к unsigned int, используя побитовые операции и арифметику указателя в C 32-разрядный код _asm для 64-разрядного ассемблерного кода в Windows AttributeError: объект ‘module’ не имеет атрибута при попытке импортировать c-код в python Каковы другие варианты более быстрого ввода-вывода в C Запись данных в файл: fflush () занимает много времени Возврат из функции void Форматировать атаку строки в printf C: malloc, кажется, выделяет больше, чем я запрашиваю (массив) Эллипсис в инициализации массива в модуле ядра C

Печать unsigned long long int Тип значения Возвращает странные результаты

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

Я понятия не имею, что случилось. Я использую Dev-Cpp 4.9.9.2 и Visual Studio 2010 Professional (я знаю, что это не компилятор C, но в любом случае хотел попробовать) на Windows 7 Professional 64-bit. Для отображения я использовал модификатор %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 – 1580552164021 (Dev-Cpp)

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


Затем я попытался использовать printf для печати двух нhive

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

Возвращает:

unsigned long long int: от 0 до 1580552164021 (Dev-Cpp)

unsigned long long int: от 0 до 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 до 1580552164021 (Dev-Cpp)

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


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

Это не верно:

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

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

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

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

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

Поэтому вы должны быть осторожны с long и long long , но вы можете быть неаккуратными с int , short и char .

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

 test.c: 5: warning: format '% llu' ожидает тип long long unsigned int, но аргумент 2 имеет тип 'int'
 test.c: 5: warning: format '% llu' ожидает тип long long unsigned int, но аргумент 3 имеет тип long long unsigned int,

Вы не пропустите 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); 

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() спецификаторам формата.

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