指针, C语言的精髓
什么是指针
保存变量地址的变量叫做指针.
这是大概的定义, 但是Defad认为这个定义不太好理解, 所以我们先不看.
我们的电脑里都有随机存储器 RAM 也就是内存条, 所有变量和数组都在这里, 这个应该大家都知道.
那么我们把内存条看成数组, 头地址显然是 0
.
那么现在我们有一个整数变量 x
.
int x;
这个 x
在内存条哪里呢?
&
可以获取变量在内存条的下标, 所以 x
的下标是 &x
.
那么我们怎么访问内存条的第 &x
项呢?
刚才我们说, 内存条头地址是 0
, 根据数组访问的方法, 可以想到用 0[&x]
访问变量 x
.
那么我们现在用一个变量存储这个 x
的下标.
int *p = &x;
int*
类型表示保存 int
类型变量在内存条里的下标的变量.
所以我们可以用 p
代替 &x
就是 0[p]
.
但是我们现在有一个语法糖.
*p
就是表示 0[p]
, 因为数组访问的本质是指针移动, 比如 a[3]
实际上是 *(a + (3))
.
所以我们可以用 *p
来访问在内存条里 p
保存的下标.
同理 *&x
也一样, 但是你变量都在这了就不需要取下标再访问下标了.
指针能干什么
我们有一个栈存储我们调用的函数和函数内部开的变量, 叫系统栈.
但是这样带来的问题就是我们给函数传入的变量是把值传进去了, 函数并不知道是要对值更改还是对变量本省更改.
现在有了指针就好办多了.
比如写一个交换函数.
void exchange(int *x, int *y) {
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
就可以传入地址后在内部做交换.
还有, 我们可以申请一块内存, 使用完再释放掉.
// 申请, 这里要强转成目标类型
int *a = (int*)malloc(sizeof(int) * 100);
// 这里做点什么
free(a); // 释放
申请来的可以当数组用, 也可以当变量用, 需要指针访问 (类似 *p
).
比如平衡树的一个结点, 插入时申请一个, 删除时释放掉.
这样其实相当于一个垃圾回收机制.