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 小时前
华为 HCIE 大数据认证中 Linux 命令行的运用及价值
大数据·linux·运维·华为·华为认证·hcie·it
PAK向日葵1 小时前
【算法导论】PDD 0817笔试题题解
算法·面试
wuicer3 小时前
ubuntu 20.04 安装anaconda以及安装spyder
linux·运维·ubuntu
地平线开发者3 小时前
ReID/OSNet 算法模型量化转换实践
算法·自动驾驶
地平线开发者4 小时前
开发者说|EmbodiedGen:为具身智能打造可交互3D世界生成引擎
算法·自动驾驶
cui__OaO5 小时前
Linux软件编程--线程
linux·开发语言·线程·互斥锁·死锁·信号量·嵌入式学习
星星火柴9365 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头5 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
小晶晶京京5 小时前
day34-LNMP详解
linux·运维·服务器
画个太阳作晴天5 小时前
A12预装app
linux·服务器·前端