可变长参数列表
可变长参数列表
该段代码输出()
1 | int main() |
A. 3,3 B. 2,2 C. 2,3 D. 3,2
参数入栈顺序:
通常情况下c/c++默认入栈方式为
__cdecl
。
关键字 堆栈清理 参数传递 __cdecl Caller 以相反的顺序(从右到左)将参数压入堆栈 __clrcall n/a 按顺序(从左到右)将参数加载到 CLR 表达式堆栈 __stdcall Callee 以相反的顺序(从右到左)将参数压入堆栈 __fastcall Callee 存储在寄存器中,然后压入堆栈 __thiscall Callee 压入堆栈;此指针存储在 ECX 中 __vectorcall Callee 存储在寄存器中,然后以相反的顺序(从右到左)压入堆栈 为什么要从右往左入栈? 因为要支持可变长参数,如果从左向右,编译器就不知道用户传入了多少实参。 参数的信息是由第一个参数
fmt...
确定的(如printf(“%s %s”,str1 ,str2)的参数信息是通过检测两个%s
来获取的)。若从左向右压栈,fmt...
就被放入了栈底,而栈顶指针由于不清楚各个参数信息,就无法确定偏移量来指向fmt...
,所以也无法指向各个参数。相反,若从右向左压栈,fmt...
就存放在栈顶,可以直接通过它读取各参数的信息从而确定偏移量。所以上题,是先处理
*(++p)
,再处理*p
,故而选A。类型检查与默认参数提升:
可变参数部分不会执行类型检查,因为其原型不能提供可变参数的数目和类型。同时,调用可变参数函数之前必须有其函数原型(这像废话,但在C语言中,函数声明不是必须的,引入头文件(其中的原型)主要作用是用于参数提示和类型检查,而C++中,调用之前必须有原型,否则会报错。
可变参数会进行默认参数提升:
char
与short
总是被提升为int
,float
总是被提升为double
,所以%f
可以同时表示float
和double
。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 极简!
评论