当printf遇上了i++和++i 当我看到这个代码的时候,突然就对printf和i++产生了疑问。
i=1; printf("%d %d\n",i,i++) // 2 1
i=1; printf("%d %d\n",i++,i); // 1 2
i=1; printf("%d %d %d\n",i,i++,i); // 2 1 2
i=1; printf("%d %d %d %d %d\n",i,++i,i++,i); // 3 3 1 3
输出的结果是不是有点意外!!! 我查阅了很多资料终于弄明白了。。。
先说下i++和++i的区别
i++ 会先复制一个副本,然后在真值上 (真值就是原来的数据) +1,相当于产生了两个变量,一个是副本不会变,一个原来的数据会+1。
++i 则是直接在原数据上+1,不会产生新的中间变量。
然后说下printf的压栈问题
用一个例子讲解一下,先自己思考一下最后会输出多少,会能更好的理解,输出结果最后解密,最后的结果可能超出你的预料哟!!!int a = 1; printf("%d %d %d %d %d %d %d\n", a++,++a,a++,++a,a,a++,++a);
printf是先从右向左压栈,压栈的时候瞬间算出结果,然后按这个例子结尾的++a属于高位,开头的a++属于低位,出栈的时候从低位开始出。
入栈顺序 |
入栈参数 |
操作 |
栈内情况 |
a的值 |
---|---|---|---|---|
⑦(低位) |
a++ |
先copy一个a,然后对原数据a+1,将copy的压栈 |
a(copy3) |
7 |
⑥ |
++a |
直接对a+1 |
a |
6 |
⑤ |
a++ |
先copy一个a,然后对原数据a+1,将copy的压栈 |
a(copy2) |
5 |
④ |
++a |
直接对a+1 |
a |
4 |
③ |
a |
直接就是a |
a |
3 |
② |
a++ |
先copy一个a,然后对原数据a+1,将copy的压栈 |
a(copy1) |
3 |
①(高位) |
++a |
直接对a+1 |
a |
2 |
注意: 1,当有副本的时候会输出副本,但是真值已经加了1了。 2,对真值操作就相当于对原来的a操作,所以每次更改真值,会把栈底的a也会改变。
正确答案就是 6 7 4 7 7 2 7.
总结
printf是从右向左读取参数压栈,在压栈的时候会算出来值。
改变真值时候是会影响下面的a,其实就是改变原来的数据。
可能老师教i++和++i的时候,是说i++先判断,++i是先加,这让更通俗,但是会把人带坏,记住他们的本质。
【C语言】五小时快速入门C语言https://nxv.xet.tech/s/3wB3iM
【C语言】零基础到项目实战(交换机项目)https://nxv.xet.tech/s/2bnZ5w【C++】实战入门:智能婚恋交友系统
https://nxv.xet.tech/s/1gtfps