目录
一、字符指针变量
1、字符指针变量的用法
2、拓展用法
为了验证这个答案,我们运行代码来找出答案
通过运行代码我们就知道了,是把字符串首字符的地址放在了p中。
3、打印“hello world”
方法一:
方法二:
二、数组指针变量
1、数组指针变量是什么呢?
这就需要我们回顾一下之前的知识了,我们知道:
在上一部分中,我们知道指针数组是一种数组,数组中存放的是指针。
整形指针变量,是存放整形变量的地址,能够指向整形数据的指针。
浮点形指针变量,是存放浮点形变量的地址,能够指向浮点形数据的指针。
所以,数组指针变量,就是存放数组的地址,能够指向数组的指针变量。
这是数组指针的形式:
在这里,问题又来了,数组指针的类型是什么?就以上面的代码为例,它的类型是:
2、数组指针变量的初始化
三、二维数组传参的本质(二维数组的使用)
我们来看下面这个代码:
#include<stdio.h>
void test(int arr[3][5], int r, int l)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < l; j++)
{
printf("%d ", arr[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;
}
运行结果如下:
我们知道,数组名是数组首元素的地址,二维数组的数组名表示的就是第一行的地址,是一维数组的地址。所以,上面代码中第一行一维数组的类型是 int [5],所以第一行的地址的类型就是数组指针类型 int (*)[5]。所以,二维数组传参本质上也是传递了地址,传递的是第一行的一维数组的地址,所以形参也可以写成指针形式,代码如下:
#include<stdio.h>
void test(int (*p)[5], int r, int l)
{
int i = 0;
for (i = 0; i < r; i++)
{
int j = 0;
for (j = 0; j < l; 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、函数指针变量的创建
什么是函数指针变量呢?
我们之前已经学习过了数组指针和字符指针,想想它们是什么意思。
通过类比,我们就可以知道,函数指针就是指向函数,存放的是函数的地址。
我们用代码来解释:
我们可以看到,他们的地址是一样的。所以函数是有地址的,函数名就是函数的地址,也可以通过&函数名获得函数的地址。
2、函数指针变量的写法
3、函数指针变量的使用
4、小练习
我们已经学完了函数指针了,就让我们来做两个小练习吧!
让我们一起理解一下下面两个代码:
(1)
(2)
这两个看起来很复杂的代码该怎么理解呢?
第一个:它是函数调用
是先将0强制类型转换成(void (*)()类型的函数指针,然后调用0地址出放的这个函数。
第二个:它是一次函数声明
5、typedef 关键字
typedef 是用来类型重命名的,可以将复杂的类型简单化。
我们举例说明:
假如说,我们觉得 unsigned int 写起来很麻烦,我们该如何让它简化呢?这时候 typedef关键字就派上用场了,我们可以把 unsigned int 改为 uint,我们看下面的代码。
(1)对 unsigned int 类型重命名
(2)typedef 对指针类型重命名
(3)对复杂指针类型重命名
五、函数指针数组
1、基本介绍
如果我们想把函数的地址放在数组中,这个数组就叫做函数指针数组。
还记得我们之前实现的简单计算器吗?今天,我们就分析一下计算器代码中的指针部分。
我们要把上述函数都存起来,就可以像下面代码一样:
我们应该发现了,这四个函数的类型都是一样的,所以,如果我们想把他们放在一个数组中,就能实现函数指针数组了。
所以:如果我们想把多个相同类型的函数指针存放在一个数组中,这个数组就是函数指针数组。
下面就是函数指针数组:
下面是这个函数指针数组的类型
2、应用
我们之前实现的能够进行两个数计算的简单计算器就是使用函数指针数组的应用:
我们继续把之前的代码放回来:这个时候也更能理解这个代码了。
#include<stdio.h>
void menu()
{
printf("**********************\n");
printf("*** 1.Add 2.Sub ***\n");
printf("*** 3.Mul 4.Div ***\n");
printf("***** 0.exit *****\n");
printf("**********************\n");
}
int Add(int x, int y)
{
return x + y;
}
int Sub(int x, int y)
{
return x - y;
}
int Mul(int x, int y)
{
return x * y;
}
int Div(int x, int y)
{
return x / y;
}
int main()
{
int x = 0;
int y = 0;
int input = 1;
int ret = 0;
int (*pfArr[5])(int, int) = { NULL,Add,Sub,Mul,Div };
do
{
menu();
printf("请选择:");
scanf("%d", &input);
if (input >= 1 && input <= 4)
{
printf("请输入数字:");
scanf("%d %d", &x, &y);
int ret = pfArr[input](x, y);
printf("ret = %d\n", ret);
}
else if (input == 0)
{
printf("退出程序\n");
break;
}
else
{
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}
咱们指针第三部分到这里就结束了,有没有感到难度越来越高呢?我也这样认为,是蛮难的,但是我们要啃硬骨头,一定要把指针狠狠的拿下!