Разница между печатью адреса памяти с использованием% u и% d в C? - PullRequest
12 голосов
/ 06 марта 2011

Я читаю С книгу. Чтобы распечатать адрес памяти переменной, иногда книга использует:

printf("%u\n",&n);

Иногда автор писал:

printf("%d\n",&n);

Результат всегда одинаков, но я не понимаю различий между ними (я знаю% u для неподписанных).

Кто-нибудь может уточнить, пожалуйста?

Большое спасибо.

Ответы [ 5 ]

38 голосов
/ 06 марта 2011

%u рассматривает целое число как беззнаковое, тогда как %d рассматривает целое число как подписанное.Если целое число находится в диапазоне от 0 до 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, вы 'получит неправильный результат для этого и всего остального, что будет напечатано позже (потому что 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.

1 голос
/ 06 марта 2011

%d и %u будут печатать одинаковые результаты, если старший значащий бит не установлен. Тем не менее, это не переносимый код и не хороший стиль. Я надеюсь, что ваша книга лучше, чем кажется из этого примера.

0 голосов
/ 27 сентября 2018

Такой разницы нет, просто не запутайтесь, если вы только начали изучать указатели.% u для неподписанных. И% d для подписанных

0 голосов
/ 06 марта 2011

Все адреса являются 32-разрядными или 64-разрядными без знака в зависимости от компьютера (запись на отрицательный адрес невозможна).Использование% d не подходит, но обычно работает.Рекомендуется использовать% u или% ul.

0 голосов
/ 06 марта 2011

Какое значение вы пробовали?Разница между неподписанным и подписанным, как вы и сказали.Так что же он сделал и что вы ожидали?

Положительные значения со знаком выглядят так же, как и без знака, так что я могу предположить, что вы использовали меньшее значение для проверки?А как насчет отрицательного значения?

Наконец, если вы пытаетесь напечатать адрес переменной (как вам кажется), используйте вместо нее% p.

...