0
点赞
收藏
分享

微信扫一扫

指针-函数指针

云上笔记 2022-02-15 阅读 91

目录

什么是函数指针?

函数指针标准

函数名的意义

函数中()的意义

一个函数指针

函数指针的赋值及使用

两个有趣的函数指针

No.1

No.2

No.2的简化——typedef


什么是函数指针?

我们来类比一下

	int* pa;   //整型指针
	char* pb;  //字符指针
	int(*pc)[3];  //数组指针,指向存放3个int的数组
	char(*pd)[3]; //数组指针,指向存放3个char的数组

顾名思义,函数指针是一个指向函数的指针

函数指针标准

函数名的意义

我们在学习数组时知道数组名表示数组的首元素地址,&数组名表示整个数组的地址,因为数组在空间中占一段连续的空间,函数同样如此。函数名表示函数的地址,但和数组名有一点区别:&函数名和函数名等价。

#include<stdio.h>
void aa(void) {    //定义aa函数
	printf("123");
}
int main(void) {

	void(*p)(void);  //定义一个函数指针,先不用管这个
	p = aa;
	printf("%p\n", p);    
	printf("%p\n", *p);
	printf("%p\n", aa);
	printf("%p\n", &aa);    //四个结果的完全相同

}

函数中()的意义

我们一般调用函数的时候,是一个函数名加上一个(),()里变看情况放着相应的参数。还记得数组的【】吗?表示对左侧的指针进行运算后解引用。()表示对于左侧的地址将参数传入后进行访问(这里并不能用*对其访问,()在设计时就限定了函数)。

一个函数指针

int Add(int a,int b){}  //一个函数定义

int (*p)(int, int);    //一个函数指针变量定义,p先于*结合知道是一个指针
					//再与()结合,表示指向函数。
					//在与int,int结合表示所指向的函数有两个参数
					//最后与int结合,表示所指向函数返回一个int

//关于为什么要加括号,因为p会先于右边的()结合而导致是一个返回值为int*类型的函数
//优先级*<[]<()

函数指针的赋值及使用

在数组指针赋值时,我们是将数组的地址赋给它,可以认为是一个比一级指针高一级的一个类型(&数组名)。函数指针同样如此,我们将函数的地址赋给函数指针变量,可以认为是一个比函数地址高一级的一个类型,所以我们在使用时需要进行访问一次,效果才等同于函数名。

#include<stdio.h>
int Add(int a, int b) {
	printf("%d\n", a + b);
	
	return a + b;
}

int main(void) {
	int (*p)(int, int);  
	p = Add;   //对其进行赋值

	Add(2, 3);
	(*p)(2, 3);		//p=Add,但是转化类型后要高一级,所以这里*p 
	printf("%d", (*p)(2, 3)); //程序在这步会打印两次5
	
}

两个有趣的函数指针

No.1

	(*(void(*)())0)()

    //先看 void(*)() 这是一个函数指针类型
    //对0进行强制类型转换 (void(*)())0
    //你可能会疑惑,0也能强制类型转换吗?之前说过数据在内存中,就是空间+方式(规则)
    //也就是类型,所以类型转换在计算机中除非特殊规定,否则就是“强制”。
    //这个时候就相当于定义了一个指向0的数组指针变量   (void(*)())0 这里用p表示一下
    //将其替换,(*p)(),调用这个函数。

也可以写成这样

	void(*p)();    
	p = 0;
	(*p)();  //将p看成 (void(*)())0 即可

No.2

void(*signal(int, void(*)(int)))(int);

    //首先我们看到signal,()优先级大于*,这是一个函数
    //参数为整型和函数指针类型,没有变量可知是一个函数声明
    //返回值呢?我们来看一下正常点的函数

int Add(int , int );
int            //将函数名和()去掉剩下的就是返回值的类型

    //将signal(int,void(*)(int))去掉
    //剩下void(*)(int),就是返回值的类型:函数指针类型

描述:

//signal是一个函数说明
//signal函数的参数有两个,第一个是int。第二个是函数指针,该函数指针指向的函数的参数是int,返回类型是void
//signal函数的返回类型是函数指针,该函数指针指向的函数的参数是int,返回类型是void

void(*)(int)    signal   (int, void(*)(int));
//可以这么理解,但不能这么写

No.2的简化——typedef

我们知道typedef可以对名字复杂的类型增加名字,这里同样可以对函数指针类型名字使用

	typedef void(*)(int) fun_p; //正常来说是这样写的,但函数指针有点特殊
	typedef void(*fun_p)(int);   //应该这样写
	fun_p signal(int, fun_p);   //函数声明就可以进行简化
举报

相关推荐

指针进阶· 函数指针

函数指针和函数指针数组

0 条评论