2010-03-03 4 views
44

В конце концов, оба эти заявления делают то же самое ...Где `% p` полезен с printf?

int a = 10; 
int *b = &a; 
printf("%p\n",b); 
printf("%08X\n",b); 

Например (с различными адресами):

0012FEE0 
0012FEE0 

Тривиально форматировать указатель по желанию с %x, так есть ли хорошее использование опции %p?

+1

С помощью '% p' ​​вы печатаете адрес переменной, о которой идет речь, «Указатель указателя void * печатается в шестнадцатеричном виде (как будто на% # x или% # lx)." –

+0

В C++ вы можете использовать (void *) typecast: см. Http://stackoverflow.com/questions/5657123/how-to-simulate-printfs-p-format-when-using-stdcout –

ответ

111

Они не делают то же самое. Последний printf оператор интерпретирует b как unsigned int, что неверно, так как b является указателем.

Указатели и unsigned int s не всегда одинакового размера, поэтому они не являются взаимозаменяемыми. Когда они не имеют одинаковый размер (все более распространенный случай, когда 64-битные процессоры и операционные системы становятся все более распространенными), %x будет печатать только половину адреса. На Mac (и, возможно, в некоторых других системах) будет разрушить адрес; выход будет неправильным.

Всегда используйте %p для указателей.

+12

% p также будет использовать адекватное текстурное представление для указателя для платформы. На платформах, где обычно указывать указатель в шестнадцатеричном формате, это не будет иметь значения до тех пор, пока размер будет правильным, но для сегментированной архитектуры (вы помните DOS?) Он может использовать представление сегмента: смещение. – AProgrammer

+8

Также нужно использовать 'b' для' void * 'с форматом'% p' - это один из немногих экземпляров на C, где вам нужно бросить. –

+1

«Все в мире VAX!» синдром. –

2

x является целым числом без знака шестнадцатеричное (32 бита)

p это указатель адреса

См printf on the C++ Reference. Даже если оба они будут писать то же самое, я бы использовал %p для печати указателя.

+0

Да, я уже прошел это страница.Я хотел знать, почему вы использовали% p для печати указателя. В любом случае ответ Питера Хоуси отвечает на мои сомнения. – Moeb

4

Размер указателя может отличаться от размера int. Кроме того, при использовании %p реализация может привести к лучшему представлению адреса шестнадцатеричного значения.

-1

x Используется для печати аргумента t указателя в шестнадцатеричном формате.

Типичный адрес при печати с использованием %x будет выглядеть bfffc6e4 и здравомыслящий адрес распечатаны с помощью %p будет 0xbfffc6e4

+0

Нет, '% x' используется для печати значения типа' unsigned int' в шестнадцатеричном формате. Нет абсолютно никакой гарантии, что 'unsigned int' имеет тот же размер, что и' void * ', и это плохая идея предположить в коде. – unwind

7

По крайней мере, на одной системе, которая не очень редко, они не печатают то же самое:

~/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, так как он знает о размере указателей и как лучше всего представлять их в виде текста.

5

Вы не можете зависеть от %p, отображая префикс 0x. На Visual C++ это не так. Используйте портативный компьютер %#p.

+1

Является ли это документированным где-то? Я не могу найти ничего о #, используемом вместе с% p. Я проверил: http://msdn.microsoft.com/en-us/library/8aky45ct(v=vs.71).aspx http://www.cplusplus.com/reference/clibrary/cstdio/printf/ – Suma

+0

ПК -Lint не нравится, но работает в Visual Studio. К сожалению, он добавляет «0X» не «0x», что делает текущую ценность трудночитаемой. Предположительно, это связано с отсутствием варианта «% P». Все сказано, что этот спецификатор формата страдает от проблемы всех реализаций, зависящих от платформы, что вы не можете реально контролировать то, что собираетесь получить. Я использую «0x% p», рискуя получить двойной 0x0X в начале. Скорее подрывает его использование, потому что вы точно знаете, что получаете с% x. –

0

Когда вам нужно отлаживать, использование параметра printf с параметром %p действительно полезно. Вы видите 0x0, когда у вас есть значение NULL.

Смежные вопросы