加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

printf函数参数压栈顺序的问题

2021/02/02
610
阅读需 5 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

本文分析 printf 函数参数压栈顺序的问题,先来个入门第一题,不看答案先做题,看看你会不会怀疑自己的答案。

题目:

#include

int main(){
 
 int a=1; 
 printf("%d, %d, %d\n", a, ++a, a++);
 
 return 0;
}

结果:

分析:

1、知识点:a++表示先用 a 后把 a+1,++a 表示先把 a+1,然后再用

2、printf()语句多个参数的执行顺序,从右往左

3、所以,从右往左:a++,先 a=1,然后 a+1,这时 a 变成 2,++a,a 先加 1,a=3,打印出来:3,3,1

编译的时候从右向左,输出的时候从左往右。

底层原理:

主要是因为栈(压栈),栈是先进后出,后进先出。

C 函数的参数压栈顺序是从右到左,printf 和 scanf 函数都是,采用压栈从右到左的原因如下:

printf 函数的原型是:

printf(const char* format,…)

它是一个不定参函数,我们在实际使用中是怎么样知道它的参数个数呢?这就要靠 format 了,编译器通过 format 中的%占位符的个数来确定参数的个数。

现在我们假设参数的压栈顺序是从左到右的,这时,函数调用的时候,format 最先进栈,之后是各个参数进栈,最后 pc 进栈,此时,由于 format 先进栈了,上面压着未知个数的参数,想要知道参数的个数,必须找到 format,而要找到 format,必须要知道参数的个数,这样就陷入了一个无法求解的死循环了。

而如果把参数从右到左压栈,函数调用时,先把若干个参数都压入栈中,再压 format,最后压 pc,这样一来,栈顶指针加 2 便找到了 format,通过 format 中的%占位符,取得后面参数的个数,从而正确取得所有参数。

所以,如果不存在这种不定参的函数,则参数的压栈顺序无论是从左到右还是从右到左都是没关系的。

函数有多个参数时计算总得有个顺序吧?不是从左至右,就是从右至左,抑或从中间向两边;一句话选定一个顺序后就“大家都这么办”,总不能有些函数从左至右,有些函数从右至左,那编译器就太难做了。当初选择从右至左肯定是这样有好多方便之处,比如 printf 中的参数表,由于 C 是基于栈操作的,栈又是后进先出的,从右至左计算压栈,然后按弹出顺序输出到屏幕上刚好顺应了大多数文本从左至右的习惯,很是方便;若从左至右计算压栈,处理就没有这么方便了。

知道了这个原理,我们再出两题加强练习:

#include

int main(){
 
 int a=0, b=0;
 printf("%d,%d,%d\n",a++,++b,a);
 a=0; 
 printf("%d %d %d\n",a,a++,a);
 b=0;
 printf("%d %d %d %d %d \n",b, b++, ++b, b++, ++b);

 return 0;
}

 

#include

int main(){
 
 int x;
 x=1;   printf("%d %d\n",x,x++);
 x=1;   printf("%d %d\n",x++,x);
 x=1;   printf("%d %d %d\n",x,x++,x);
 x=1;   printf("%d %d %d %d\n",x,++x,x++,x);
 
 return 0;
}

 

 

注意:不同编译器可能出现不同的结果。

我们研究此题目只是为了深究一下 C 语言函数参数调用的原理,现实中最好不要这么写代码,这么写你可能会被打死。

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
KSZ8863RLLI-TR 1 Microchip Technology Inc DATACOM, LAN SWITCHING CIRCUIT
$5.09 查看
TLE9271QXV33XUMA1 1 Infineon Technologies AG Interface Circuit, PQCC48, VQFN-48
暂无数据 查看
CPC1718J 1 IXYS Corporation Transistor Output SSR, 1-Channel, 2500V Isolation, ROHS COMPLIANT, ISOPLUS264, 4 PIN
$6.72 查看

相关推荐

电子产业图谱

研究生在读,熟悉硬件、STM32单片机、嵌入式Linux。已收获小米、联发科、浙江大华、上能电气、英威腾、汇川技术、格力、富士康等大厂offer。在这里分享求职经验、嵌入式学习规划、考研、嵌入式Linux技术文章等。