欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > 深⼊理解指针(7)

深⼊理解指针(7)

2025/5/1 17:15:52 来源:https://blog.csdn.net/2301_79479763/article/details/147641243  浏览:    关键词:深⼊理解指针(7)

1.函数指针变量的创建

在x86环境下:

我们发现:以函数是有地址的,函数名就是函数的地址,当然也可以通过& 函数名 的⽅式获得函数的地址。

如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指针⾮常类似。如下:

函数指针类型解析: 

 

再加上一组:

发现pf的前面可以不带*

2.两段有趣的代码

 
    (*(void (*)())0)();
    //解释一下
    // void (*)()—— 是函数指针类型
    //(void (*)()) —— 括弧里面放类型就是强制转换
    //(void (*)())0 —— 将0强制转换为 void (*)() 的函数指针类型
    //这就意味着我们假设 0 地址处放着无参,返回类型是 void 的函数
    //最终是调用 0 地址处放的这个函数

 void (* signal( int, void(*)(int) ) )(int);
// signal —— 函数名
// int —— 参数1
// void(*)(int) —— 参数2
// signal( int, void(*)(int) ) —— 其中少函数值的返回类型
// 而剩下的void ( )(int); —— 这就是返回类型
// 所以这段代码本质是一个函数声明
// 想表达的意思是:
// void (*)(int)signal( int, void(*)(int) )
// 注意像上一行这样写是会报错的
// 只是想要表达这个意思而已

3.typedef关键字

typedef 是⽤来类型重命名的,可以将复杂的类型,简单化。⽐如,你觉得unsigned int 写起来不⽅便,如果能写成 uint 就⽅便多了,那么我们可以使⽤:

如果是指针类型,能否重命名呢?其实也是可以的,⽐如,将int* 重命名为 ptr_t ,这样写:

但是对于数组指针和函数指针稍微有点区别:

⽐如我们有数组指针类型 int(*)[5] ,需要重命名为 parr_t ,那可以这样写:

注意:

// 新的类型名必须在 * 的右边

函数指针类型的重命名也是⼀样的,⽐如,将 void(*)(int)  类型重命名为  pf_t  ,就可以这样写:

那么要简化上述的代码2,可以这样写:

typedef void(*pfun_t)(int);

pfun_t signal(int, pfun_t);

本篇文章中所用到的代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
//int Add(int x, int y)
//{
//	return x + y;
//}
//int main()
//{
//	printf("%p\n", Add);
//	printf("%p\n", &Add);
//	return 0;
//}//int Add(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	//回忆一下数组指针
//	//int arr[10] = { 0 };
//	//int (*pa)[10] = &arr;
//	//函数与数组类似
//	int (* pf)(int, int) = &Add;
//	//(int, int) 是因为(int x, int y)
//	// int (* pf)是因为int Add
//	//pf是专门用来存放函数地址的,pf 就是函数指针变量
//	return 0;
//}//int Add(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	int(*pf)(int, int) = Add;
//
//	int c = Add(2, 3);
//	//函数名调用
//	printf("%d\n", c);
//
//	int d = (*pf)(3, 4);
//	//函数指针变量调用
//	printf("%d\n", d);
//
//	int e = (pf)(4, 5);
//	//函数指针变量调用
//	printf("%d\n", e);
//
//	return 0;
//}看看有趣的代码
//int main()
//{
//	(*(void (*)())0)();
//	//解释一下
//	// void (*)()—— 是函数指针类型
//	//(void (*)()) —— 括弧里面放类型就是强制转换
//	//(void (*)())0 —— 将0强制转换为 void (*)() 的函数指针类型
//	//这就意味着我们假设 0 地址处放着无参,返回类型是 void 的函数
//	//最终是调用 0 地址处放的这个函数
//	return 0;
//}//void (* signal( int, void(*)(int) ) )(int);signal —— 函数名int —— 参数1void(*)(int) —— 参数2signal( int, void(*)(int) ) —— 其中少函数值的返回类型而剩下的void ( )(int); —— 这就是返回类型所以这段代码本质是一个函数声明想表达的意思是:void (*)(int)signal( int, void(*)(int) )注意像上一行这样写是会报错的只是想要表达这个意思而已
//
//int main()
//{
//
//	return 0;
//}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词