#include <stdio.h> int main(int argc, char *argv[]) { int b = 3; int arr[] = { 6, 7, 8, 9, 10}; int *ptr = arr; *(ptr++) += 123; printf( "%d, %d\n", *ptr, *(++ptr) ); return 0; }
求输出结果?
开始看这个题目觉得很简单的,无非就是考i++和++i的问题,后来发现,在printf那里出问题了,我以为参数是按照stdcall顺序的,即从左到右,
可结果确实从右到左,查阅资料表明,C语言里面的函数参数入栈都是从右到左的顺序(之前忘记了,汗~~~),究其原因。看到某篇文章,称那
是因为C语言支持不定参数而要求这样做的,因为这样的话,右边的参数先入栈,在栈底,而左边的却在栈顶,调用参数的话就只需要从栈依
次取出即可,而不需要参数个数。倘若参数入栈是从左到右,那么在遇到动态参数个数的问题时,由于函数调用的参数个数是不确定的,所以
对于取参数就遇到了不好处理的问题了,因为不知道栈顶的那个参数对应于函数的哪个参数,而如果采用参数从右到左顺序的话,那么就不需
要知道参数个数,直接从栈里取参数,然后和函数里面的参数从左到右匹配即可。这种解释,我觉得还是很不错的。
回到本题来,因为入栈是从右到左的,所以先会执行++ptr操作,然后把此时的数据值入栈,然后把左边的*ptr入栈,这时的ptr已经自增了,所以
本题的答案是:8, 8
事实发现当采用如下方式输出时:
printf( "%d, %d, %d\n", *ptr, *(++ptr), *ptr );
结果是:8, 8, 7
补充一点,由于printf采用的是动态参数个数,当采用如下方式输出数据时:
printf( "%d, %d", 1, 3, 5);
输出结果是:1, 3
表明printf摒弃了后面的5,即print根据格式字符串决定输出,然后按照格式字符串的规则,对于函数参数从左到右匹配,如果匹配完了之后还剩
下其他参数,那么函数将会摒弃这些参数。
附:好久没认真学习过C语言了,忘记了许多东西,现在复习起来真有点惭愧。