指针和数组的深度理解

1.指针数组和数组指针
指针数组是数组,是一个存放指针的数组。而数组指针是一个指针,是一个有能力指向数组的。

int *arr1[10];
int (*arr2)[10]

解释:1.arr1先和[]结合,说明它是一个数组,而每一个类型为 int *的指针。(一个数组,类型为int *的指针,为指针数组)
          2.arr2先和*结合,说明它是一个指针,然后指向一个大小为10的数组。(一个指针,指向一个数组为数组指针)

看代码:

int arr[5];//五个元素的数组,int类型
int *p[5];//五个元素的数组,int *类型(指针)
int (*q)[5];//q和*结合成指针,指向一个五个元素的数组
int (*a[10])[5];//(*a[10]为数组指针,指向一个五个元素的数组,即为数组指针的数组)


2.函数指针
首先看代码:
#include<stdio.h>
#include<windows.h>
void test()
{
	printf("hehe\n");
}
int main()
{
	printf("%p\n", test);
	printf("%p\n", &test);
	system("pause");
	return 0;
}

结果:
输出的两个地址均为test函数的地址,这就可以说明打印函数的地址时,直接打印函数名和&+函数名都可以
打印出函数。

我们可以用代码1带存放函数的地址
1.void (*pfun)()
pfun先和*结合成指针,然后指向一个无参数的函数,返回值类型为void。



3.函数指针数组和函数指针数组的指针


函数指针数组就是存放函数指针的数组;
看代码:
int (*parr[10])();

parr先和[]结合是一个数组,它的类型为int (*)()的函数指针。
函数指针函数的指针是一个 指针,指向一个 数组,数组的元素都是 函数指针
看代码:
void(*(*ppfunarr)[5])()

上代码中:*ppfunarr为指针,指向*(ppfunarr)[5]的数组,数组的每一个元素为 void(*)()的函数指针。


函数指针数组的用途:转移表
举例子(简单计算器)


看代码:
#include<stdio.h>
#include<windows.h>
int jia(int x,int y)
{
	return x + y;
}
int jian(int x,int y)
{
	return x - y;
}
int cheng(int x,int y)
{
	return x * y;
}
int chu(int x,int y)
{
	return x / y;
}
int main()
{
	int x, y = 0;
	int input = 1;
	int ret ;
	while (1)
	{
		printf("------------------------\n");
		printf("++1.jia         2.jian++\n");
		printf("++3.cheng       4.chu ++\n");
		printf("------   0.exit     ----\n");
		printf("------------------------\n");
		printf("请您选择:\n");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			printf("请输入:");
			scanf_s("%d %d", &x, &y);
			ret = jia(x, y);
			printf("%d\n", ret);
			break;
		case 2:
			printf("请输入:");
			scanf_s("%d %d", &x, &y);
			ret = jian(x, y);
			printf("%d\n", ret);
			break;
		case 3:
			printf("请输入:");
			scanf_s("%d %d", &x, &y);
			ret = cheng(x, y);
			printf("%d\n", ret);
			break;
		case 4:
			printf("请输入:");
			scanf_s("%d %d", &x, &y);
			ret = chu(x, y);
			printf("%d\n", ret);
			break;
		case 0:
			printf("已结束!\n");
			ret = 0;
			break;
		default:
			printf("输入错误。");
			break;
		}
		if (ret == 0)
			break;
	}
	system("pause");
	return 0;
}

结果:
这代码虽然实现功能,但是在switch语句中大量的话再重复,所以我们用转移表对其优化。

用函数指针数组实现:


#include<stdio.h>
#include<windows.h>
int jia(int x,int y)
{
	return x + y;
}
int jian(int x,int y)
{
	return x - y;
}
int cheng(int x,int y)
{
	return x * y;
}
int chu(int x,int y)
{
	return x / y;
}
int main()
{
	int x, y = 0;
	int input = 1;
	int ret ;
	int(*p[5])(int x,int y) = { 0, jia, jian, cheng, chu };//转移表
	while (1)
	{
		printf("------------------------\n");
		printf("++1.jia         2.jian++\n");
		printf("++3.cheng       4.chu ++\n");
		printf("------   0.exit     ----\n");
		printf("------------------------\n");
		printf("请您选择:\n");
		scanf_s("%d", &input);
		if (input >= 1 && input <= 4)
		{
			printf("请输入:");
			scanf_s("%d %d", &x, &y);
			ret = (*p[input])(x, y);
		}
		else if (input == 0)
		{
			printf("已结束!\n");
			break;
		}
		else  
		{
			printf("输入错误!");
		}
		
		printf("%d\n", ret);
	}
	system("pause");
	return 0;
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值