C/C++中关于int *p[n]、int(*p)[n]、int*p()和int(*p)()巨详细实例解释

本文深入解析了C/C++中的四种指针表达式:int*p[n](指针数组)、int(*p)[n](指向数组的指针)、int*p()(指针函数)和int(*p)()(函数指针)。通过实例代码展示了它们的用途和区别,帮助读者理解这些复杂的语法结构。
摘要由CSDN通过智能技术生成

关于int *p[n]、int(p)[n]、intp()和int(*p)()详细实例解释

指针是C/C++语言中最精彩部分,话不多说,下边对这四种形式进行寻根问底,进行剖析。

  1. int *p[n];
  2. int(*p)[n];
  3. int*p();
  4. int(*p)();
    看似好像乱的不像话,但是它理解起来并没有那么难懂,注意注意,下边是正文部分。

提示:要区分这四个的区别,可以从运算符优先级的层面来看差异,C语言中,[]和()的优先级比 * 的优先级高。


一、int *p[n]

根据优先级,int *p[n]等价于int *(p[n]),那p[n]顾名思义就只是一个数组而已,前边加一个 * ,就变成了数组指针了,即这个一维数组里边n个变量都是指针变量。

数组指针抽象图

这样一来的便捷之处在于可以一次定义很多指针,如果需要很多同类型的指针的话,这么做很省事,事实上确实如此:

测试代码001

#include<stdio.h>
int main()
{
	int* p[3];		//定义一个指针数组
	int* q1, * q2, * q3;		//定义三个指针变量
	int a = 10, b = 20, c = 30;		//定义整型变量,便于后边检验

	p[0] = &a;
	p[1] = &b;
	p[2] = &c;

	q1 = &a;
	q2 = &b;
	q3 = &c;
	printf("%d\t%d\t%d\n", *p[0], *p[1], *p[2]);
	printf("%d\t%d\t%d\n", *q1, *q2, *q3);
	return 0;
}

这里是输出结果:

可以看出:

  • int *p[n]是定义了一个指针数组,数组中的每一个元素都是一个指针变量
  • 每一个数组指针变量都和普通变量没有区别
  • 要注意使用数组指针变量时,下标的范围,不要越界

二、int(*p)[n]

到这里,*p不能简单地只看做是 *p=a(假定a是一个整型变量),应该比较着来看:
在这里插入图片描述
int a[3][4];
int (*p)[4];
第二个式子表示定义了一个指针变量p,p所指的对象是包含4个int型元素的一维数组,可能有点绕,我们来看一下代码:

测试代码002

#include<stdio.h>
int main()
{
	int a[3][4]={ 1,2,3,4,5,6,7,8,9,10,11,12 };
	int(*p)[4];		

	p = a;		//p是一个二维指针,此时指向a[0]

	p[0][0] = a[0][0];		//p相当于a,但p是一个变量
	*(*(p + 1) + 1) = a[1][1];		

	printf("%d %d\n", p[0][0], *(*(p + 1) + 1));
	return 0;
}

运行结果是这样的:
在这里插入图片描述
是不是有点明白定义的这个p是什么东西了?是的,你的直觉正确。

  • int(*p)[4]定义出来的指针p,相当于二维数组a[3][4]的a
  • p指向二维数组a的行a[0]

如果还是不太清楚,我们继续看一段实例代码:

测试代码003

#include<stdio.h>
int main()
{
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	int(*p)[4];		//定义p为指针变量,指向含有4个int型元素的一维数组
	int i, j;
	p = a;		//p指向二维数组a的行a[0]
	for (i = 0; i < 3; i++)
		for (j = 0; j < 4; j++)
			printf("%d ", *(*(p + i) + j));
	printf("\n");
	return 0;
}

这下子是不是就释然了?
原来是这样
别急,我们继续强化一下(方便认识起见,自行把a脑补成p):

表示形式含义地址
a二维数组名1000
a[],*(a+0),*a第0行的首地址,即[0][0]的首地址1000
a+2,&a[2]第二行的首地址1016
a[2],*(a+1)第二行的首地址,a[2][0]的地址1016
a[2]+2,* (a+2)+2,&a[2][2]第二行第二列的元素a[2][2]的地址1024
* (a[2]+2),* (*(a+2)+2),a[2][2]第二行第二列的元素a[2][2]值1024

三、int*p()

当出现(),那这种形式就是一种函数,那现在的问题是int*p()函数和int(*p)()有什么区别,如果有一个fun函数,其定义为:int fun(int a,int b);
那我们很好理解,这就是一个普通的函数,返回值为int型,但是如果我们把它转换成int *fun(int a,int b),同理,这也是一个函数,只不过返回值为指针类型(加 * 的fun函数为指针函数,其返回的指针指向一个整型变量)

老样子,看个代码就明白了。

测试代码003

#include<stdio.h>
int main()
{
	int a = 4, b = 5;
	int *pluse;		//指针Pluse用来接收指针函数返回的值
	int* sun(int* p, int* q);		//声明一个指针函数
	pluse = sun(&a, &b);
	printf("%d\n", *pluse);
}

int* sun(int* p, int* q)
{
	int s;
	s = *p + *q;
	return &s;		//返回s的地址
}

运行结果当然也就很明了了,屏幕上蹦出一个9,就结束了,当然,对于这个int*p()讲到这里,最重要的是要记得,这个是
在这里插入图片描述
因为函数返回的类型是指针,所以就叫指针函数咯,这样记还是比较简单的。

四、int(*p)()

对于函数的概念这里就不在多说了,值得一提的是,每个函数都要占用一段连续的存储空间,而函数名就是这段内存区域的首地址,讲到这里,我们其实就可以想,如果把这个首地址赋给一个指针变量,那就可以调用指针来实现函数的功能了,没错,事实就是这样,而这样的函数叫做函数指针(把函数当成一个指针来看),其形式就是int(*p)(),
赶紧上车,看代码去:

在这里插入图片描述

#include<stdio.h>
int max(int a, int b)		//取a,b的最大值
{
	if (a > b) return a;
	else return b;
}
int main()
{
	int a = 1, b = 2;
	int z;
	int (*p)(int, int);		//定义一个函数指针
	p = max;		//这个函数指针指向定义的函数
	z = (*p)(a, b);
	printf("%d\n", z);
	return 0;
}

函数指针是比较容易理解的,但在这里要提两点注意的:

  • 函数指针变量不能进行算术运算,这是与数组指针变量不同的,数组指针变量加减一个整数可以使指针移动,但是这里你要是想让函数指针变量移动的话,估计,,,只能说你很有想法
  • 函数调用时“(*指针变量名)”两边的括号一定一定不能少,其中的“ * ”不要理解为指针运算,此时的它只是一种指示符号
  • 我强调一下,这个是:
    在这里插入图片描述
    我们再来小小比较一下这两个函数:
形式名称
int*p();指针函数
int(*p)()函数指针

总结

以上就是本次对C/C++中关于int *p[n]、int(p)[n]、intp()和int(*p)()详细介绍,当然,以上的代码都是用C语言敲写,如果看着难受,也可以用C++咯,那就这样,下次见。

在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值