字符指针变量
什么是指针变量呢?字符指针变量是一种特殊的指针变量,它专门用于存储字符型数据的地址。
代码1:
//示例1
int main() {
char ch = 'a';
char* pc = &ch;
*pc = 'a';
return 0;
}
//示例2
int main() {
const char* pstr = "hello world";
printf("%s\n", pstr);
return 0;
}
总之,字符指针变量就是存放字符地址的指针。
数组指针变量
我们已经知道了字符指针变量,那数组指针变量又是什么呢?数组指针变量指的是存放数组的地址并且是能够指向数组的指针变量。
思考1:
下面那个代码是数组指针变量?p1和p2分别是什么?
int* p1[10];
int (*p2)[10];
在这两个指针变量中,p1
是一个指针数组。它本质上是一个数组,数组的每个元素都是 int*
类型,也就是指向 int
类型的指针;p2
是一个数组指针,它指向一个包含10个 int
类型元素的数组 。所以指针变量p2就是指针变量。
解析1:
//数组指针变量解析
int (*p) [10] = &arr;
| | |
| | |
| | p指向数组的元素个数
| p是数组指针变量名
p指向的数组的元素类型
二维数组传参的本质
说到二维数组的传参本质,我们先来复习一下一维数组传参的本质,即本质上一维数组传参传递的是数组首元素的地址。
关于二维数组作者这里再解释一下。我们知道,空间是多维的,有一维也有二维,一维就很容易理解,用数学几何来表示一维就是一条x轴线,不过这条x轴线是横向的。二维只不过是在一维的基础上再增加了一维,怎么理解呢?简单来说,二维用数学几何表示就是直角坐标系,这就很容易理解了吧!二维在x轴线的基础上增加了一条y轴线,不过这条直线是纵向的。
那么二维数组就很容易理解了吧!
事实上二维数组其实可以看做是每个元素是一维数组的数组,也就是二维数组的每个元素是一个一维数组。那么,二维数组的首元素就是第一行是一个一维数组。
图1:
0 1 2 3 4
0 1 2 3 4 5
1 2 3 4 5 6
2 3 4 5 6 7
所以根据数组名是数组首元素的地址这个规则,二维数组的数组名表示的就是第一行的地址,是一维数组的地址。
这就意味着二维数组传参本质上也是传递了地址,传递的是第一行这个一维数组的地址。
代码1:
#include<stdio.h>
void test(int (*p)[5], int r, int c) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("%d", *(*(p + i) + j));
}
printf("\n");
}
}
int main() {
int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
test(arr, 3, 5);
return 0;
}
总之,⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式。
函数指针变量
什么是函数指针变量呢?根据前面我们学的指针知识,不难得出结论,函数指针变量应该是用来存放函数地址的,未来通过地址能够调用函数。
思考1:
函数是否具有地址?
代码1:
#include<stdio.h>
void test() {
printf("hehe\n");
}
int main() {
printf(" test: %p\n", test);
printf("&test: %p\n", &test);
return 0;
}
输出结果:
test: 005913CA
&test: 005913CA
可以看出,函数确实是有地址的,函数名就是函数的地址。
这时候函数指针的作用就凸显出来了,如果要将函数的地址存放起来,就得创建函数指针变量。
代码2:
void test() {
printf("hehe\n");
}
void(*p1) = &test;
void(*p2)) = test;
int Add(int x, int y) {
return x + y;
}
int (*p3)(int, int) = Add;
int (*p4)(int x, int y) = &Add;
解析:
函数指针解析
int (*p3) (int x,int y)
| | |
| | |
| | p3指向函数的参数类型和个数的交代
| 函数指针变量名
p3指向函数的返回类型
函数指针数组
什么是函数指针数组?函数指针数组是一个数组,数组的每个元素都是函数指针。如何定义函数指针的数组?
思考2:
下面哪一个是定义函数指针数组的?
int(*p1[3])();
int* p2[3]();
int (*)()p3[3];
解释:
答案是p1。parr1 先和 [] 结合,说明parr1是数组,数组的内容是什么呢? 是 i nt (*)() 类型的函数指针。