1809228982 发表于 2018-12-22 11:37:24

关于高级宏定义的问题

#include <stdio.h>

#define SQUARE(y) y*y

int main()
{
    int x;

    printf("请输入一个整数:");
    scanf("%d",&x);

    printf("%d的平方是%d",x,SQUARE(x--));
   
    return 0;
}


程序运行   输入 3

输出的结果为什么是   1的平方是6

???
求解答

人造人 发表于 2018-12-22 11:51:50

sh-4.4$ cat main.c
//#include <stdio.h>

#define SQUARE(y) y*y

int main()
{
      int x;
      printf("请输入一个整数:");
      scanf("%d",&x);
      printf("%d的平方是%d",x,SQUARE(x--));
      return 0;
}
sh-4.4$ gcc -E main.c
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"




int main()
{
int x;
printf("请输入一个整数:");
scanf("%d",&x);
printf("%d的平方是%d",x,x--*x--);
return 0;
}
sh-4.4$

人造人 发表于 2018-12-22 11:57:56

_main:
      pushl   %ebp
      movl    %esp, %ebp
      andl    $-16, %esp
      subl    $32, %esp
      call    ___main
      movl    $LC0, (%esp)
      call    _printf
      leal    28(%esp), %eax
      movl    %eax, 4(%esp)
      movl    $LC1, (%esp)
      call    _scanf
      movl    28(%esp), %edx
      leal    -1(%edx), %eax
      movl    %eax, 28(%esp)
      movl    28(%esp), %eax
      leal    -1(%eax), %ecx
      movl    %ecx, 28(%esp)
      imull   %eax, %edx
      movl    28(%esp), %eax
      movl    %edx, 8(%esp)
      movl    %eax, 4(%esp)
      movl    $LC2, (%esp)
      call    _printf
      movl    $0, %eax
      leave
      ret

1809228982 发表于 2018-12-22 14:39:49

人造人 发表于 2018-12-22 11:51


??怎么有两个main函数??

人造人 发表于 2018-12-22 15:24:24

1809228982 发表于 2018-12-22 14:39
??怎么有两个main函数??


#define SQUARE(y) y*y

int main()
{
      int x;
      printf("请输入一个整数:");
      scanf("%d",&x);
      printf("%d的平方是%d",x,SQUARE(x--));
      return 0;
}

相当于


int main()
{
int x;
printf("请输入一个整数:");
scanf("%d",&x);
printf("%d的平方是%d",x,x--*x--);
return 0;
}

1809228982 发表于 2018-12-28 09:12:57

人造人 发表于 2018-12-22 15:24
相当于

x--*x--    分解 是 x = x - 1 * x = x - 1;(还是 (x = x - 1 )* (x = x - 1))

人造人 发表于 2018-12-28 13:00:48

本帖最后由 人造人 于 2018-12-28 13:02 编辑

1809228982 发表于 2018-12-28 09:12
x--*x--    分解 是 x = x - 1 * x = x - 1;(还是 (x = x - 1 )* (x = x - 1))

答案是不确定,标准对这类代码行为的定义是“未定义”,也就是说编译器爱怎么搞就怎么搞
编译器可以先算x*x,然后把x的结果减2
或者... 嗯,我认为我描述不清楚,看下面的代码吧

例1.    x=10
int y = x-- * x--;
先算x*x,结果为100,y的最终结果为100,然后把x减2,x的最终结果为8

例2.    x=10
int y = x-- * x--;
这个不好解释
这个计算的是9 * 10,y的最终结果为90,x最终为8
看下面汇编代码吧,你也许现在看不懂,但是如果你要深入研究这些,你必须要学习汇编语言

#include <stdio.h>

