赞
踩
宏,在我看来是一个C语言中的一大特色,在此基础上可以使用一些特殊的功能。
在一些运用场景下,我们常常要用到类似于二者求最大、最小值,常常将这样的简单的一个功能封装为一个方法函数,但在函数的语法中,要明确定义参数的变量类型,也就是不同类型的变量需要建立相对不同的函数,但我们使用一些特殊的手段,就可以用宏实现不定类型的带参宏。见如下例子:
#define max(x,y)({\
typeof(x) _x = (x);\
typeof(y) _y = (y);\
(void)(&_x == &_y);\
_x > _y? _x:_y;})
没错就是这样一个带参宏就可以实现,任意变量类型求最大值的功能。
typeof:获取一个变量的变量类型。
(void)(&_x == &_y):这一句代码仅仅用来提醒用户两个变量类型是否一致。
__x > _y? _x:_y;:返回最后的结果。
### 2.1可变参数的简单使用
对于可变参数,我们其实很熟悉,但你可能还不知道。大家还记得一开始学习C语言的时候敲的第一行代码吗?没错就是
printf("hallo wolrd!")
其实printf函数就是使用可变参数实现的,我们看一个例子:
printf(char *fmt,...); //这是printf函数的原型
int count = 10;
char sex = 'L';
printf("%d,%c",count,sex);
- fmt : 格式字符串。
- . . . :对应多个参数。
实现可变参数需要添加头文件stdarg.h
下面使用一个经典而又简单的例子来看一下用法。
#include <stdarg.h> void printArray(int count,...) { char var; int gap,i; /*创建了一个指向参数的指针*/ va_list args; /*初始化指针*/ va_start(args,count); /*对不定参数进行解析*/ for( i = 0 ; i < count ; i++) { printf("*args %d = %d\n",count,*(int*)args); gap = (int)(sizeof(count)/sizeof(var)); //获取指针应该跳过的字节数 args += gap; } /*使用完成后释放指针为NULL*/ va_end(args); } void main(void) { printArray(4,1,2,3,4); printArray(5,1,2,3,4,5); }
最终我们可以看到后面的参数一个个被打印出来
我们在写程序的时候,常常需要打印一些日志。不同的情况下需要打印不同的东西,所以我们常常会有一个调试的模块,下面是使用不定参数实现的一个简单的调式模块程序,如下:
#include <stdarg.h> #include <stdio.h> /* 用户需要配置的地方 */ #define USER_DEBUG_LEVEL 3 /* ERROR:错误等级的日志 WARNIG:警告等级的日志 DEBUG:调式等级的日志 */ #if USER_DEBUG_LEVEL>=3 #define ERROR #endif #if USER_DEBUG_LEVEL >= 2 #define WARNING #endif #if USER_DEBUG_LEVEL >= 1 #define DEBUG #endif void printfError(char* fmt ,...) { va_list args; va_start(args,fmt); #ifdef ERROR vprintf(fmt,args); #endif va_end(args); } void printfWarning(char* fmt ,...) { va_list args; va_start(args,fmt); #ifdef WARNING vprintf(fmt,args); #endif va_end(args); } void printfDebug(char* fmt ,...) { va_list args; va_start(args,fmt); #ifdef DEBUG vprintf(fmt,args); #endif va_end(args); } void main(void) { printfError("Error\n"); printfWarning("Warning\n"); printfDebug("Debug\n"); }
不同的调试等级对应了不同的打印数据,可用于调试。
内联函数是在编译后将函数体中的内容填充到函数调用的地方,而在运行的时候不用调用函数本身,而是直接执行函数体内的语句。但声明为内联函数,最终是否是内联函数是不确定的。
来看一个简单的例子,如下:
inline int sum(int a ,int b)
{
return a + b;
}
void main(void)
{
printf("sum = %d",sum(5,6));
}
返回结果一目了然,在普通函数中是调用sum()函数,然后返回。而内联函数是将 a+b 填充到了函数名的位置如下,形参作用周期在函数语句运行器件。
内联如下:
inline int sum(int a ,int b)
{
return a + b;
}
void main(void)
{
{
int a = 5,b = 6;
printf("sum = %d",a + b);
}
}
函数体本身替代原有函数调用的地方。
关注公众号,获取本文的代码以及单片机调试中的一些工具
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。