输入理解C语言中的函数声明
来源:互联网 发布:mysql character 编辑:程序博客网 时间:2024/04/28 19:59
看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解。
1.理解函数声明
为了模拟开机启动时的情形,我们必须设计出一个C语句,以显示调用位于地址0的子例程。调用语句如下:
(*(void (*)())0)();
胆颤了吧?首先我们从函数的声明说起:有如下一个函数
void func(){...}
那么,要想声明一个函数指针,指向这类函数,怎样声明呢?如下:
void (*pf)();
那么,想要将一个值转换成一个指针,指向这类函数,怎么强制转换呢?如下:
(void (*)())value
现在value被转换成了一个指向函数的指针,怎么调用它呢?如下:
((void) (*)()value)();
或 (*(void) (*)()value)();
或 (******(void) (*)value)();
神奇吧,看了上面的函数调用方式!其实你完全可以这样调用函数:
func();
(*func)();
(********func)();
没有任何问题!
对于初学的时候,最容易头晕的就是指针符*到底是什么东西?它是变量的一部分?还是声明类型的一部分?其实,仔细回忆C中标识符的定义规则就知道,指针符*必须是类型声明的一部分,因为变量的声明不能含有指针符号,否则是一个非法的变量!
2.C语言中的声明
对比简单类型的强制转换我们就可以更加明白上面的强制转换,简单类型定义如下:
int a;
char b;
b=(char)a;
int *a;
char *b;
b=(int *)a;
其实,在各种指针之间转换很少见,最常见的就是将void指针转换成各种指针,用过malloc族函数吗?
a=(int *)malloc(sizeof(int));
由于声明符和表达式类似,所以你可以这样声明
int ((a)); //将a声明为一个int型值
int *func(),(*fp)();
前者是一个函数,后者是一个指针,所以千万不要对指针定义成函数了,分不清概念的时候最容易这样
int (*fp)(){
/*do something*/
}
显然,这里将一个指针定义成了一个函数!这是任何编译器都不能容忍的。
结合简单变量的类型,出去声明中的变量,得到的就是这个变量的类型,如float a,那么要将一个变量转换成a的类型,那么只需要
(float)value;即可,同理:
float *b,除去变量b,得到b的类型是(float *)。
float (*fp)();除去变量fp,得到的类型是float (*)(),所以要将变量转换成fp类型的值时,只需要(float (*)())value,即可!这样value即被转换成一个函数指针了,也就像最前面的例子中那样!
如果,更复杂,有声明如下:
float * (*fp)(); //返回一个float指针
其实,这也是唬人的,同理可知:强制转换类型为(float * (*)())value;
3.其他考量
看到第一个例子时,可能想,能不能这样子:(*0)();呢?
不行,因为0是一个数字,而*必须要操作一个指针,而且对于要调用的函数是void型的,所以这个指针应该转换成相应的类型,所以需要将0转成一个指向void返回值的参数为空的函数的指针。
最后,linux内核中的信号处理函数定义如下:
void (*signal(int,void (*)(int)))(int);
首先,将上面的函数声明看成这样void (*p)(int);可知,p是一个函数,所以signal函数的返回类型为一个函数指针,指向的函数类型是
void (*)(int);使用typedef可以简化上面signal函数的声明
typedef void (*HANDLER)(int);
HANDLER signal(int,HANDLER);
解释一下:signal是一个返回函数指针的函数,返回的指针指向的函数类型是void (*)(int);而signal的参数一个是int,另一个是一个函数,类型为void (*)(int),刚好就是最初声明的样子。
- 输入理解C语言中的函数声明
- C语言中的函数声明
- 如何理解C语言中的变量声明
- 理解 C 语言中的复杂声明
- c语言中的复杂声明理解方法
- c语言中的输入函数
- C语言中的隐式函数声明
- C语言中的隐式函数声明
- C语言函数声明
- C语言函数声明
- C语言函数声明
- C语言--函数声明
- 对c语言陷阱与缺陷中函数声明理解
- 理解c语言中的复杂声明-向右看,向左看
- C语言中的各种输入函数整理
- 谈谈C语言中的scanf()输入函数
- C语言中的函数定义及函数声明
- C语言声明的理解
- 09.11.19面试手机软件测试实习生过程中面试官给提出来的一些问题整理归纳
- .Net学习资源集合
- Linux
- 改变
- 数字图像攻击模拟系统(7)
- 输入理解C语言中的函数声明
- JMX 编程实现在weblogic中添加用户
- JDBC连接执行MySQL存储过程报空指针或权限错误
- 数字图像攻击模拟系统(8)
- codeproject
- 数字图像攻击模拟系统(9)
- blog皮肤----Sweet Coffee
- P2P之UDP穿透NAT的原理与实现
- Android基础教程(九)之自定义下拉菜单模式----Spinner与setDropDownViewResource的应用