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

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

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

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

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

说明 :

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

代码演示:

c 复制代码
#include<stdio.h>

#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;
}

结果显示:

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

说明:

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

代码演示:

c 复制代码
#include<stdio.h>

#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;
}

结果显示:

3. 宏的嵌套 :

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

c 复制代码
#define F(f) f(args)
#define args a,b

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

代码演示:

c 复制代码
#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;
}

结果显示:

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

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

代码演示:

c 复制代码
/*  '\' 表示续航符,表明这一行还没有结束   */

#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;
}

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

c 复制代码
do {     

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

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

代码演示:

c 复制代码
#ifndef _TOOLS_H     /* tools.h   头文件的名称   */
#ifdef  _TOOLS_H

//头文件内容

#endif //  _TOOLS_H
6 . 宏和函数的区别
  • 函数调用时,先求出实参表达式的值,然后带入形参, 带参数的宏只是进行简单的字符替换.
  • 函数调用是在程序运行时处理,分配临时内存, 而宏展开(函函数),是在编译时进行的,展开时是不分配内存,也没有返回值,也没 有值传递.
  • 宏的参数没有类型 ,只是一个符号 ,展开时带入到指定的字符串中.
  • 使用宏的次数多时, 宏展开后源程序变长 ,函数调用不会使源程序变长.
  • 宏替换只会占用编译时间 ,不会占用运行时间,而函数调用占用的是运行时间(分配内存 ,传递参数 ,执行函数体).
    时进行的,展开时是不分配内存,也没有返回值,也没有值传递.
  • 宏的参数没有类型 ,只是一个符号 ,展开时带入到指定的字符串中.
  • 使用宏的次数多时, 宏展开后源程序变长 ,函数调用不会使源程序变长.
  • 宏替换只会占用编译时间 ,不会占用运行时间,而函数调用占用的是运行时间(分配内存 ,传递参数 ,执行函数体).
相关推荐
朝朝辞暮i29 分钟前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
小师兄吃牛肉1 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记2 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
炸膛坦客2 小时前
单片机开发工具篇:(十四)配置输出 .map 文件及其本地路径
c语言·单片机·嵌入式硬件
言乐62 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
weixin_307779132 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
kakakahahahaha2 小时前
Windows C盘临时文件清理:%temp%、Windows Temp、Prefetch、Windows.old与hiberfil.sys处理指南
c语言·开发语言·windows
朝朝辞暮i3 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
朝朝辞暮i3 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
笨笨饿3 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网