Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Difference between %p and %x in C/C++
Here we will see what are the differences between %p and %x in C or C++. The %p format specifier is used to print pointer values (memory addresses), while %x is used to print unsigned integers in hexadecimal format. Though pointers can also be displayed using %u or %x, the correct and portable way to print a pointer is %p.
The visible difference is that %p prints with leading zeros and is platform-width aware (16 hex digits on 64-bit systems, 8 on 32-bit), while %x prints only the significant digits without padding.
Syntax
printf("%p", pointer); // prints address with leading zeros
printf("%x", integer); // prints integer as hexadecimal (lowercase)
printf("%X", integer); // prints integer as hexadecimal (uppercase)
Example − Comparing %p and %x
The following example shows how the same value appears differently with %p and %x −
#include <stdio.h>
int main() {
int x = 59;
printf("Value using %%p: %p\n", (void *)&x);
printf("Value using %%x: %x\n", x);
printf("Value using %%X: %X\n", x);
return 0;
}
The output of the above code is −
Value using %p: 0x7ffd5e8a3c4c Value using %x: 3b Value using %X: 3B
Notice that %p prints the full memory address of x with a 0x prefix, while %x prints the value 59 as 3b in hexadecimal without leading zeros. %X prints the same but in uppercase.
Example − Printing Pointer Addresses
The correct use of %p is to print the memory address held by a pointer variable −
#include <stdio.h>
int main() {
int a = 100;
int *ptr = &a;
printf("Value of a: %d\n", a);
printf("Address using %%p: %p\n", (void *)ptr);
printf("Address using %%x: %x\n", (unsigned int)(unsigned long)ptr);
return 0;
}
The output of the above code is −
Value of a: 100 Address using %p: 0x7ffc12ab9d24 Address using %x: 12ab9d24
When using %x to print a pointer, the address may be truncated on 64-bit systems because %x expects an unsigned int (32 bits), while a pointer may be 64 bits. This is why %p is the safe and portable choice for printing addresses.
Key Differences
| Feature | %p | %x |
|---|---|---|
| Purpose | Print pointer (memory address) | Print unsigned int as hexadecimal |
| Expected argument | void * |
unsigned int |
| Leading zeros | Yes (platform-width padded) | No |
| Prefix | Typically 0x (implementation-defined) |
None (unless %#x is used) |
| Width | Matches pointer size (8 or 16 hex digits) | Only significant digits |
| 64-bit safe | Yes | No (truncates upper 32 bits) |
| Case | Implementation-defined | Lowercase (%X for uppercase) |
Conclusion
The %p format specifier is designed specifically for printing pointer addresses and is portable across 32-bit and 64-bit systems. The %x specifier prints unsigned integers in hexadecimal and should not be used for pointers, as it may truncate the address on 64-bit platforms. Always use %p with a (void *) cast when printing memory addresses.
