7.C语言 宏(Macro) 宏定义,宏函数

目录

宏定义

宏函数

1.注释事项

2.注意事项

宏(Macro)用法

常量定义

简单函数实现

类型检查

条件编译

宏函数计算参数个数

宏定义进行类型转换

宏定义进行位操作

宏定义进行断言

总结


宏定义

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MAX 1025 //定义宏

int main() 
{

	system("pause");
	return EXIT_SUCCESS;
}

宏函数

宏函数通常将一些比较频繁,短小的函数封装为宏函数。减少一些入栈,出栈的时间消耗。

在C语言中,宏(Macro)是预处理器的一种功能,它允许你定义一种简写形式来代替一段特定的代码。宏定义的基本形式如下:

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MYADD(x,y) x + y //宏函数

int main() 
{
	int a = 10;
	int b = 20;

	printf("a+b = %d\n",MYADD(a,b));
	system("pause");
	return EXIT_SUCCESS;
}

运行结果:

宏函数在预处理中做了一个替换 就是将 a 和 b替换成x和y。

宏函数是使用宏定义的函数风格的宏。它们可以像普通函数那样调用,但最终会被预处理器替换成相应的代码,减少入栈,出栈的时间。

1.注释事项

宏函数要保证运算的完整性才能执行,可以查看下面代码处理流程

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MYADD(x,y) x + y //宏函数

int main() 
{
	int a = 10;
	int b = 20;

	int result = MYADD(a, b) * 10;
	printf("result = %d\n", result);
	system("pause");
	return EXIT_SUCCESS;
}

打印结果

从上面结果来看,10 + 20 * 10 结果是等于300才符合我们预期,这个是运算完整性导致的。就是先乘除后加减问题

这个问题是可以解决的,通过()来处理,

复制代码
#define MYADD(x,y) ((x) + (y)) //宏函数

2.注意事项

宏函数在一定的程度上会比普通的函数效率高

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MYADD(x,y) ((x) + (y)) //宏函数

void myAdd(int x,int y) { //x会在栈上定义,y也会 . 所以宏函数会有一定优势
	return x + y;
}

int main() 
{
	int a = 10;
	int b = 20;

	int result = MYADD(a, b) * 10;
	printf("result = %d\n", result);
	system("pause");
	return EXIT_SUCCESS;
}

可以从宏函数,和普通函数对比,一个没有栈的开销,一个有开销。

普通函数会有入栈和出栈时间上的开销

宏(Macro)用法

常量定义

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MAX 1024

int main() 
{

	printf("MAX = %d\n", MAX);
	system("pause");
	return EXIT_SUCCESS;
}

运行结果

有参数宏

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MYADD(x,y) ((x) + (y)) //宏函数


int main() 
{
	int a = 10;
	int b = 20;

	int result = MYADD(a, b);
	printf("result = %d\n", result);

	system("pause");
	return EXIT_SUCCESS;
}

运行结果:

宏运算链接符

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MAX 100
#define ROW 100
#define GET_MAX(x,y) \
x = x+y;\
y = x+y;

int main() 
{
	int a = 10;
	int b = 10;

	GET_MAX(a, b)

	printf("random %d  %d\n\n", a,b);
	system("pause");
	return EXIT_SUCCESS;
}

从上面代码来看\表示链接符号,运行完第一个,就执行第二个

无参数宏

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define MAX 100
#define ROW 100
#define RANDOM (-1.0 + 2.0*(double)rand() / RAND_MAX)

int main() 
{
	int v = 10;
	printf("random %lf\n\n",RANDOM);
	system("pause");
	return EXIT_SUCCESS;
}

类型检查

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define CHECK_TYPE(a) generic((a), \
    int: printf("int"), \
    char: printf("char"), \
    float: printf("float"), \
    default: printf("other type") \
)

int main() 
{

	int v = 10;

	//CHECK_TYPE(v);
	printf("%s", _Generic(v));

	system("pause");
	return EXIT_SUCCESS;
}

条件编译

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#define DEBUG

#ifdef DEBUG
#define PRINT_DEBUG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define PRINT_DEBUG(fmt, ...)
#endif

int main() 
{

	int v = 10;

	char value[] = "达帮主";

	PRINT_DEBUG("%s\n",value);

	system("pause");
	return EXIT_SUCCESS;
}

运行结果:

如果删掉define就不会有打印

宏函数计算参数个数

复制代码
#define GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME
#define VA_SIZE(...) \
    GET_MACRO(__VA_ARGS__, 4, 3, 2, 1, 0)
 
#define SHOW_PARAM_COUNT(...) \
    printf("Number of parameters: %d\n", VA_SIZE(__VA_ARGS__))
 
// 使用
SHOW_PARAM_COUNT(1, 2); // 输出:Number of parameters: 2

宏定义进行类型转换

复制代码
#define CONTAINER_OF(ptr, type, member) \
    ((type *)((char *)(ptr) - (char *) &((type *)0)->member))

宏定义进行位操作

复制代码
#define SET_BIT(x, bit) ((x) |= (1 << (bit)))
#define CLEAR_BIT(x, bit) ((x) &= ~(1 << (bit)))
#define FLIP_BIT(x, bit) ((x) ^= (1 << (bit)))
#define GET_BIT(x, bit) (((x) >> (bit)) & 1)

宏定义进行断言

复制代码
#define ASSERT(expr) \
    if (!(expr)) { \
        printf("Assertion failed: %s\n", #expr); \
        exit(1); \
    }

总结

1.宏函数要保证运算的完整性。

2.宏函数在一定程度上,会比普通函数效率高,普通函数会有入栈和出栈时间上的开销。

3.通常会吧调用频繁的,短小的函数封装为宏函数。

4.宏函数的优点,以空间换时间。

相关推荐
代码小将1 小时前
Leetcode209做题笔记
java·笔记·算法
Musennn2 小时前
leetcode 15.三数之和 思路分析
算法·leetcode·职场和发展
不知几秋3 小时前
数字取证-内存取证(volatility)
java·linux·前端
CM莫问4 小时前
<论文>(微软)避免推荐域外物品:基于LLM的受限生成式推荐
人工智能·算法·大模型·推荐算法·受限生成
康谋自动驾驶5 小时前
康谋分享 | 自动驾驶仿真进入“标准时代”:aiSim全面对接ASAM OpenX
人工智能·科技·算法·机器学习·自动驾驶·汽车
欧先生^_^6 小时前
Linux内核可配置的参数
linux·服务器·数据库
C++ 老炮儿的技术栈6 小时前
什么是函数重载?为什么 C 不支持函数重载,而 C++能支持函数重载?
c语言·开发语言·c++·qt·算法
inputA6 小时前
【LwIP源码学习6】UDP部分源码分析
c语言·stm32·单片机·嵌入式硬件·网络协议·学习·udp
海尔辛6 小时前
学习黑客5 分钟读懂Linux Permissions 101
linux·学习·安全
yychen_java7 小时前
R-tree详解
java·算法·r-tree