深入了解指针(3)【数组指针变量】【函数指针变量】【typedef关键字】

一.数组指针变量

1.什么是数组指针变量?

说到数组指针,那必然要说一下指针数组,指针数组是什么呢?指针数组是一种数组,只不过这种数组存放的是地址(指针)。那把这两个词反过来,数组指针是什么?它是指针变量,还是数组?答案是:指针变量。这个指针有些特殊,它存放的是数组的地址,它是能够指向数组的指针变量。思考一下 int* p1[10] 和 int(*p2)[10]分别代表的是什么。int* p1[10]这里的p1是指针数组,有十个元素,每一个元素都是指针。p2是指针变量,指向的是一个大小为十个整型的数组。

#include <stdio.h>
void print(int(*p)[5], int r, int c)//所以我们这里用了一个数组指针来接收一维数组的地址
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < c; j++)
		{
			printf("%d ", *(*(p + i) + j));
		}
		printf("\n");
	}
}
int main()
{
	int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
	print(arr, 3, 5);//这里传参时传过去的是数组,实际上是一维数组的地址
	return 0;
}

这里需要注意,这里的()非常重要,因为[]的优先级是高于*号的,所以要加上()来保证p先和*结合。

2.数组指针变量怎么初始化?

int main()
{
	int arr[10] = { 0 };
	int(*p2)[10] = &arr;
	return 0;
}

很简单,既然想要指针,直接用取地址符号&取出数组arr的地在赋值给p2就行了。那么这里的p2的类型是什么类型呢?我们知道如果是指针数组(int* p1[10])的话,它的类型就是int*。那么数组指针的类型就是int(*)[10],同样的,&arr的类型也是int(*)[10]。

3.二维数组传参的本质

我们可以先想一下关于二维数组的基本概念,我先给一个数组arr[10][10]关于二维数组名,其实代表的就是首元素的地址,但是这里的首元素代表的可不是arr[0][0],而是arr[0],代表的是第一行的地址。第一行的地址就是一维数组的地址,类型就是数组指针类型。给大家写一个代码。

这是最终的输出结果

总的来说,二维数组传参的本质上也是传递了指针,是第一行的这个一维数组的指针。跟一维数组差不多,在传参的时候,形参的部分可以写成数组,也可以写成指针形式。

二.函数指针变量

1.函数指针变量的创建

前面我们已经说过了,数组指针指向的是数组的地址,那么函数指针自然就是指向函数的指针。其实,如果已经理解了数组指针,这个就比较好理解了。

#include<stdio.h>
void Add(int x, int y)
{
	return x+y;
}
int main()
{
	int (*p)(int, int) = &Add;
	return 0;
}

关于int (*p)(int, int)这个东西大家可以单独的先看int (*)(int, int),这个东西就是函数指针的类型

2.函数指针变量的使用

使用的方法也是很简单,还是上面的加法函数。咱们调用的话应该就是直接写函数名,后面跟上参数。既然学习了函数指针,这里我们就可以稍微改变一下。

#include<stdio.h>
void Add(int x, int y)
{
	return x+y;
}
int main()
{
	int (*p)(int, int) = &Add;
	int ret = (*p)(2, 3);//函数指针调用,其实这里不用解引用
	printf("%d \n", ret);

	int a = p(3, 4);//因为我们在用函数名调用函数的时候,函数名本身就是地址,所以这里不用解引用就可以直接用
	printf("%d ", a);
	return 0;
}

这个就是函数指针的简单运用了。

三.typedef关键字

关于typedef关键字,它的作用是类型重定义。简单的说,我有一个类型叫做unsigned int,但是我觉得这种类型的名字太长的,我如果需要频繁使用这种类型,那么太长的话就很难受了,这时我们可以用typedef关键字,重新给它取一个名字。比如

typedef unsigned int u_int;

以后我们如果再去使用它的时候,就可以直接使用u_int。比如我定义a为unsigned int类型,这时我们就可以直接写成u_int  a;这跟unsigned int  a是等价的。但是对于数组指针变量和函数指针变量要特殊对待一下。

typedef void(*p)(int);//函数指针变量:这里的p就是void(*)(int)
typedef int(*p1)[10];//数组指针变量:这里的p1就是int(*)[5]

可千万不能写成了typedef   void(*)(int)  p,这种写法是绝对错误的。

define和typedef对比

先思考一下这里的p1,p2,p3,p4分别对应的是什么类型。

#define PTR_T int*
typedef int* ptr_t;
int main()
{
	ptr_t p1, p2;
	PTR_T p3, p4;
	return 0;
}

正确答案是p1,p2,p3这三个是指针变量,p4是整型变量。

具体是为什么呢?

我们通过define定义的PTR_T是直接把int*给替换过来了。大家可以这样理解。

感谢观看,请多多指正。

  • 32
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值