C语言在GCC编译器下为了表示宏定义中的不定长参数,引入了两个宏##__VA_ARGS__和__VA_ARGS__,实际开发生产中,很多人区分不清其中区别和使用场景,今天小编就抛砖引玉,进行相关说明。
1.C语言不定长参数使用
C语言中,没有函数重载,所以同一个函数名而参数不同时,就需要使用不定长参数,不定长参数使用...表示,而处理不定长参数需要用到特殊的数据结构va_list,具体演示代码如下:
#include <cstdarg>
#include <iostream>
using namespace std;
void hesy_print(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char buffer[1024] = {0};
int temp_size = vsnprintf(buffer, 1024 - 1, fmt, args);
va_end(args);
std::cout << buffer << " " << temp_size << std::endl;
}
int main() {
hesy_print("hello world");
hesy_print("hello %s, today is %d 年 %d 月 %d日", "hesy", 2022, 11, 8);
return 0;
}
运行结果如下:
2.宏替换的方式调用不定长参数函数
2.1__VA_ARGS__的使用
情况一:一个固定参数和一个不定长参数
#include <cstdarg>
#include <iostream>
using namespace std;
void hesy_print(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char buffer[1024] = {0};
int temp_size = vsnprintf(buffer, 1024 - 1, fmt, args);
va_end(args);
std::cout << buffer << " " << temp_size << std::endl;
}
#define MY_PRINT(fmt, ...) hesy_print(fmt, __VA_ARGS__)
int main() {
MY_PRINT("hesy");
return 0;
}
报错如下:
从报错信息看,一个参数编译器回报错,当使用__VA_ARGS__代表不定长参数时候,必须得有一个参数来替代__VA_ARGS__,否则报错
正常情况如下:
#include <cstdarg>
#include <iostream>
using namespace std;
void hesy_print(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char buffer[1024] = {0};
int temp_size = vsnprintf(buffer, 1024 - 1, fmt, args);
va_end(args);
std::cout << buffer << " " << temp_size << std::endl;
}
#define MY_PRINT(fmt, ...) hesy_print(fmt, __VA_ARGS__)
int main() {
MY_PRINT("hello %s, %d + %d = %d", "andy", 10, 5, 15);
return 0;
}
运行结果如下:
情况二:一个不定长参数
#include <cstdarg>
#include <iostream>
using namespace std;
void hesy_print(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char buffer[1024] = {0};
int temp_size = vsnprintf(buffer, 1024 - 1, fmt, args);
va_end(args);
std::cout << buffer << " " << temp_size << std::endl;
}
#define MY_PRINT(...) hesy_print(__VA_ARGS__)
int main() {
MY_PRINT("andy andy");
MY_PRINT("hello %s, %d + %d = %d", "andy", 10, 5, 15);
return 0;
}
运行结果如下:
2.2##__VA_ARGS__的使用
情况一:一个固定参数和一个不定长参数
#include <cstdarg>
#include <iostream>
using namespace std;
void hesy_print(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char buffer[1024] = {0};
int temp_size = vsnprintf(buffer, 1024 - 1, fmt, args);
va_end(args);
std::cout << buffer << " " << temp_size << std::endl;
}
#define MY_PRINT(fmt, ...) hesy_print(fmt, ##__VA_ARGS__)
int main() {
MY_PRINT("andy andy");
MY_PRINT("hello %s, %d + %d = %d", "andy", 10, 5, 15);
return 0;
}
运行结果如下:
情况二:一个不定长参数
#include <cstdarg>
#include <iostream>
using namespace std;
void hesy_print(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char buffer[1024] = {0};
int temp_size = vsnprintf(buffer, 1024 - 1, fmt, args);
va_end(args);
std::cout << buffer << " " << temp_size << std::endl;
}
#define MY_PRINT(...) hesy_print(##__VA_ARGS__)
int main() {
MY_PRINT("andy andy");
MY_PRINT("hello %s, %d + %d = %d", "andy", 10, 5, 15);
return 0;
}
编译报如下错误信息:
由此可见,##__VA_ARGS__必须搭配固定参数使用,__VA_ARGS__可以单独使用。同时,在搭配固定参数使用时候,__VA_ARGS__在使用时候,除固定参数外,还必须要有一个可变参数,##__VA_ARGS__使用时,除了固定参数外,可以不包含任何可变参数。