您的位置:首页 > 编程语言 > C语言/C++

从华为面试来看C/C++的调用约定

2016-06-19 09:44 429 查看
先看一个代码

void myfun(int i, int ii)
{
cout << i << " " << ii << endl;
}
void main()
{
int b = 3;
int arr[] = {6,7,8,9,10};
int *ptr = arr;
*(ptr++) += 123;
printf("%d\t%d\n", *ptr, *++ptr);
int i = 10;
myfun(i, ++i);
}VS2008输出:



函数的调用规范

      函数的调用规范,也称为调用约定(Calling convention)。函数的调用规范决定了函数调用时,实参压栈、退栈及堆栈释放方式,以及函数名改编(Name Mangling)的方案,也即命名规范。

      Windows环境下常用的调用规范有:

     1)__cdecl:这是C/C++函数默认的调用规范,参数从右向左依次传递,压入堆栈,由调用函数负责堆栈的清退。这种方式适用于传递个数可变的参数给被调用函数,因为只有调用函数才知道它传递了多少个参数给被调函数。如printf函数。

     2)__stdcall:参数从右向左依次传递,并压入堆栈,由被调用函数清退堆栈。当函数有可变个数参数,自动转化为__cdecl调用规范。

     3)__thiscall:这是C++非静态成员函数的默认调用规范,不能使用个数可变的参数。调用非静态成员函数的时候,this指针直接保存在ECX寄存器中,不入栈。其他方面同__stdcall。

     4)__fastcall

      凡是接口函数都必须显示指定其调用规范,除非接口函数是类的非静态成员函数。

 

关于结果的解释

     据说此题是华为的笔试题。但可能出题者也没理解此种的奥秘,而只知道结果。关于函数调用的参数求值顺序,语言实现标准是未定义的。之所以出现如图所示的结果,不仅与函数的调用规范决定的(从右向左对参数压栈),而是由微软编译器的具体实现:参数求值按照自右向左顺序决定的。函数调用压栈压入的是表达式的计算后的值,而不是表达式本身。

    另外,如果调用myfun(i, ++i); 改为myfun(i, i++);。将输入:11     10
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: