一切皆为地址
C语言用变量来存储数据,用函数来定义一段功能代码,它们最终都要放到内存中供 CPU 调用。
数据和代码都以二进制的形式存储在内存中,计算机无法从格式上区分某块内存存储的是数据还是代码。当程序被加载到内存后,操作系统会给不同的内存块指定不同的权限,拥有读取和执行权限的内存块就是代码,而拥有读取和写入权限(也可能只有读取权限)的内存块就是数据。
CPU访问内存时需要的是地址,而不是变量名或函数名。程序在执行过程中会告知 CPU 要执行的代码以及要读写的数据的地址。变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。
何为指针
计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节,char 占用 1 个字节。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。这个编号就是指针(Pointer)。
也就是说,指针是一个变量,其值为另一个变量的地址(Address),即变量在内存中字节的编号。
指针变量的声明
与其他变量或常量一样,在使用指针存储其他变量地址之前,需对其进行声明。指针变量声明的一般形式为:
type *var_name;
其中 type 是指针的类型,它必须是一个有效的 C 数据类型,var_name 是指针变量的名称。
如下图所示,x是一个整型变量,其值为8,p是一个整型指针,指向x。使用&操作符取得变量x的地址,将其赋给p,从而使p指向变量x的地址;使用*操作符即可访问该地址存储的变量值。
用来声明指针的星号 * 与乘法所使用的星号是相同的。但在这里,星号是用来声明这个变量是指针。
char *pc; /* 一个字符型指针 */
int *pi; /* 一个整型指针 */
float *pf; /* 一个浮点型指针 */
double *pd; /* 一个 double 型指针 */
指针变量的大小
在32位计算机中,一个指针变量所占的字节数通常是4,在64位系统中通常为8。
如下图所示,在64位机器上,指针变量所占的字节数都是8。
sizeof是C/C++中的一个操作符(operator),其作用是返回一个对象或者类型所占的内存字节数。