首页 > 其他分享 >c语言中的宏定义

c语言中的宏定义

时间:2023-01-24 10:33:56浏览次数:54  
标签:语言 putchar 函数 puts int double sq 定义

普通函数

        #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

标签:语言,putchar,函数,puts,int,double,sq,定义
From: https://www.cnblogs.com/bitcuoo/p/17065892.html

相关文章

  • C语言:二维字符数组
    #include<stdio.h>main(){chara[3][10]={"beijing","shanghai","tianjin"},*pa=a[0];printf("%s\n",*(a+1));printf("%s\n",a+1);printf("%s\n",......
  • 新人入门编程如何选择编程语言
    新人入门编程选择编程语言时,应该考虑以下几点:易学性:选择易于学习和理解的编程语言,可以让新人更快地入门。应用领域:根据自己的兴趣和未来发展规划来选择适合自己的编程语言......
  • vue:v-model (原生组件与自定义组件)
    vue2:原生组件 vue2:自定义组件 vue3:自定义组件vue3更改了vue2声明自定义组件的方式,将vue2中的value替换成了modelValue,将emit触发的事件名改为'update:model......
  • 自定义类型转换
    自定义类之间的类型转换是通过构建构造函数的多态来进行的 在对象刚刚定义时,即使你使用的是赋值操作符=,也是会调用构造函数,而不是重载的operator=运算符.用类型转......
  • arcgis api for 自定义zoom
    1.需求自定义UI,实现对地图的zoom操作,在view缩放的时候,带动画效果2.分析问题UI视图一般情况,可能大部分初学者会使用以下代码对zoom进行操作,这个方法是可以放大缩小,但是动画是......
  • 【算法-链表】Go语言实现
    0、go语言自定义链表节点typeNodestruct{ Dataint Next*Node}typeDoubleNodestruct{ Dataint Next*DoubleNode Pre*DoubleNode}1、单链表反转......
  • Python语言基础—集合的常见操作方法
    希望本阶段内容可以帮助大家学好Python基础,详情可以关注上方Python专栏!文章目录​​系列文章目录​​​​一、创建集合​​​​二、集合常见操作方法​​​​2.1增加数据​......
  • Python语言基础—列表的常用操作
    希望本阶段内容可以帮助大家学好Python基础,详情可以关注上方Python专栏!文章目录​​系列文章目录​​​​一、列表的应用场景​​​​二、列表的格式​​​​三、列表的常用......
  • 汇编语言 str 指令
    汇编str指令,将值写到某个地址。 示例:1/*汇编点亮一个LED灯*/23.text4.global_start56_start:7ldrr1,=0x560000508ldrr0,=......
  • 汇编语言 halt 命令
    汇编halt命令,是一条重复执行指定标号的循环命令。处理器暂停,直到出现中断或复位信号才继续 1/*汇编点亮一个LED灯*/23.text4.global_start56......