printf函数参数压栈顺序

时间:2023-01-09 22:28:48

printf函数的参数的压栈顺序和求值顺序(VC++6.0编译器)
有以下程序段:
设int arr[]={6,7,8,9,10};
int *ptr=arr;
*(ptr++)+=123;
printf("%d,%d",ptr,(++ptr));
答案为什么是:8,8
这是一道华为面试题。
这个题考的关键就是printf的运算顺序。

这个是比较绕的一个问题,主要考验的是i++ 和++i :
我们逐个分析:
int arr[]={6,7,8,9,10};
int *ptr=arr;
//这里ptr是数组的首地址。
*(ptr++)+=123;
//这个我们将之拆分
//1. 首先是 ptr++, 这个时候重点看到是后++,也就是说返回的ptr还是原来的ptr的值,也就是arr的首地址。
//那么这句话也就转换成了 a[0]+=123,即运算后 a[0] = 129
//2. 这整句运行完之后,ptr才真正的++。也就是说,这个时候ptr指向的数组第二个位置,也就是7
printf("%d,%d",ptr,(++ptr));
//这一句有一个函数参数入栈的顺序,一般VC的编译器是从右往左入栈,那么这个运算也自然是从右往左。
//++ptr之后ptr再次向后一个位置移动,即a[2],8。
//前面的*ptr自然也就是8,所以这句运行之后输出的是8,8

printf函数的压栈顺序和求值顺组不一样 压栈顺序是从右向左的,是固定的,而求值顺序是不定的,根据每个编译器的不同而不同。比如VC++6.0就是从右向左 C语言那样的参数压栈比较适合不定参数的实现,也就是比如 f(int ,float, …) 如果考虑效率,也可以用用pascal方式(它的压栈循序与c的相反),求值的循序如果对程序有影响的话,也不用去关心程序的实现是从左到右还是从右到左,而应在调用函数之前确定好