【C语言】指针深入理解

上一篇,讲到了指针的初识及理解,感兴趣的编友点这里~

一、指针变量

1、数组指针变量

在理解数组指针变量之前,我们可以仿照一下整型指针变量
整型指针变量存放的是整型变量地址,指向的是整型变量
例如:

int n = 10;
int* pn = &n;

数组指针变量它存放的是数组地址,指向的是数组
例如:

int arr[5];
int (*p)[5] = &arr;

需要注意的是&arr是数组的地址,而arr是数组中第一个元素的地址,也就是首地址,两者不一样。

突然跳出这样的两行代码,可能说不清楚,我们仍旧用实例说明:

#include <stdio.h>

int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int (*p)[5] = &arr;
	int i;
	for (i = 0;i < 5;i++)
	{
		printf("%d ", (*p)[i]);
	}

	return 0;
}

运行效果:
在这里插入图片描述
大家可能对(*p)[i]感到困惑?这是什么意思?
不必紧张,大家都知道p = &arr, 而*p=*(&arr)即arr,所以(*p)[i]就是arr[ i ]

1.1 数组指针变量的用途

数组指针变量一般在二维数组传参时使用
实例:

#include <stdio.h>

void print(int(*p)[3], int n, int m)
{
	int i, j;
	for (i = 0;i < n; i++)
	{
		for (j = 0;j < m;j++)
		{
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
}

int main()
{
	int arr[2][3] = { 1,2,3, 4,5,6 };
	print(arr, 2, 3);

	return 0;
}

运行结果:
在这里插入图片描述
当然,print函数定义时也可以写成int arr[2][3],看过我之前写扫雷代码实现博客的朋友都知道,我在扫雷实现的时候就这么用的。
值得注意的是,如果你也用实例中使用的方法进行传参,(*p)[ ],这个方括号中必须是二维数组的列数。

2、函数指针变量

每个变量都有自己的地址,函数也是有自己的地址的
函数指针变量存放的就是函数的地址。
那么函数指针变量是如何定义的呢?

int (*pf) (int,int);//这是标准形式 ,其中int (*) (int, int);是函数指针变量pf的类型

应用:

#include <stdio.h>

int mul(int a, int b)
{
	return a * b;
}

int main()
{
	int (*pf)(int, int) = mul;
	printf("%d", pf(2, 3));

	return 0;
}

运行结果:
在这里插入图片描述

int (*pf) (int,int) 后面的这个括号中是需要调用函数中的变量类型。

二、指针数组

1、指针数组定义及使用

指针数组,就是存放指针的数组

#include <stdio.h>

int main()
{
	int a = 1;
	int b = 2;
	int c = 10;
	int* arr[3] = { &a,&b,&c };
	int i;
	for (i = 0;i < 3;i++)
	{
		printf("%d ", *(arr[i]));
	}

	return 0;
}

运行结果:
在这里插入图片描述

2、指针数组模拟二维数组

#include <stdio.h>

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 6,7,8,9,10 };
	int arr3[] = { 11,12,13,14,15 };

	int* pf[] = { arr1,arr2,arr3 };

	int i;
	for (i = 0;i < 3;i++)
	{
		for (int j = 0;j < 5;j++)
		{
			printf("%d ", pf[i][j]);
		}
		printf("\n");
	}

	return 0;
}

运行结果:
在这里插入图片描述
从这里可以看出指针数组数组指针有很多相似之处

三、函数指针数组

1、函数指针数组

函数指针数组数组,存放 的是函数指针。

int (*pf[5])(int, int)={NULL};//大括号里面存放函数地址

2、函数指针数组的用途—转移表

实现简单 加、减、乘、除 的转移表

#include <stdio.h>

int sub(int a, int b)
{
	return a - b;
}

int add(int a, int b)
{
	return a + b;
}


int mul(int a, int b)
{
	return a * b;
}

int div(int a, int b)
{
	if (b == 0) return -1;
	return a / b;
}

int main()
{
	int (*pf[5])(int, int) = { NULL,add,sub,mul,div };
	int n;
	printf("请输入你想要计算的次数-》\n");
	scanf("%d", &n);
	int m;
	while (n)
	{
		printf("1.add 2.sub 3.mul 4.div\n");
		printf("请选择-》\n");
		scanf("%d", &m);

		if (m < 1 || m>4) printf("选择错误,请重新选择-》\n");
		else
		{
			int x, y;
			printf("请输入两个操作数-》\n");
			scanf("%d %d", &x, &y);
			printf("%d\n", pf[m](x, y));
			n--;
		}
	}

	return 0;
}

运行结果:
在这里插入图片描述
好了,以上就是本期博客的全部内容,博主在此感谢大家的观看

有点懵的同志可以重复观看,便于消化

(记得支持博主哦)那我们下期再见,告辞~
ヾ(≧▽≦*)o

(添加这些文字就到3000字了,你们不用管~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

矢 望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值