在学习apue的11.5 Threads时,有一个实例代码,其中有一个打印地址fp的语句printf(" structure at 0x%lx ", (unsigned long)fp);为什么要将指针变量fp强制转换为unsigned long再打印呢,(为了兼容unix的各种分支平台)以前学习c语言的经验是指针变量占用空间大小是4个字节,查阅资料后发现:
void printfoo(const char *s, const struct foo *fp) { printf("%s", s); printf(" structure at 0x%lx ", (unsigned long)fp); printf(" foo.a = %d ", fp->a); printf(" foo.b = %d ", fp->b); printf(" foo.c = %d ", fp->c); printf(" foo.d = %d ", fp->d); }
指针的空间大小没有固定的值,它取决于体系结构、编译器实现、指针的类型(指向不同类型变量的指针不一定有相同的空间大小或表示方法)
例如,假设有一个word-addressed architecture,where最小的存储地址单元是16位,每一个字可以存储多个char类型的变量,所有其他类型占据一整个字或者多个字,在这样的体系结构中,一个指针型的变量可能需要一些额外的位表示字里面的偏移量
还有就是一个指针类型的变量的位数可能比实际上需要的用来存储一个地址的位数多,最初是的运行在Motorola 68000CPU上的Macintosh系统的字大小为32位,但是仅有24位属于地址总线,指针类型是32位宽,其中有8个位没有使用,MacOS程序员利用了这个特性来存储一些数据,利用一个指针类型的高字节地址,充分利用了宝贵的128字节的随机访问存储空间,后来Motorola最终发布了一个32位地址线的CPU,意味着那些代码需要重写。
C99提供了intptr_t和uintptr_t类型,是整数,并且保证足够宽以满足存放一个指针变量。