理解数组指针、函数指针、函数指针数组。

一、数组指针:
1、数组指针是数组还是指针呢?
答案是指针,是一个能够指向数组的指针。
2、例如:int(p)[10]
p先和
结合,说明p是一个指针变量,指向大小为10 的整形数组,所以p是一个指针,指向一个数组,叫数组指针。
注意:[ ]的优先级高于号,所以必须加上()保证p先和结合。
3、&数组名vs数组名
对于这个数组:int arr[10]; arr和&arr分别指的是什么?
我们知道arr指的是数组名,表示数组首元素的地址。那么&arr呢?
我们看一段代码:

#include<stdio.h>
#include<stdlib.h>
int main(){
 int arr[10] = { 0 };
 printf("arr    = %p\n", arr);
 printf("&arr   = %p\n", &arr); 
 printf("arr+1  = %p\n", arr+1);
 printf("&arr+1 = %p\n", &arr+1);system("pause"); 
 return 0;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190824124937124.png)
根据以上代码我们发现:arr和&arr值虽然一样,但是意义不一样。&arr表示的是数组的地址,不是数组首元素的地址,数组地址+1,跳过整个数组大小,所以&arr+1相对于arr+1差值是40.


二、函数指针:
		如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址。既然是地址我们就可以定义一个指针变量来存放,这个指针变量就叫作函数指针变量,简称函数指针。
		例如  void (*p)(int ,int );
		这个语句定义了一个指向函数的指针变量p,p与*结合,p是一个指针,前面的void表示这个指针变量指向返回值类型为void型的函数。后面括号中的两个int表示这个指针变量可以指向有两个参数都是int型的函数。p的类型为int(*)(int,int).
	函数指针的定义方式为:(函数值返回类型)(*指针变量)(函数参数列表)

三、函数指针数组
		把函数的地址存到一个数组中,那这个数组就叫函数指针数组,如何定义?
		int (*p[10])()
		p先和[ ]结合,说明p是数组,数组内容为 int(*)()类型的函数指针。
		函数指针数组的用途:转移表
例子:计算器

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
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 xy;
}
int Div(int x, int y)
{
return x / y;
}void menu()
{
printf("
***************************\n");
printf("
1. add 2. sub \n");
printf("
3. mul 4. div \n");
printf("
0.exit \n");
printf("
****************************\n");
}void calc(int(*pfun)(int, int))
{
int x = 0;
int y = 0;
int ret = 0;
printf(“请输入要进行计算的值:”);
scanf("%d%d", &x, &y);
ret = pfun(x, y);
printf(“ret = %d\n”, ret);
}int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
int(*pfun[5])(int, int) = { 0, Add, Sub, Mul, Div };
//创建函数指针的数组,数组中保存的都是返回值为int的函数的指针。
do{
menu();
printf(“请选择:”);
scanf("%d", &input);
switch (input)
{
case 1:
calc(pfun[1]);
//通过数组调用函数的指针进而调用函数,可大量节省代码篇幅
break;
case 2:
calc(pfun[2]);
break;
case 3:
calc(pfun[3]);
break;
case 4:
calc(pfun[4]);
break;
case 0:
printf(“退出\n”);
break;
default:
printf(“输入错误,请重新输入\n”);
break;}
} while (input);
system(“pause”);
return 0;
}


![在这里插入图片描述](https://img-blog.csdnimg.cn/20190825164645295.png)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值