C语言如何定义带“默认参数”的函数?

使用C++开发过程序时,定义函数可以指定默认参数,例如 void fun(int x, int y=3); 在调用 fun() 时第二个参数可以不传递,此时 fun() 函数默认第二个参数等于 3,例如 f(1) 就相当于 f(1,3)。这是一个很好用的特性,那么在C语言程序开发中,是否也可以定义带“默认参数”的函数呢?

有“默认参数”的C语言函数

首先应该清楚,目前C语言还没有原生支持带默认参数的函数,也就是说下面这样的C语言代码是非法的:

void fun(int x, int y =3)
{
    return x+y;
}
fun(1);     // 不等价于 fun(1, 3)

但是,C语言作为一门极其灵活的编程语言,又的确可以借助其他基本语法实现这样的需求。不过要在C语言中定义带“默认参数”的函数可能略微有些繁琐,当然了,方法可能不止一种,本文不打算从枯燥的理论层面讨论这些方法,而是给出一个实例,希望能够起到抛砖引玉的作用。

假设我们希望在某段C语言程序中定义一个带默认参数的函数,它可以接收两个参数,并将之打印出来:

double f(int i, double x)
{
    printf("i=%d, x=%0.2f\n", i, x);
    return x;
}

现在期望调用 f 时,如果不显式指定参数,f 的两个默认参数为 (i=8, x=3.14),例如:

f(); // 输出 i=3, x=3.14
f(1); // 输出 i=1, x=3.14
f(2, 6.28); // 输出 i=2,x=6.28

C语言自然没有支持这种需求的原生语法,但是为了实现这样的目的,可以定义下面这个结构体,请看相关C语言代码:

typedef struct {
    int i;
    double x;
} f_args;

接着,定义 f_base() 函数,它的C语言代码实现和 f() 是一样的,目的是让 f_base() 函数具有期望的 f() 函数功能。然后再定义一个函数将 f_base() 封装,相关C语言代码如下,请看:

double var_f(f_args in)
{
    int i_out = in.i ? in.i : 8;
    double x_out = in.x ? in.x : 3.14;
    return f_base(i_out, x_out);
}


显然,从上述C语言代码来看,var_f() 函数实现了默认参数的功能。现在再定义一个带可变参数的宏,这样一来,调用者就不必知道结构体 f_args 的结构了:

#define f(...) var_f((f_args){__VA_ARGS__})

现在我们就在C语言中实现了带“默认参数”的方法,全部C语言代码如下,请看:


上述C语言代码在 main() 函数中调用 f() 函数,并分别传递了不同的参数,编译并执行之,得到如下结果:

# gcc t.c
# ./a.out 
i=3, x=8.00
i=1, x=2.30
i=2, x=3.14
i=8, x=9.20

最后

可见,C语言是一门极其简洁灵活的编程语言,其他编程语言中一些好用的特性,可能C语言没有原生语法支持,但是我们却可以组合其他基本语法,自己实现这些好用的特性。

