1. #用来把参数转换成字符串
#define P(A) printf("%s:%d\n",#A,A);
#define SQUARE(x) printf("The square of "#x" is %d.\n", ((x)*(x)));
2. ##运算符可以用于宏函数的替换部分。这个运算符把两个语言符号组合成单个语言符号
3. __VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。
实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。
4. ##__VA_ARGS__ 宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错
举例:
#define my_print1(...) printf(__VA_ARGS__)
#define my_print2(fmt,...) printf(fmt,__VA_ARGS__)
#define my_print3(fmt,...) printf(fmt,##__VA_ARGS__)
5.
C语言printf家族函数的成员:
#include stdio.h
int printf(const char *format, ...); //输出到标准输出
int fprintf(FILE *stream, const char *format, ...); //输出到文件
int sprintf(char *str, const char *format, ...); //输出到字符串str中
int snprintf(char *str, size_t size, const char *format, ...);
//按size大小输出到字符串str中
以下函数功能与上面的一一对应相同,只是在函数调用时,把上面的...对应的一个个变量用va_list调用所替代。在函数调用前ap要通过va_start()宏来动态获取。
#include stdarg
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
// 函数add() 计算可选参数之和
// 参数:第一个强制参数指定了可选参数的数量,可选参数为double类型
double add( int n, ... )
{
int i = 0;
double sum = 0.0;
va_list argptr;
va_start( argptr, n ); // 初始化argptr
for ( i = 0; i < n; ++i ) // 对每个可选参数,读取类型为double的参数,
sum += va_arg( argptr, double ); // 然后累加到sum中
va_end( argptr );
return sum;
}
//里有vsnprintf整合可变参数为字符串
void stdio_printf(const char* fmt, ...)
{
uint16_t len, i;
va_list ap;
char buffer[256];
va_start(ap, fmt);
len = vsnprintf(buffer, sizeof(buffer), (const char*)fmt, ap);
va_end(ap);
uart_send(buffer, len);
}