Где `% p` полезно использовать printf?
В конце концов, оба этих утверждения делают то же самое...
int a = 10;
int *b = &a;
printf("%p\n",b);
printf("%08X\n",b);
Например (с разными адресами):
0012FEE0
0012FEE0
Тривиально форматировать указатель по желанию с помощью %x
, так хорошо ли использовать параметр %p
?
Ответы
Ответ 1
Они не делают то же самое. Последний printf
оператор интерпретирует b
как unsigned int
, что неверно, поскольку b
является указателем.
Указатели и unsigned int
не всегда одинакового размера, поэтому они не взаимозаменяемы. Когда они не имеют одинаковый размер (все более распространенный случай, когда 64-битные процессоры и операционные системы становятся более распространенными), %x
будет печатать только половину адреса. На Mac (и, возможно, в некоторых других системах) это разрушит адрес; выход будет неправильным.
Всегда используйте %p
для указателей.
Ответ 2
По крайней мере, в одной системе, которая не очень необычна, они не печатают одно и то же:
~/src> uname -m
i686
~/src> gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
[some output snipped]
gcc version 4.1.2 (Gentoo 4.1.2)
~/src> gcc -o printfptr printfptr.c
~/src> ./printfptr
0xbf8ce99c
bf8ce99c
Обратите внимание, как версия указателя добавляет префикс 0x
, например. Всегда используйте% p, так как он знает о размере указателей и как наилучшим образом представлять их в виде текста.
Ответ 3
Вы не можете зависеть от %p
отображения префикса 0x
. На Visual С++ это не так. Используйте %#p
для переноски.
Ответ 4
Размер указателя может отличаться от размера int
. Кроме того, при использовании %p
для реализации может быть лучше, чем простое шестнадцатеричное представление адреса.
Ответ 5
x
Незначенное шестнадцатеричное целое число (32 бит)
p
- адрес указателя
См. printf в С++ Reference. Даже если оба они будут писать то же самое, я бы использовал %p
для печати указателя.
Ответ 6
Когда вам нужно отлаживать, использование параметра printf с %p
действительно полезно. Вы видите 0x0, когда у вас есть значение NULL.
Ответ 7
x
используется для печати аргумента t указателя в шестнадцатеричном формате.
Типичный адрес при печати с использованием %x
будет выглядеть как bfffc6e4
, а назначенный по умолчанию адрес %p
будет 0xbfffc6e4