不过应该注意,有件事是行不通的——f(0),因为上述实现我们无法在 var_f() 中区分 “0”究竟是调用者传递的,还是默认值。

  • 11
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容: 1、Linux系统C语言编程连接MySql数据库实现的用户 用户组 用户策略 管理系统(getopt解析命令行参数).c 代码的源文件。 user-usergroup-authoritys.vsd user-usergroup-authoritys.jpg 数据库的图,以及图片。 2、部分操作: 显示操作 -S //-S显示名为xxx用户具体信息(所在组、改组定义了什么策略) 提示必须加-n参数 ./userGroupUser users -S //显示用户表 用户组表 所有信息 ./userGroupUser users -S -n root //显示用户表内 name=root的用户的信息 //可以显示该用户对应用户组内 所在的组 定义的策略信息 新增操作 -A /* 全:./userGroupUser users -A s -n test3 -p test3 -a 2 -groot -rasdc*/ /**添加用户 (-g(+) group ; -r(+) remark)**/ //新增用户的时候必须有-n|-p|-a选项 name password authentication //一次性输入所有选项也是错误的 需要为每个参数赋值 // printf("ADD -- Please enter necessary parameters -n|-p|-a,and assign a value to each parameter!\n"); //-g的参数必须紧跟 否则改用户会默认加入root组; //-r的参数必须紧跟 否则判定为输入为空 //当-g选项没有加参数时候 默认该用户属于root组; //-g后的参数不存在则加入失败,提示该用户组不存在 ./userGroupUser users -A -n ddf -p aa -a 1//添加用户 name=ddf authentication=1 默认加到用户组root //insert into users values(7,'ddf','aa','2018-7-2 16:23:39',1,1,' ','KEY认证需要的文件',''); ./userGroupUser users -A -n dds -a 1 -p sd -rkj -gaa //添加用户 name=dds authentication=1 group=aa //insert into users values(6,'dds','sd','2018-7-2 16:20:33',1,1,' ','KEY认证需要的文件','kj'); //-g后的参数 用户组名不存在不允许加入users usergroups表 /**添加用户组 (-e(+) enable; -o(+) policy; -r(+) remark)**/ /*全: ./userGroupUser usergroups -A -n dd -e1 -oWEB,HTTP -rddWH*/ //新增用户时候有必须参数-n选项 name //只有-n参数时候 策略状态( enable_type_)为0 默认策略( policy_type_)为所有策略资源 //其他参数 -e(+) 策略状态enable; -o(+)策略类型policy; -r(+) 标记内容remark ./userGroupUser usergroups -A //提示 Please enter other parameters when you want to add someone!! ./userGroupUser usergroups -A -n aa //用户组表中添加name=aa policy默认如下 remark默认为空 的用户组信息 //insert into usergroups values(2,'aa','2018-7-2 16:14:19',0,'GET,HEAD,POST,PUT,DELETE,OPTIONS','') ./userGroupUser usergroups -A -n aa -oGET -rasd //向用户组中添加 name=aa policy=GET remark=asd的用户 //insert into usergroups values(2,'aa','2018-7-2 16:14:46',0,'GET','asd'); 修改操作 /**修改用户**/ /*全:./userGroupUser users -E -n test33 -p test33 -a 1 -gaa -rtest3totest33 where name test3 password test3*/ //修改用户操作必须有where name password 字符;且where后个数需为偶数; name password参数参数值 //判断要进行改的用户是不是管理员用户,禁止对管理员用户进行任何操作 //参数 :-n newname;-p newpassword;-a authentication; -ggroup; -rremark; ./userGroupUser users -E -n test22 where name test2 password test2 //把名为test2密码为test2的用户名改为test22 /**修改用户组**/ /*全:./userGroupUser usergroups -E -n aaa -e1 -oGET,HEAD -raatoaaa where name aa*/ //修改用户组操作必须有where name字符;且where后个数需为偶数; name 参数参数值 //判断要进行改的用户是不是管理员用户,禁止对管理员用户进行任何操作 //参数 : -n newname;-eenabled ; -opolicy; -rremark; ./userGroupUser usergroups -E -n AA where name aa//把aa用户名改为AA ./userGroupUser usergroups -E -n csa -e1 -oAAA,WEB,HTTP -rAAA where name aaa //修改 用户组name为aaa为 name=csa enable=1 policy=AAA,WEB,HTTP remark=AAA 删除操作 ./userGroupUser users -D // 提示 Please enter other parameters when you want to add someone!! ./userGroupUser users -D -n root -p r //root用户不允许删除 //name或passwd 不正确不允许删除 ./userGroupUser usergroups -D //提示 Please enter other parameters when you want to add someone!! ./userGroupUser usergroups -D -n as//判断是否有用户属于该用户组 若有用户属于该用户组 不允许删除该用户组 //root 用户组不允许删除

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值