如何在C中选择性地传递变量参数

如何在C中选择性地传递变量参数,c,variadic-functions,C,Variadic Functions,考虑以下功能: void foo(int n,...); 我需要调用这个函数,“可选地”传递变量参数 可能吗 大概是这样的: foo(10, (bIsJobDone ? "OK" : xxx) ); 我不知道应该用什么来代替xxx(xxx应该转换为nothing),也不知道如果我不需要将任何变量arg传递给foo,如何避免10之后的“?” 注意:我不能更改“foo”的签名。单独调用它: bijobdone?foo(10,“OK”):foo(10)单独调用: bijobdone?foo(10,

考虑以下功能:

void foo(int n,...);
我需要调用这个函数,“可选地”传递变量参数

可能吗

大概是这样的:

foo(10, (bIsJobDone ? "OK" : xxx) );
我不知道应该用什么来代替xxx(xxx应该转换为nothing),也不知道如果我不需要将任何变量arg传递给foo,如何避免10之后的“?”

注意:我不能更改“foo”的签名。

单独调用它:

bijobdone?foo(10,“OK”):foo(10)

单独调用:


bijobdone?foo(10,“OK”):foo(10)

只要被调用函数的原型和定义正确(不容易…,
根据条件,使用一个或两个参数调用它很容易:

if(bIsJobDone)
{    foo(10, "OK");
} else
{    foo(10);
}

另一种选择是,将其压缩成三元运算符,这是可能的,但许多人认为它不可读(当然这只是一个意见问题),并且您在问题中展示的返回空的原型不需要它。

只要您正确地原型化和定义了被调用的函数(不容易…,
根据条件,使用一个或两个参数调用它很容易:

if(bIsJobDone)
{    foo(10, "OK");
} else
{    foo(10);
}

另一种选择是,将其压缩成三元运算符,这是可能的,但许多人认为它不可读(当然这只是一个意见问题),并且对于您在问题中展示的返回空的原型来说,这是不需要的。

如果函数是为可变数量的参数编写的(例如,
printf
),然后,可以将数量可变的参数传递给函数

它们使用两种模式中的任何一种

地图样式 与printf一样,早期的非可选参数描述了已添加的其余参数。然后从堆栈中适当地提取这些数据

终止模式 可以编写一个函数来求一组参数的和,这些参数具有某种检测终止符的机制

int sum( int first_arg, ... );
将特殊令牌添加到函数以正确调用


如果函数只接受固定数量的参数,则必须传递该数量的参数

这是因为调用代码和被调用代码必须就使用了多少堆栈达成一致。本合同中的任何差异都将导致未定义的行为,这可能意味着崩溃,或者您的程序可能会被恶意参与者利用


假定函数有一组参数,您需要提供所有这些参数。

如果函数是为可变数量的参数编写的(例如,
printf
),则可以将可变数量的参数传递给函数

它们使用两种模式中的任何一种

地图样式 与printf一样,早期的非可选参数描述了已添加的其余参数。然后从堆栈中适当地提取这些数据

终止模式 可以编写一个函数来求一组参数的和,这些参数具有某种检测终止符的机制

int sum( int first_arg, ... );
将特殊令牌添加到函数以正确调用


如果函数只接受固定数量的参数,则必须传递该数量的参数

这是因为调用代码和被调用代码必须就使用了多少堆栈达成一致。本合同中的任何差异都将导致未定义的行为,这可能意味着崩溃,或者您的程序可能会被恶意参与者利用


鉴于函数有一组参数,您需要提供所有这些参数。

xxx是指字符串以外的另一种类型,还是什么都没有?@Lundin xxx应该转换为“无”。这种情况没有用;如果两个调用中的第一个参数相同,那么被调用函数应该如何确定是否存在第二个参数?对于varargs函数,固定参数中必须有一些信息,告诉被调用函数预期的变量参数数量(或者必须使用sentinel,即始终至少有一个变量参数可能是sentinel)。在
foo()
内部,你无法区分
foo(10)
foo(10,“OK”)
。你对xxx是什么意思,字符串以外的另一种类型,还是什么都没有?@Lundin xxx应该转换为“无”。这种情况没有用;如果两个调用中的第一个参数相同,那么被调用函数应该如何确定是否存在第二个参数?对于varargs函数,固定参数中必须有一些信息,告诉被调用函数预期的变量参数数量(或者必须使用sentinel,即始终至少有一个变量参数可能是sentinel)。在
foo()
内部,您无法区分
foo(10)
foo(10,“OK”)