问题描述
在 C 中,当您声明一个不带参数的函数时,该函数可以接受任意数量的参数。示例:
int sum() {
// some code
}
int subs(void) {
// some code
}
int main() {
sum(1,2,3,4,5,6); // This is valid
subs(1,6); // This is NOT valid
}
在第一种情况下(sum),如何判断是否提供了一些参数?
提前致谢
解决方法
如何判断在C中,是否提供了函数的参数?
这不可能。从 C 的角度来看,不可能知道是否为此类函数提供了任何参数,也不知道它们的数量是多少。
当你声明一个不带参数的函数时,该函数可以接受任意数量的参数
是的,当您声明一个没有参数的函数时。并且它不一定意味着该函数接受任意数量的参数。在您提供的代码中:
int sum() {
// some code
}
它是 sum
函数定义。在定义中,当函数没有参数时,那么,这个函数真的没有参数——就好像int sum(void)
。它来自C11 6.7.6.3p14,强调我的:
标识符列表仅声明函数参数的标识符。函数声明符中的空列表(该函数的定义的一部分)指定该函数没有参数。函数声明符中的空列表不是该函数定义的一部分,它指定不提供有关参数数量或类型的信息。
您提供的代码无效 - sum
不带参数。
所以:
sum(1,2,3,4,5,6); // This is also NOT valid
,
作为一种解决方法,您可以传递对数组的引用,其中包含类型信息和对变量的引用。
typedef enum
{
CHAR_T,INT_T,FLOAT_T,}TYPES_t;
typedef struct
{
TYPES_t type;
void *arg;
}ARG_t;
int foo(ARG_t *args)
{
size_t argnum = 0;
while(args -> arg)
{
printf("Parameter %zu has type pointer to ",argnum);
switch(args -> type)
{
case CHAR_T:
printf("char and value of the refenced object is %c\n",*(char *)args -> arg);
break;
case INT_T:
printf("int and value of the refenced object is %d\n",*(int *)args -> arg);
break;
case FLOAT_T:
printf("float and value of the refenced object is %f\n",*(float *)args -> arg);
break;
}
args++;
}
}
int main(void)
{
int i = 1234;
char c = 'c';
float f = 9876.543;
ARG_t args[10] = {{CHAR_T,&c},{INT_T,&i},{FLOAT_T,&f},{0,}};
foo(args);
}
,
你告诉的方式是阅读被调用函数的文档。
调用者负责传递被调用函数可接受的参数。
这不仅适用于参数的数量,而且适用于它们的值。例如,一个名为 SquareRoot
的函数可能被指定为返回它传递的非负值的平方根,但如果传递负值则具有未定义的行为。在这种情况下,调用者负责传递一个非负值。
所以我们看到声明函数参数并让编译器报告参数数量或类型的错误只是确保函数被正确调用的任务的一部分。