C 语言指针
基本概念
指针代表内存地址。
通常在类型关键字的后面加字符*
来表示指针,表示指针指向什么类型的值。比如,char*
表示一个指向字符的指针,float*
表示一个指向float
类型值的指针。
指针指向的可能还是指针,这时要用两个星号**
表示。
int** foo;
指针变量初始化
声明指针变量之后,编译器会为指针变量分配一个内存空间,但是这个内存空间里面的值是随机的。
因此,指针变量声明后,必须先让它指向一个分配好的地址,然后再进行读写,这叫做指针变量的初始化。
int* p;
int i;
p = &i;
为了防止读写未初始化的指针变量,可以将未初始化的指针变量设为NULL
。
int* p = NULL;
指针运算符
* 运算符
*
号除了表示指针以外,还可以作为运算符,用来取出内存地址里面的值。
void increment(int* p) {
*p = *p + 1;
}
*p
表示指针p
指向的值。对*p
赋值,会改变指针所指向的地址里面的值。
& 运算符
&
运算符用来取出变量所在的内存地址。
int x = 1;
printf("x"s address is %p
", &x); // %p是内存地址的占位符
&
运算符与*
运算符互为逆运算。
int i = 5;
if (i == *(&i)) // 正确
指针运算
指针本质上是一个无符号整数,代表了内存地址。它可以进行运算,但是规则并不是整数的规则。
- 指针与整数值的加减运算
指针与整数值的运算,表示指针的移动。
short* j;
j = (short*)0x1234;
j = j + 1; // 0x1236
上面示例中,j
是一个指针,指向内存地址0x1234
。你可能以为j + 1
等于0x1235
,但正确答案是0x1236
。原因是j + 1
表示指针向内存地址的高位移动一个单位,而一个单位的short
类型占据两个字节的宽度,所以相当于向高位移动两个字节。同样的,j - 1
得到的结果是0x1232
。
指针移动的单位,与指针指向的数据类型有关。数据类型占据多少个字节,每单位就移动多少个字节。
- 指针与指针的加法运算
虽然指针本质上是一个无符号整数,但是指针只能与整数值进行加减运算,两个指针进行加法是非法的。
- 指针与指针的减法
相同类型的指针允许进行减法运算,返回它们之间的距离,即相隔多少个数据单位。
高位地址减去低位地址,返回的是正值;低位地址减去高位地址,返回的是负值。
减法返回的值属于ptrdiff_t
类型,这是一个带符号的整数类型别名,具体类型根据系统不同而不同。这个类型的原型定义在头文件stddef.h
里面。
short* j1;
short* j2;
j1 = (short*)0x1234;
j2 = (short*)0x1236;
ptrdiff_t dist = j2 - j1;
printf("%d
", dist); // 1
- 指针与指针的比较运算
指针之间的比较运算,比较的是各自的内存地址哪一个更大,返回值是整数1
(true)或0
(false)。
参考: C 语言教程