int main(void)
{
012C17A0 55                   push      ebp
012C17A1 8B EC                mov         ebp,esp
012C17A3 81 EC D0 00 00 00    sub         esp,0D0h
012C17A9 53                   push      ebx
012C17AA 56                   push      esi
012C17AB 57                   push      edi
012C17AC 8D BD 30 FF FF FF    lea         edi,
012C17B2 B9 34 00 00 00       mov         ecx,34h
012C17B7 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
012C17BC F3 AB                rep stos    dword ptr es:
        int x = 10;
012C17BE C7 45 F8 0A 00 00 00 mov         dword ptr ,0Ah
        printf("%d\n", x-- * x--);
012C17C5 8B 45 F8             mov         eax,dword ptr
012C17C8 0F AF 45 F8          imul      eax,dword ptr
012C17CC 89 85 30 FF FF FF    mov         dword ptr ,eax
012C17D2 8B 4D F8             mov         ecx,dword ptr
012C17D5 83 E9 01             sub         ecx,1
012C17D8 89 4D F8             mov         dword ptr ,ecx
012C17DB 8B 55 F8             mov         edx,dword ptr
012C17DE 83 EA 01             sub         edx,1
012C17E1 89 55 F8             mov         dword ptr ,edx
012C17E4 8B 85 30 FF FF FF    mov         eax,dword ptr
012C17EA 50                   push      eax
012C17EB 68 D0 7B 2C 01       push      offset string "%d\n" (012C7BD0h)
012C17F0 E8 35 FB FF FF       call      _printf (012C132Ah)
012C17F5 83 C4 08             add         esp,8
        return 0;
012C17F8 33 C0                xor         eax,eax
}
012C17FA 5F                   pop         edi
012C17FB 5E                   pop         esi
012C17FC 5B                   pop         ebx
012C17FD 81 C4 D0 00 00 00    add         esp,0D0h
012C1803 3B EC                cmp         ebp,esp
012C1805 E8 18 F9 FF FF       call      __RTC_CheckEsp (012C1122h)
012C180A 8B E5                mov         esp,ebp
012C180C 5D                   pop         ebp
012C180D C3                   ret


seg000:0291 ; =============== S U B R O U T I N E =======================================
seg000:0291
seg000:0291 ; Attributes: bp-based frame
seg000:0291
seg000:0291 sub_10291       proc near               ; CODE XREF: start+155p
seg000:0291               push    bp
seg000:0292               mov   bp, sp
seg000:0294               push    si


seg000:0295               mov   si, 0Ah



seg000:0298               mov   ax, 291h
seg000:029B               push    ax
seg000:029C               mov   ax, 0AAh ; '
seg000:029F               push    ax
seg000:02A0               call    sub_10EEC
seg000:02A3               pop   cx
seg000:02A4               pop   cx



seg000:02A5               mov   ax, si
seg000:02A7               dec   si
seg000:02A8               mov   dx, si
seg000:02AA               dec   si
seg000:02AB               imul    dx
seg000:02AD               push    ax
seg000:02AE               mov   ax, 0B4h ; '
seg000:02B1               push    ax
seg000:02B2               call    sub_10EEC
seg000:02B5               pop   cx
seg000:02B6               pop   cx



seg000:02B7               xor   ax, ax
seg000:02B9               jmp   short $+2
seg000:02BB ; ---------------------------------------------------------------------------
seg000:02BB
seg000:02BB loc_102BB:                              ; CODE XREF: sub_10291+28j
seg000:02BB               pop   si
seg000:02BC               pop   bp
seg000:02BD               retn
seg000:02BD sub_10291       endp
seg000:02BD
seg000:02BE ; ---------------------------------------------------------------------------

人造人 发表于 2018-12-28 13:04:46

vs2017

#include <stdio.h>

int main(void)
{
        int x = 10;
        int y = x-- * x--;
        printf("%d\n", x);
        printf("%d\n", y);
        return 0;
}

8
100
请按任意键继续. . .

人造人 发表于 2018-12-28 13:08:45

纯DOS,tc3.0



1809228982 发表于 2019-1-3 08:36:52

人造人 发表于 2018-12-28 13:04
vs2017

好的,谢谢
页: [1]
查看完整版本: 关于高级宏定义的问题