指针进阶---函数指针

函数指针

首先看一段代码找到函数的地址

#define _CRT_SECURE_NO_WARNINGS 1
#include

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

int main() {
	
	int a = 2;
	int b = 3;
	printf("%p\n", Add); //005811C2
	printf("%p\n", &Add); //005811C2
	getchar();
	return 0;
}

程序运行后可得知Add和&Add都代表函数的地址

	printf("%p\n", Add); //005811C2
	printf("%p\n", &Add); //005811C2

存放函数的指针

int (*p)(int, int) = &Add;

p因为()的原因,首先和*结合,成为指针类型,p指向参数为( int , int ),范围值为int类型的函数.

int *p():p先和()结合,成为函数,返回类型为int *

和数组指针有点类似,p1指向的是10个元素的地址,元素都是int类型

	int arr[10] = { 0 };
	int(*p1)[10] = &arr;

函数指针类型 int (* )(int ,int)
数组指针类型 int( * )[10];

使用函数指针调用函数
	printf("%d\n", p(a, b));
	printf("%d\n", (*p)(a, b));
	printf("%d\n", (***p)(a, b));

*两个执行的结果相同,p是函数指针,p是调用这个函数,其实直接用p进行调用也行,可对比上面的Add和&Add都代表函数的地址。
其实p前面有多少*无所谓,执行结果都一样

其他类型函数的指针
#define _CRT_SECURE_NO_WARNINGS 1
#include

void Print(const char* str) {
	printf("%s", str);
}

int main() {
	
	const char* str = "abcdef";
	void (*ps)(const char* str) = &Print;
	ps(str);
	getchar();
	return 0;
}
下面分析两块代码

代码1

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

可以拆分为

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

void()()是函数指针类型,加上(),( void( * )() ) 0,是将0处的地址强制类型转换成void()()类型,
( * ( void( * )() )0)()后前面的 * 进行解引用操作,执行这个地址的函数,后面的()是这个地址的函数没有参数。

代码2

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

进行拆分

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

signal先后和后面的()结合形成函数
函数的第一个参数是int ,类型,第二个参数是void(*)(int)类型

void(*)(int)

signal函数饿返回类型是void(*)(int)函数指针类型。

使用typedef 对函数指针重命名,将void(*)(int)命名为pfu_t

typedef void(*pfu_t)(int)

所以代码2可改成:

pfu_t signal(int ,pfu_t)

你可能感兴趣的:(C指针,C指针)