龙空技术网

C 语言的带有默认参数函数和不定参数函数的一种实现

编程黑科技 241

前言:

当前兄弟们对“c语言中和有什么区别”大概比较注重,你们都需要剖析一些“c语言中和有什么区别”的相关知识。那么小编在网络上搜集了一些关于“c语言中和有什么区别””的相关知识,希望兄弟们能喜欢,姐妹们快快来学习一下吧!

C 语言中的语法默认上是不支持函数的默认形参,通过__VA_ARGS__宏的机制包装实现类似的机制(目前仅限于学习,业务不建议使用,意义不大)。

关于不定参数函数,C 语言默认支持是有的,比如 printf(), scanf() 等函数都是例子,但是它们都不支持 0 个参数。通过自己的思考,可通过__VA_ARGS__, #__VA_ARGS__, ##__VA_ARGS__ 宏的机制扩展支持 0 个参数的场景。

以上描述的情况的代码示例如下:

// 文件名:variable_para.c#include <stdio.h>#include <stdarg.h>// 该方式计算函数参数个数,会有一个最大数限制,以下的版本是最多 64 个参数// 如果要修改限制可以修改ARG_N_M及ARG_N_RESQ对应的参数及数据个数#define ARG_N(...) ARG_N_(0, ##__VA_ARGS__, ARG_N_RESQ)#define ARG_N_(...) ARG_N_M(__VA_ARGS__)#define ARG_N_M(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10,      \                _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \                _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \                _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \                _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \                _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \                _61, _62, _63, N, ...) N#define ARG_N_RESQ 63, 62, 61, 60,                         \                   59, 58, 57, 56, 55, 54, 53, 52, 51, 50, \                   49, 48, 47, 46, 45, 44, 43, 42, 41, 40, \                   39, 38, 37, 36, 35, 34, 33, 32, 31, 30, \                   29, 28, 27, 26, 25, 24, 23, 22, 21, 20, \                   19, 18, 17, 16, 15, 14, 13, 12, 11, 10, \                   9, 8, 7, 6, 5, 4, 3, 2, 1, 0#define INFO(...) myinfo(ARG_N(__VA_ARGS__), ##__VA_ARGS__)// 目标函数int info(int a, char *b, int c, int d){    printf("a: %d b: %s c: %d d: %d\n", a, b, c, d);}// 适配函数, 通过传入的参数的个数不同,来补充参数#define ARG_1 0#define ARG_2 "test"#define ARG_3 2#define ARG_4 3int myinfo(int argc, ...){    int a = ARG_1;    char *b = ARG_2;    int c = ARG_3;    int d = ARG_4;    va_list argptr;    va_start(argptr, argc);    if (argc >= 4)    {        // 如果提供过多参数,则自动忽略        a = va_arg(argptr, int);        b = va_arg(argptr, char *);        c = va_arg(argptr, int);        d = va_arg(argptr, int);    }    else if (argc == 3)    {        a = va_arg(argptr, int);        b = va_arg(argptr, char *);        c = va_arg(argptr, int);    }    else if (argc == 2)    {        a = va_arg(argptr, int);        b = va_arg(argptr, char *);    }    else if (argc == 1)    {        a = va_arg(argptr, int);    }    va_end(argptr);    return info(a, b, c, d);}#define DEFAULT_DEBUG "This is default debug (%s:%u)\n", __FILE__, __LINE__#define DEBUG(...) #__VA_ARGS__[0] ? myprintf(#__VA_ARGS__, ##__VA_ARGS__) : myprintf(#__VA_ARGS__, DEFAULT_DEBUG)int myprintf(const char *flag, ...){    int cnt;    va_list argptr;    va_start(argptr, flag);    char *format = va_arg(argptr, char *);    cnt = vprintf(format, argptr);    va_end(argptr);    return cnt;}int main(int argc, char const *argv[]){    INFO();    INFO(10);    INFO(10, "info");    INFO(10, "info", 8);    INFO(10, "info", 8, 7);    INFO(10, "info", 8, 7, 6);    DEBUG();    DEBUG("%d\n", ARG_N(1, 2));    DEBUG("%d\n", 123);    DEBUG("%d %s %f\n", 123, "test", 1.2);    DEBUG("%d %s %f %x\n", 123, "test", 1.2, 0x1234);    DEBUG("%d %s %f %x %c\n", 123, "test", 1.2, 0x1234, 78);    DEBUG("%d %s %f %x %c %p\n", 123, "test", 1.2, 0x1234, 78, 56789);    return 0;}

编译及执行指令如下:

gcc variable_para.c -o variable_para && ./variable_para 

执行结果如下:

a: 0 b: test c: 2 d: 3a: 10 b: test c: 2 d: 3a: 10 b: info c: 2 d: 3a: 10 b: info c: 8 d: 3a: 10 b: info c: 8 d: 7a: 10 b: info c: 8 d: 7This is default debug (variable_para.c:100)2123123 test 1.200000123 test 1.200000 1234123 test 1.200000 1234 N123 test 1.200000 1234 N 0xddd5

标签: #c语言中和有什么区别 #iosc语言函数 #c语言 x的n次方 #c语言x的n次方怎么打 #c语言的宏定义命令为default