Для школьного проекта я пытаюсь воссоздать функцию printf
библиотеки stdio.h
на C.
В настоящее время я работаю над тем, чтобы заставить работать часть печати unsigned int
, но по какой-то причине, почему я пытаюсь распечатать настоящий printf
беззнаковый int, он выдает мне предупреждение (что считается ошибкой в моей школе). Не могли бы вы объяснить мне, почему?
Вот строка кода, которую я использовал: printf("%u\n", 4294967295);
. И вот ошибка, которую я получаю:
main.c:18:17: warning: format specifies type 'unsigned int' but the argument has type 'long' [-Wformat]
printf("%u\n", 4294967295);
~~ ^~~~~~~~~~
%ld
1 warning generated.
Вы должны писать 4294967295U
, а не 4294967295
.
Спасибо, это решило это. Цените помощь.
Тип целочисленных констант не является фиксированным и зависит от того, какой тип может фактически представлять это значение.
Только что восстановил @bruno
Кажется, вы пытаетесь напечатать целое число без знака, но значение, которое вы передали в printf("%u\n", 4294967295)
, имеет тип long. Итак, вы можете попробовать изменить тип данных на unsigned long int
Тип целочисленного литерала берется первым подходящим типом в списке стандарта. Список литералов без суффикса any: int
, long int
, long long int
/unsigned long int
. Поскольку 4294967295 не помещается в int
, он будет long
, если long
имеет тип шире 32-бит (что имеет место на вашей платформе). Чтобы получить литерал unsigned int
, вам нужно использовать суффикс U
Тип целочисленной константы
Тип целочисленного литерала — это первый тип, которому может соответствовать значение, из списка типов, который зависит от того, какая числовая база и какой целочисленный суффикс был использован.
Типы допустимых целочисленных констант:
- без суффикса
- десятичные основания:
- инт
- длинный внутренний
- беззнаковое длинное целое (до C99)
- long long int (начиная с C99)
- другие базы:
- инт
- беззнаковое целое
- длинный внутренний
- беззнаковое длинное целое
- long long int (начиная с C99)
- unsigned long long int (начиная с C99)
- ...
Если значение целочисленной константы слишком велико, чтобы соответствовать любому из типов, разрешенных комбинацией суффикс/база, и компилятор поддерживает расширенные целочисленные типы (например,
__int128
), константе может быть присвоен расширенный целочисленный тип; в противном случае программа плохо сформирована.
Это своего рода ответ C++. C не имеет двоичной базы, и в случае, если число не подходит для расширенного целочисленного типа, оно не имеет типа - оно не является "неправильным", в C нет ничего, что называется неправильно сформированным.
@Lundin C23 имеет литерал двоичного целого числа en.cppreference.com/w/c/language/integer_constant
Это еще предстоит выяснить, этот стандарт все еще находится в разработке.
Все целочисленные константы, такие как 4294967295
, имеют тип, как и объявленные переменные. Компилятор C присваивает тип такой константе на основе различных сложных правил. Упрощенное объяснение заключается в том, что эти правила в основном сводятся к следующему:
int
? Если да, сделайте это int
».long
?» ... и так далее.Обратите внимание, что эти типы по умолчанию являются подписанными типами.
На 32-битном компьютере с 32-битным int максимальное число, которое вы можете сохранить в int
, равно 2^31 - 1 = 2147483647
. 4294967295
больше, поэтому компилятор должен сохранить его в long
. Отсюда предупреждение.
Поскольку 4294967295
поместилось бы в unsigned int
, вы могли бы исправить код, просто заставив компилятор обрабатывать целочисленную константу как беззнаковую: 4294967295u
.
Предупреждение вполне ясное. Какую часть вы не понимаете?