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.宏函数的优点,以空间换时间。

相关推荐
牢七13 小时前
新linux
linux
HIT_Weston16 小时前
27、【Ubuntu】【远程开发】内网穿透:CA 签名
linux·运维·ubuntu
大胆飞猪16 小时前
递归、剪枝、回溯算法---全排列、子集问题(力扣.46,78)
算法·leetcode·剪枝
阿巴~阿巴~16 小时前
基于UDP协议的英汉翻译服务系统:从网络通信到字典查询的完整机制
linux·服务器·网络·网络协议·udp协议·套接字绑定·英汉翻译服务系统
阿巴~阿巴~16 小时前
简易回声服务器实现与网络测试指南
linux·服务器·网络·udp协议·网络测试·udp套接字编程
Aldrich_3218 小时前
蓝桥杯嵌入式赛道—-软件篇(GPIO输出模式配置)
c语言·vscode·stm32·单片机·嵌入式硬件·蓝桥杯
Kisorge18 小时前
【电机控制】基于STM32F103C8T6的二轮平衡车设计——LQR线性二次线控制器(算法篇)
stm32·嵌入式硬件·算法
@卞19 小时前
C语言常见概念
c语言·开发语言
铭哥的编程日记19 小时前
深入浅出蓝桥杯:算法基础概念与实战应用(二)基础算法(下)
算法·职场和发展·蓝桥杯
Swift社区19 小时前
LeetCode 421 - 数组中两个数的最大异或值
算法·leetcode·职场和发展