从华为面试来看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
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
相关文章推荐
- struct和typedef struct的区别
- C++之深浅复制剖析
- PAT乙级练习题B1009. 说反话
- leetcode #122 in cpp
- leetcode #121 in cpp
- leetcode #119 in cpp
- leetcode #118 in cpp
- leetcode #117 in cpp
- leetcode #116 in cpp
- *leetcode #115 in cpp
- c++面试题
- C002-CPP-用malloc()存储任意长度的键入字符串
- 幂法求矩阵最大特征值的近似解(C++实现)
- 日常小结-模板类型限制、getline使用
- 将Python代码嵌入到C++程序
- C语言 百炼成钢22
- 整数反转
- C语言定义和声明的区别
- C++ IO流小结
- C++大数类 大数模版