GCC编译器下C语言不定长参数宏##__VA_ARGS__和__VA_ARGS__的使用

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__使用时,除了固定参数外,可以不包含任何可变参数。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值