// 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",并且也方便移植。