• C语言大佬的必杀技---宏的高级用法


    C语言大佬的必杀技—宏的高级用法

    目录:
    • 字符串化
    • 标记的拼接
    • 宏的嵌套
    • 替换多条语句
    • 防止一个文件被重复包含
    • 宏和函数的区别

    可能大家在学习的时候用得比较少,但是在一些代码量比较大的时候,这样使用,可以大大的提高代码的可读性,方便我们后期维护

    1、字符串化 -------( 打印变量的值和格式化字符串 ):
    #define test(x,format) printf(#x "= %" #format "\n", x)
    
    • 1

    说明 :

    1. #x 在宏定义中被称为字符串化操作符,它将 x 参数转换为一个字符串,并在代码中插入。
    2. "= %" 是一个字符串,用于指定输出的格式。
    3. #format 也是字符串化操作符,将 format 参数转换为一个字符串,并在代码中插入。
    4. 整个宏的作用就是 : 可以用于打印变量的值和格式化字符串。

    代码演示:

    #include
    
    #define test(x,format) printf(#x "= %" #format "\n", x)
    
    int main() {
    	const char* name = "wxf";
    	test(name,s);            //s       相当于 %s
    
    	int i = 1;
    	test(i, d);      //d   相当于%d
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果显示:
    在这里插入图片描述

    2. 标记的拼接---------(将宏参数进行字符串化和连接操作) :
    #define test(x,format) printf(#x "= %" #format "\n", x)
     #define test2(i) test(age ## i,d)       //d  相当于%d   当然这里可以替换成其他的类型
    
    • 1
    • 2

    说明:

    在该宏的扩展部分,它将 agei 进行连接操作(使用 ## 连接运算符),形成一个新的标识符,并作为参数传递给 test 宏。

    代码演示:

    #include
    
    #define test(x,format) printf(#x "= %" #format "\n", x)
    #define test2(i) test(age ## i,d)       //d  相当于%d   当然这里可以替换成其他的类型
    
    int main() {
    	
    	int age1 = 21,age2=22;
    	test2(1);
    	test2(2);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果显示:
    在这里插入图片描述

    3. 宏的嵌套 :

    宏的嵌套是我们常用的 , 话不多说,我们直接看例子

    #define F(f) f(args)
    #define args a,b
    
    • 1
    • 2

    说明: 第一个宏里面的f ,替换成f(args), 然后下一个宏,将args ,替换成 a, b 。两者嵌套

    代码演示:

    #define F(f) f(args)
    #define args a,b
    
    void test3(int number1, int number2) {
    	printf(" %d + %d= %d\n ", number1, number2 , number1+ number2 );
    }
    
    int main() {
    	
    	int a = 21,b=22;
    	F(test3);
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    结果显示:
    在这里插入图片描述

    4. 替换多条语句:
    #define YUE_HUIU(name) do {                           \   
         printf("%s ,我们一起去看电影把!\n , name);       \
         printf("%s, 我们一起去唱歌吧!\n ", name);      \
         printf("%s, 我们一起回家吧!\n", name);          \
    }while (0);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意: 使用了 do...while(0) 结构来创建一个匿名的代码块,目的是为了让宏展开后能够正常使用分号进行语句结束。这种技巧可以避免在使用宏时造成错误的语法解析。

    代码演示:

    /*  '\' 表示续航符,表明这一行还没有结束   */
    
    #define YUE_HUIU(name) do {                           \   
         printf("%s ,我们一起去看电影把!\n , name);       \
         printf("%s, 我们一起去唱歌吧!\n ", name);      \
         printf("%s, 我们一起回家吧!\n", name);          \
    }while (0);
    
    int main() {
    
        YUE_HUI("wxf");
         
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    结果显示—(宏展开后的样子):

    do {printf("%s ,我们一起去看电影把!\n , "wxf");     
         printf("%s,我们一起去唱歌吧!\n ", "wxf");         
        printf("%s, 我们一起回家吧!\n", "wxf"); 
        } while (0);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    5. 防止头文件被重复包含

    这个用法还是经常会用到的 ,我们经常会使用到一些自己定义的 头文件

    代码演示:

    #ifndef _TOOLS_H     /* tools.h   头文件的名称   */
    #ifdef  _TOOLS_H
    
    //头文件内容
    
    #endif //  _TOOLS_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    6 . 宏和函数的区别
    • 函数调用时,先求出实参表达式的值,然后带入形参, 带参数的宏只是进行简单的字符替换.
    • 函数调用是在程序运行时处理,分配临时内存, 而宏展开(函函数),是在编译时进行的,展开时是不分配内存,也没有返回值,也没 有值传递.
    • 宏的参数没有类型 ,只是一个符号 ,展开时带入到指定的字符串中.
    • 使用宏的次数多时, 宏展开后源程序变长 ,函数调用不会使源程序变长.
    • 宏替换只会占用编译时间 ,不会占用运行时间,而函数调用占用的是运行时间(分配内存 ,传递参数 ,执行函数体).
      时进行的,展开时是不分配内存,也没有返回值,也没有值传递.
    • 宏的参数没有类型 ,只是一个符号 ,展开时带入到指定的字符串中.
    • 使用宏的次数多时, 宏展开后源程序变长 ,函数调用不会使源程序变长.
    • 宏替换只会占用编译时间 ,不会占用运行时间,而函数调用占用的是运行时间(分配内存 ,传递参数 ,执行函数体).
  • 相关阅读:
    深度学习基础知识 register_buffer 与 register_parameter用法分析
    WebScoket
    什么是.NET的极限优化数值库?
    【历史上的今天】6 月 24 日:网易成立;首届消费电子展召开;世界上第一次网络直播
    力扣—最长回文子串
    rabbitmq知识梳理
    多目标应用:基于非支配排序的鲸鱼优化算法NSWOA求解微电网多目标优化调度(MATLAB代码)
    Maven
    java 网络编程Socket
    微信小程序_8,视图与逻辑
  • 原文地址:https://blog.csdn.net/qq_62989250/article/details/133212377