一级指针
对于一级指针来讲, 我们再熟悉不过的应用就是修改实参的值
注意下方应用:
#include <stdio.h>
void changeValue(int* value);
int main() {
int num = 2018;
changeValue(&num);
printf("%d\n", num);
return 0;
}
void changeValue(int* value) {
*value = 2019;
}
效果图
从以上的实例可以看出, 我们可以通过指针来修改实参的值, 这里涉及到了一个实参和形参的概念, 我们进一步探讨
所谓的实参, 即传递给调用函数的参数, 在内存中占有指定的空间; 而形参是实参的一份拷贝, 函数调用开始为形参分配指定空间, 函数调用结束后该形参就被释放. 因此, 函数调用发生的实参向形参的数据传递是单向的
我们可以这样理解, 如果实参是以变量本身向形参传递数据, 则函数调用过程中, 形参是实参的一份拷贝, 临时分配的内存与实参不一样, 实参不随形参的改变而改变; 如果实参是以地址(即指针)的形式向形参传递数据, 则调用函数过程中, 形参的内存地址就是实参的内存地址, 实参就会随形参的改变而改变.
总而言之, 运用函数对数据的更新, 是基于数据的地址传递, 对数据的地址进行操作而言的
二级指针
对于二级指针, 我们不妨看一下下面这个例子:
#include <stdio.h>
void changeAddress(int** value);
int main() {
int arr[] = {1, 2, 3};
int* p = arr;
// 改变之前 p 的地址
printf("%p\n", p);
// q 用来保存改变之前 p 的地址
int* q = p;
changeAddress(&p);
// 改变之后 p 的地址
printf("%p\n", p);
// 地址改变的差值
printf("%lu\n", p - q);
return 0;
}
void changeAddress(int** value) {
*value += sizeof(int);
}
效果图
仔细一看, 这个例子是不是与一级指针的例子大同小异呢
没错, 如果说一级指针是用于对数据的更新, 那么二级指针就是用于对数据地址的更新. 以此类推, 三级指针就是对数据地址的地址的更新…