Ответ 1
%u
обрабатывает целое число как unsigned, тогда как %d
обрабатывает целое число как подписанное. Если целое число находится между 0 an INT_MAX
(которое равно 2 31 -1 в 32-битных системах), то вывод идентичен для обоих случаев.
Это только имеет значение, если целое число отрицательное (для подписанных входов) или между INT_MAX+1
и UINT_MAX
(например, между 2 31 и 2 32 - 1). В этом случае, если вы используете спецификатор %d
, вы получите отрицательное число, тогда как если вы используете %u
, вы получите большое положительное число.
Адреса имеют смысл только как неподписанные числа, поэтому никогда не будет никаких причин печатать их как подписанные числа. Кроме того, когда они распечатываются, они обычно печатаются в шестнадцатеричном формате (с спецификатором формата %x
), а не десятичным.
Вы действительно должны просто использовать спецификатор формата %p
для адресов, хотя это гарантировано для работы для всех действительных указателей. Если вы используете систему с 32-разрядными целыми числами, но 64-разрядными указателями, если вы пытаетесь напечатать указатель с любыми %d
, %u
или %x
без модификатора длины ll
ll получить неправильный результат для этого и что-нибудь еще, которое будет напечатано позже (потому что printf
читает только 4 из 8 байтов аргумента указателя); если вы добавите модификатор длины ll
, то вы не будете переносимы в 32-разрядные системы.
Нижняя строка: всегда используйте %p
для вывода указателей/адресов:
printf("The address of n is: %p\n", &n);
// Output (32-bit system): "The address of n is: 0xbffff9ec"
// Output (64-bit system): "The address of n is: 0x7fff5fbff96c"
Точный формат вывода определяется реализацией (C99 §7.19.6.1/8), но он будет почти всегда печататься как шестнадцатеричное число без знака, обычно с ведущим 0x
.