张世来4610484 发表于 2020-2-18 22:44:25

自增自减问题

#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吗,
有没有朋友帮我解答下,详细点

SHRS23 发表于 2020-2-18 23:57:02

这个问题前几天见到过
你可以在这个帖子里看我的回答。
https://fishc.com.cn/forum.php?mod=redirect&goto=findpost&ptid=155919&pid=4343099

看懂了的话可以选个最佳答案{:10_279:}

人造人 发表于 2020-2-19 00:00:36

又是这类问题,对于这类问题不管输出了什么样的结果,都是错误的,因为这样的代码标准未定义,编译器可以随意发挥(真的是随意发挥,好好理解随意发挥这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 也行,因为这样的代码行为未定义,不同的编译器会给出不同的结果

再一次说明,对于这类问题,编译器可以随意发挥

4goodworld 发表于 2020-2-19 00:12:50



          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)


你看下反汇编,看注释
我个人的建议,++和--不要乱用,不然容易出问题的,不同的编译器处理起来也不同的

ba21 发表于 2020-2-19 15:10:27

先看前提知识,再看步骤:
注:不同的编译器++ -- 放在一起运算的方式也不相同的,得到的值自然也就不同;道理差不多。所以一般都不会这么用。















页: [1]
查看完整版本: 自增自减问题