函数指针的定义相比大家都知道,返回值是函数指针的也有相关说明,比如linux下的信号处理函数signal()这个函数的原型就不贴出来了
因为这不是本篇文章的重点,本篇文章的重点是在返回值是函数指针的用法 普通的用法大家应该都见过,先来个引子热热身:
废话不多说先上代码
-
#include <stdio.h>
-
-
typedef int(*rtfunc_t)(int );
-
-
int foo(int m)
-
{
-
printf("m = %d\n",m);
-
return 0;
-
}
-
-
rtfunc_t func(int a)
-
{
-
return foo;
-
}
-
-
int main(int argc, const char *argv[])
-
{
-
func(1)(2);
-
-
return 0;
-
}
运行结果是m=2;
注意第18行的用法,这个用法可能比较少见,第一个参数素传给func函数的,第二个参数素传个函数指针的
可能有不少人见过这种用法,但是原理是怎样的就不得而知了。
一般情况下unix下c程序调用函数是参数入栈,想当然的情况是
pushl 1
pushl 2
call func;
但是这样的话想想函数执行的原理也是想不通的当执行foo函数的时候其参数到底在什么位置,
对于func函数来说在(ebp+8)的位置,但是对于foo来说呢 因为foo也是函数 也有自己的栈帧
其参数肯定不会在(ebp+8)的位置、
我们来看下汇编代码(在linux执行gcc -S 就可以得到其汇编代码)
-
main:
-
.LFB2:
-
.cfi_startproc
-
pushl %ebp
-
.cfi_def_cfa_offset 8
-
.cfi_offset 5, -8
-
movl %esp, %ebp
-
.cfi_def_cfa_register 5
-
andl $-16, %esp
-
subl $16, %esp
-
movl $1, (%esp)
-
call func
-
movl $2, (%esp)
-
call *%eax
-
movl $0, %eax
-
leave
-
.cfi_restore 5
-
.cfi_def_cfa 4, 4
-
ret
-
.cfi_endproc
此处只贴上相关的代码
注意第11行12行 在call func函数之前只是把1入栈 调用完毕再把数字2入栈 然后再call eax 此刻的eax 值是 foo的地址
从这里可知,只有遇到函数的时候才会把自己的参数入栈 也就是创建自己的栈帧,不会和其他函数冲突。
阅读(1722) | 评论(0) | 转发(0) |