c语言中的宏定义

普通函数

        #include <stdio.h>
        
        int sq_int(int x)
        {
            return x*x;
        }
        
        double sq_double(double x)
        {
            return x*x;
        }
        
        int main()
        {
            int n = 9;
            double x = 4.5;
            
            printf("%d的平方是:%d\n",n,sq_int(n));
            printf("%lf的平方是:%lf\n",x,sq_double(x));
            
            return 0;
   }

        对于上面的sq_int和sq_double来说,这两个函数的功能相似,如果求其它数据类型的平方根还需要添加对应类型的函数,代码比较冗余。

宏函数

        #include <stdio.h>
        
        #define sq(x) ((x)*(x))
        
        int main()
        {
            int n = 9;
            double x = 4.5;
            
            printf("%d的平方是:%d\n",n,sq(n));
            printf("%lf的平方是:%lf\n",x,sq(x));
            
            return 0;
        }

  宏函数会把相应位置的代码做替换。比如说sq(n)会被替换成((n)*(n))。

  • 这种替换发生在编译的时候。这样就通过一个宏函数实现了原来多个函数的功能。
  • 宏函数不会去做具体的运算,仅作替换。
  • 宏函数省略了参数传递、函数调用和函数返回等操作,所以相对于普通函数来说运行速度提高了。
  • 宏函数也可以不加参数。

宏函数与逗号表达式

        #include <stdio.h>
        #define puts_alert(str)  {putchar('\a');puts(str);}
        
        int main()
        {
            int n;
            printf("请输入一个整数:");
            scanf("%d",&n);
            
            if(n)
                puts_alert("这个数不是0.");
            else
                puts_alert("这个数是0.");
            
            return 0;
        }
       

  上述代码经过宏替换之后变成:

        if(n)
            {putchar('\a');puts("这个数不是0.");};
        else
            {putchar('\a');puts("这个数是0.");};
      

  可以发现有多余的分号,导致代码报错。

  解决方法是利用逗号表达式。
          #define puts_alert(str)  (putchar('\a'),puts(str))
       经过宏替换之后变成:
          if(n)
            (putchar('\a'),puts(str));
        else
            (putchar('\a'),puts(str));

        这样整个逗号表达式的值都会被计算到。

 

宏的副作用

        要记住宏仅做替换,不做运算。宏的副作用都来源于替换操作。

  • 例一:

            #define sq(a) ((a)*(a))
            当调用sq(a++)的时候,原则上是希望a先求完平方之后再自增。但是宏替换的结果是((a++)*(a++)),这样a就自增了两次。

  • 例二:

            #define sq (a) ((a)*(a))
            当这样在sq和(a)之前多敲一个空格,这时就是普通的宏定义了,sq会被替换成(a) ((a)*(a))。

  • 例三:

            #define sum(x,y) x + y
      z = sum(a,b)*sum(c,d)
            上述sum被替换之后就变成了z = a+b*c+d,就会先算乘法后算加法。所以要把宏函数整个用括号括起来。

 

参考

https://blog.csdn.net/wit_732/article/details/106602503

posted @ 2023-01-24 10:18  bitcuoo  阅读(187)  评论(0编辑  收藏  举报