// Debian Linux 32bit #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <inttypes.h> typedef struct data_t { unsigned int a:12; unsigned int b:20; } data_t; int main() { uint8_t u8i = 1; uint16_t u16i = 1; uint32_t u32i = 1; uint64_t u64i = 1; data_t data; data_t *pdata = malloc(sizeof(data_t)); //printf("%x", (unsigned int)data); // Error: aggregate value used where an integer was expected printf("1 %x\n", *(unsigned int *)&data); printf("2 %x\n", u8i); // OK printf("3 %x\n", u16i); // OK printf("4 %x\n", u32i); // OK printf("5 %llx\n", u64i); // in 64bit, gcc will report warning, format '%llx' expect argument of type 'long long unsigned int', but argument 2 has type 'uint64_t' printf("6 %lx\n", u64i); // in 32bit, gcc will report warning, format '%lx' expect argument of type 'long unsigned int', but argument 2 has type 'uint64_t' printf("7 %"PRIu64"\n", u64i); // OK, with portable format string introduced in C99 printf("8 %p\n", pdata); // OK, will automatically add prefix "0x" printf("9 %x\n", pdata); // warning, and without prefix "0x" printf("10 %#x\n", pdata); // identical to %p, but with warning printf("11 %#lx\n", pdata); // identical to %p, but with warning free(pdata); return 0; }
输出为:
1 80485c0
2 1
3 1
4 1
5 1
6 1
7 1
8 0x97e5008
9 97e5008
10 0x97e5008
11 0x97e5008
几个值得注意的地方:
1. 由于uint64_t在32位和64位机上的定义是不一样的,所以移植的时候会出warning。可以用C99引入的可移植的描述符:
这些宏一般都以PRI开头,可以参见/usr/include/inttypes.h,也可以见http://en.wikipedia.org/wiki/Printf#Format_placeholders。
2. 如果一个结构体刚好是32位,想用%x输出,直接输出会出错,需要两次转型。
3. 输出地址是优先选%p,它会自动输出"0x",并且也方便移植。