printf的执行顺序

printf()函数的参数,在printf()函数读取时是从左往右读取的,然后将读取到的参数放到栈里面去,

最后读取到的就放在栈顶,处理参数的时候是从栈顶开始的,所以是从右边开始处理的.                                  --printf()函数的特点.

所以printf的执行顺序是从  从右到左进行运算
注意:我们在写代码时,尽量避免无确定意义的表达式出现,因为不同的编译器,可能会采用不同的理解方式.

附上一个例子:


#include<stdio.h>
void main()
{
    int i=2;
    printf("%d,%d,%d,%d,\n",i++,++i,i,i++);
    printf("%d\n",i);
}   

首先,应该说明的是在不同的编译环境中结果是不一样的。

关于本段代码在VC++6.0中的规则如下: 
1、printf函数的执行顺序是由右到左的 
2、前自增运算符(++i)先加1,再使用i,此时i已经加了1; 
3、后自增运算符(i++)先使用i,再加1,***注意这里是关键所在,VC++6.0后自增运算是要在整条语句结束以后才自加1的!

所以: 
printf("%d,%d,%d,%d,\n",i++,++i,i,i++); 
从右往左运算: 
i++得到2(i=2,后加1在整条语句执行完才进行,这里先记下) 
i还是2 (i=2,原因见上一行) 
++i得到3(i=3,先加1,后使用) 
i++得到3(i=3,后加1在整条语句执行完才进行,这里先记下) 
所以输出结果为:3,3,2,2 
然后计算刚才的两次后自增运算后,i=5

printf("%d\n",i); 
所以,结果是5

参考链接:http://blog.csdn.net/bingxuewujian/article/details/6728396

时间: 2024-10-09 10:37:52

printf的执行顺序的相关文章

C: printf参数执行顺序与前置后置自增自减的影响

起源: 今天在了解副作用side-effect的过程中,看到了下面的网页,把我带到了由printf引起的一系列问题,纠结了一整天,勉强弄懂. 第一个代码没什么好解释的.而第二个printf("return of swap is %d\tx=%d,y=%d\n",swap(&x,&y),x,y)居然是"return of swap is 1 x=1,y=0",输出的x和y的值并没有改变! 原因在于C语言函数参数的处理是从右到左的压栈顺序(这个我在看第一

51Nod - 1099 任务执行顺序

51Nod - 1099 任务执行顺序 有N个任务需要执行,第i个任务计算时占R[i]个空间,而后会释放一部分,最后储存计算结果需要占据O[i]个空间(O[i] < R[i]). 例如:执行需要5个空间,最后储存需要2个空间.给出N个任务执行和存储所需的空间,问执行所有任务最少需要多少空间. Input 第1行:1个数N,表示任务的数量.(2 <= N <= 100000) 第2 - N + 1行:每行2个数R[i]和O[i],分别为执行所需的空间和存储所需的空间.(1 <= O[

助教:C语言问题收集--scanf()的一些常见问题;switch语句;for循环的执行顺序

scanf函数中的"格式控制"后面应当是变量地址,而不应是变量名. 输入数据时不能规定精度. scanf("%7.2f",&a).这是不合法的.但是,scanf("%3d%3d",&a,&b)这样写可以. 如果在"格式控制"字符串中除了格式说明以外还有其他字符,则在输入数据时在对应位置应输入与这些字符相同的字符. scanf("%d,%d,%d",&a,&b,&

一个有关Golang Deferred Function 执行顺序的问题

先看一下一段关于defer的解释, 引自<Go程序设计语言> Syntactically, a defer statement is an ordinary function or method call prefixed by the keyword defer.The function and argument expressions are evaluated when the statement is executed, but the actual call is deferred

贪心基础入门讲解五——任务执行顺序

分析: 本题可以抽象成,从一个整数开始,每次减去a,再加上b (a,b都是正数),要求每次操作都不产生负数. 针对本题a[i] = R[i], b[i] = R[i] – O[i],注意O[i] < R[i],我们有0<b[i]<a[i]. 所以尽管每次有减有加,但是加的没有减的多,总数还是在不断见效的.关键我们是要“最有利”的一种执行顺序.大家可以尝试多种贪心策略. 我们给出标准答案——按照b[i]不增的顺序排序,是最“有利”的. 为了定义“有利”,我们这样证明我们的结论: 如果对于b

C++ 构造与析构的执行顺序

1.代码如下:class A{public: int _Id; A():_Id(0) { printf("A[%d]\n",_Id); } ~A() { printf("~A[%d]\n",_Id); }}; class B{public: A _A; A* _PA; B() { printf("B\n"); } ~B() { printf("~B\n"); delete _PA; }}; int main(int argc,

虚函数构造和析构函数执行顺序总结

一.定义 虚函数: 在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数,可实现函数成员的动态重载. 纯虚函数: 纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做.含有纯虚函数的类被称为抽象类(abstract class) 二.格式 虚函数:virtual <函数返回类型>< 函数名>(<参数表>) {函数体}: 纯虚函数:virtual <函数返回类型&

iOS程序执行顺序和UIViewController 的生命周期(整理)

说明:此文是自己的总结笔记,主要参考: iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 UIView的生命周期 言叶之庭.jpeg 一. iOS程序的启动执行顺序 程序启动顺序图 iOS启动原理图.png 具体执行流程 程序入口进入main函数,设置AppDelegate称为函数的代理 程序完成加载[AppDelegate application:didFinishLaunchingWithOptions:] 创建window窗口 程序被激活[

修饰符-包-内部类-代码块执行顺序

1.访问权限修饰符     从大到小的顺序为:public--protected--default--private     private--只能在同一类中使用;     default--不用写出来,默认不加.可以被同一包中的类使用     protected--可以被不同包的子类使用     public--可以被不同包的其它类使用 2.各种修饰符的修饰对象(可修饰哪些:类/接口/方法/属性)(多个修饰符连用是可以没有顺序的!)     1)访问权限修饰符:public/default--