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