0
点赞
收藏
分享

微信扫一扫

【C语言】 指针的进阶 浅谈一下吧 大家来浅学一下吧

您好 2022-03-12 阅读 81
c语言

 

目录

数组指针

 存放数组指针的数组

二维数组的传参

函数指针

函数指针数组


指针,想必我们早已熟悉,其又可以称为指针变量,是存放地址的变量.

int a = 0;
int* pa = &a;//一级指针
int** ppa = &pa;//二级指针

对于" int* pa = &a; "来讲,*告诉我们pa是个指针(其存放 int类型变量a 的地址),而 int 告诉我们这个地址所存放的对象是int类型;同理,对于代码" int** ppa = &pa; "来讲,我们拿出一颗*来,这颗*告诉我们,ppa是指针,而剩下的 int* 告诉我们其地址所存放的类型为 int*,因为ppa指向的也为指针,所以我们称ppa为二级指针。

指针的范围只有这么小吗?当然不是,前面只是复习一下,是饭前甜点,接下来我将为大家介绍更深入一些的内容。

数组指针

指向数组的指针,是指针

int arr[10] = {0,1,2,3,4,5,6,7,8,9};

通常我们用函数调用数组传过去的是arr,即首元素的地址,而我们创建函数是通常用,int arr[10]或int* arr来接受实参。 对,我们传过去的是首元素的地址而不是整个数组的地址,那么如果我们传过去整个数组的地址又该如何接收呢?怎样声明呢? 我对于C语言的体会就是,要学会一一对应,存放普通变量地址的指针声明就是  地址所存放的变量类型+ * + 名称,我们照葫芦画瓢,存放数组地址当然要用数组指针来存放了,按照理解,应当这样声明: 数组类型 + * +名称

所以数组arr的指针变量初步声明为: int* parr [10] ,好,这里出现了一点点小问题,由于[ ]的优先级比*高,所以parr会优先和[10]结合变成一个指针数组,就是一个数组了,不是指针了,所以我们要把parr和*绑定在一起,告诉大家我是指针,所以更改后变为:int (* parr) [10]

 存放数组指针的数组

int (*parr[5]) [10];

这里的parr先和[5]结合说明这是个数组,里面有5个元素,那么元素的类型呢?这里教给大家一个小技巧,把parr[5]去掉就是元素的类型啦,int (*) [10],我们可以清晰地看到元素类型为数组指针,可以存放五个数组的地址。

注:是整个数组的地址! &arr

二维数组的传参

大家都知道数组名代表首元素的地址,而二维数组的首元素是第一行的地址,而第一行又可以看成是一个一维数组,因此我们可以用数组指针来接收。

#include<stdio.h>
void print(int(*p)[5],int x,int y)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < x; i++)
	{
		for (j = 0; j < y; j++)
		{
			printf("%d ", *(*(p + i) + j));
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {0,1,2,3,4},{5,6,7,8,9},{10,11,12,13,14} };
	print(arr,3,5);
	return 0;
}

p是指向第一行的指针,+i指向第i行。

以第一行为例,第一行为   * ( *( p + 0 ) + j )  ,*(p+0)得到第一行,相当于得到第一行的数组名,而数组名又是首元素地址,再+j,得到这一行的第几个元素的地址,在对其解引用,得到该元素。

函数指针

我们知道了数组指针的声明方法,函数指针我们应该也手到擒来了吧!类型+ * +名

但是对于函数来说,多了一个返回类型,我们要给它加上!

int Add(int x, int y)
{
	return (x + y);
}

因此,存放函数地址的指针就是: int (* pAdd)  (int , int);

这里不禁会有小伙伴们提出疑问,函数是否和数组一样名字代表地址呢?答案是肯定的!

但是这里和数组不一样的是&函数名和函数名等价,都是函数的地址,而&数组名和数组名是不一样的 ,&数组名拿到的是整个数组的地址,而数组名代表数组首元素的地址

 

 因此,我们可以通过函数指针来调用函数。

此时,细心的同学可能会发现,Add(2,3);和(*pAdd)(2,3)的结果都是5,而Add代表函数地址,而pAdd存放的也是函数地址,那么可以理解为Add和pAdd是一回事,那么可不可以不带*直接调用函数呢?

 结果依然是肯定的!

所以这里的*是个摆设,无论有还是没有,有几个*都对结果没有影响

 

函数指针数组

int (*pa [5])(int,int);

为什么这么创建,这里就不用多说了吧!

那么我们通过函数指针数组来实现一个简易计算器的实现吧。

#include<stdio.h>

void menu()
{
	printf("      1.Add\n");
	printf("      2.Sub\n");
	printf("      3.Mul\n");
	printf("      4.Div\n");
	printf("      0.Exit\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 result = 0;
	int input = 0;
	int x = 0;
	int y = 0;
	int (*p[5])(int, int) = { 0,Add,Sub,Mul,Div };
	
	do
	{
		menu();
		printf("请选择->");
		scanf("%d", &input);
		if (input == 0)
		{
			printf("您已退出\n");
			break;
		}
		else if (input >= 1 && input <= 4)
		{
			printf("请输入两个操作数:");
			scanf("%d %d", &x, &y);
			result = p[input](x, y);
			printf("%d\n", result);
		}
		else
		{
			printf("输入错误 请重新输入\n");
		}

	} while (input);
	
	return 0;
}

数组添加个0是为了方便调用加减乘除,因为我们在菜单中定义的是:1为加法,2为减法,3为乘法,4为除法

通过数组找到对应的地址,来进行调用,进行计算。

举报

相关推荐

0 条评论