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 小时前
【Leetcode 热题 100】208. 实现 Trie (前缀树)
数据结构·算法·leetcode
小王爱吃月亮糖2 小时前
C++的23种设计模式
开发语言·c++·qt·算法·设计模式·ecmascript
007php0073 小时前
linux服务器上CentOS的yum和Ubuntu包管理工具apt区别与使用实战
linux·运维·服务器·ubuntu·centos·php·ai编程
djykkkkkk3 小时前
ubuntu编译遇到的问题
linux·运维·ubuntu
qq_429856573 小时前
linux 查看服务是否开机自启动
linux·运维·服务器
就爱学编程4 小时前
重生之我在异世界学编程之C语言:数据在内存中的存储篇(下)
java·服务器·c语言
IT猿手4 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解LRMOP1-LRMOP6及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·算法·matlab·智能优化算法·多目标算法
落羽的落羽4 小时前
【落羽的落羽 C语言篇】动态内存管理·下
c语言
7yewh5 小时前
Linux驱动开发 IIC I2C驱动 编写APP访问EEPROM AT24C02
linux·arm开发·驱动开发·嵌入式硬件·嵌入式
InfiSight智睿视界5 小时前
AI 技术,让洗护行业焕然「衣」新
人工智能·算法