自增自减问题
#include <stdio.h>void main ()
{
int i=8;
printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--);
}
看了小甲鱼的视频,自己动手试了下,使用一个printf输出自增自减,
我理解的是所有的i自增自减以后才输出,但是第二个为什么会是7,不应该是8吗,
有没有朋友帮我解答下,详细点 这个问题前几天见到过
你可以在这个帖子里看我的回答。
https://fishc.com.cn/forum.php?mod=redirect&goto=findpost&ptid=155919&pid=4343099
看懂了的话可以选个最佳答案{:10_279:} 又是这类问题,对于这类问题不管输出了什么样的结果,都是错误的,因为这样的代码标准未定义,编译器可以随意发挥(真的是随意发挥,好好理解随意发挥这4个字),不同的编译器可能会有不同的结果,即使是同一个编译器,用了不同的选项也有可能会得到不同的结果,如果编译器输出了6个0,你也不能抱怨,因为你的代码行为未定义,编译器完全可以输出6个0以表示对你程序的抱怨,不过好像没有编译器这样做
有的编译器是把这一行中所有的前缀 ++ -- 全部运行完,然后输出结果,然后再继续运算后缀 ++ --
也有的编译器真的是从右到左,遇到一个算一个
int a = 10;
printf("%d %d %d\n", --a, --a, --a);
编译器有可能输出 7 7 7
也有可能是 7 8 9
或者输出 9 8 7 (这个的可能性不大,不过并不是不能,虽然我没有见过输出这个结果的编译器,我见过前两个的,就是vs系列和gcc系列)
就算是输出了 0 0 0 也行,因为这样的代码行为未定义,不同的编译器会给出不同的结果
再一次说明,对于这类问题,编译器可以随意发挥
printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--);
00412D3F 8B 45 FC mov eax,dword ptr //ebp-4就是i=8
00412D42 F7 D8 neg eax //-8
00412D44 89 45 F8 mov dword ptr ,eax
00412D47 8B 4D F8 mov ecx,dword ptr
00412D4A 51 push ecx // ecx=eax=-8 倒数第一个数
00412D4B 8B 55 FC mov edx,dword ptr
00412D4E F7 DA neg edx //-8
00412D50 89 55 F4 mov dword ptr ,edx
00412D53 8B 45 F4 mov eax,dword ptr
00412D56 50 push eax //eax=edx=-8倒数第二个数
00412D57 8B 4D FC mov ecx,dword ptr
00412D5A 89 4D F0 mov dword ptr ,ecx
00412D5D 8B 55 F0 mov edx,dword ptr
00412D60 52 push edx //edx=ecx=8 倒数第三个数
00412D61 8B 45 FC mov eax,dword ptr
00412D64 89 45 EC mov dword ptr ,eax
00412D67 8B 4D EC mov ecx,dword ptr
00412D6A 51 push ecx //ecx=eax=8 倒数第四个数
00412D6B 8B 55 FC mov edx,dword ptr //edx=ebp-4=8
00412D6E 83 EA 01 sub edx,1 //edx=edx-1=7
00412D71 89 55 FC mov dword ptr ,edx //ebp-4=edx=7
00412D74 8B 45 FC mov eax,dword ptr
00412D77 50 push eax //eax=edx=7 倒数第五个数 你所关心的
00412D78 8B 4D FC mov ecx,dword ptr //ecx=ebp-4=7
00412D7B 83 C1 01 add ecx,1 //ecx=ecx+1=8
00412D7E 89 4D FC mov dword ptr ,ecx //ecx=ebp-4=8
00412D81 8B 55 FC mov edx,dword ptr //edx=ebp-4=8
00412D84 52 push edx //edx=8 倒数第六个数
00412D85 68 B4 A1 42 00 push offset string "%d\n%d\n%d\n%d\n%d\n%d\n" (0042a1b4)
00412D8A 8B 45 FC mov eax,dword ptr
00412D8D 83 C0 01 add eax,1
00412D90 89 45 FC mov dword ptr ,eax
00412D93 8B 4D FC mov ecx,dword ptr
00412D96 83 E9 01 sub ecx,1
00412D99 89 4D FC mov dword ptr ,ecx
00412D9C 8B 55 FC mov edx,dword ptr
00412D9F 83 C2 01 add edx,1
00412DA2 89 55 FC mov dword ptr ,edx
00412DA5 8B 45 FC mov eax,dword ptr
00412DA8 83 E8 01 sub eax,1
00412DAB 89 45 FC mov dword ptr ,eax
00412DAE E8 9D E5 FE FF call printf (00401350)
00412DB3 83 C4 1C add esp,1Ch //1Ch=28d 28/4(字节)=7个,这个call被压了7个参数,你数数看 再加上 pushoffset string"%d\n%d\n%d\n%d\n%d\n%d\n" (0042a1b4)
你看下反汇编,看注释
我个人的建议,++和--不要乱用,不然容易出问题的,不同的编译器处理起来也不同的 先看前提知识,再看步骤:
注:不同的编译器++ -- 放在一起运算的方式也不相同的,得到的值自然也就不同;道理差不多。所以一般都不会这么用。
页:
[1]