一个空的参数列表意味着什么?

8
我正在阅读的书指出,当你在C语言中声明一个不接受参数的函数时,但是没有使用关键字void,“函数调用可以传递任何参数”。所以我尝试了这个方法。
int number();

int main(void)
{
    int x =1;
    printf("%d",number(x));
}

int number()
{
    return x;
}

但是它没有编译???这是怎么回事?

这是关于it技术的问题。

number() 函数从哪里精确地获取 x?关于 C 语言中 func(void)func() 的区别,可以参考这个问答 - WhozCraig
这是什么书?我猜这本书要么是错误的,要么——更有可能——已经过时了。 - Undefined
5个回答

13

这是一个过时的特性1,几十年前在C语言标准化之前就已经存在了。

永远不要使用它。

在古老的C语言中(早于你的出生十年之前),你可以声明一个没有参数的函数。当你调用它时,编译器会将参数提升为默认类型并将它们传递给函数。基本上,编译器从调用中的参数推断出参数声明。

函数应该仍然带有参数定义,并且它们应该与调用函数的方式相匹配。


1“特性”这个词不太合适。那时候还没有更好的方法,所以这是当时的做法。在一种新的编程语言中,这种特征将被视为缺陷。


7
支持Eric Postpischil的回答,我想引用C11标准(6.11 Future language directions)中的一段话:

6.11.6 函数声明符

使用带有空括号的函数声明符(不是原型格式的参数类型声明符)是一个已过时的特性。

以及

6.11.7 函数定义

使用具有单独的参数标识符和声明列表的函数定义(不是原型格式的参数类型和标识符声明符)是一个已过时的特性。

强调是我的 :)


1
这里的问题在于您的函数 number 没有关于 x 的知识。
也就是说,当您让函数 number 返回 x 时,它没有任何关于 x 的范围来返回,因此会出现编译错误。如果您改为写成:
int number() {
    return 5;
}

它会编译成功。

我猜你的意思是,如果你向这样的函数传递参数,你就无法在函数内部访问它们? - FutureSci
是的,没错。我看不出这有什么用处,但我想如果你有一个函数指针数组,其中大多数函数都需要特定的参数集,而其中一个函数不需要参数,你可以将那个函数声明为 () 而不是 (void),以便每次迭代该数组时都使用相同的参数。 - qaphla
也许编译器无法诊断错误,但是当使用int number() {…}定义函数后,调用number(x)的行为在C标准中没有定义。这不是正确的代码。 - Eric Postpischil

0

如果你想无限制地传递参数,你可能需要一个可变参数列表。这里是一个例子:

  #include <stdio.h>
  #include <stdarg.h>
  int number(int , ... );

  int main(void)
  {
       int x =1;
       printf("%d",number(1,x));
  }
  int number(int n, ... )
  {
          va_list         ap;
          va_start(ap,n);
          int x = va_arg(ap,int);
          va_end(ap);
          return x;
  }

或者,如果你只想传递 x,但不使用它。

 #include <stdio.h>
  int number();

  int main(void)
  {
      int x =1;
      printf("%d",number(x));
  }

  int number()
  {
     int x = 1;
     return x;
  }

它可以编译并工作。当你在C语言中声明int number();时,意味着这个函数可以被赋予非特殊类型,但是你不能使用它。


-2

在找到答案后,我编辑了整篇回答。

您想要做的是使用number(void)而不是main(void)。这就是您想要的,它会将任何变量打印为整数。如果传递字符“F”,int number(void)将返回数字70,“F”的int形式。在代码中:

int number(void e);

void main(){
    char C = 'F';
    printf("%d",number(C));
};

int number(void e){
    return e;
};

注意:
如果你想要一个超出作用域的变量,你必须始终传递一个参数。

我了解函数和参数,我的问题是有意处理将数据传递给没有指定参数列表的函数。因此,在这个问题的范围内,number() 不应该有类型。 - FutureSci
@worlboss 那是不可能的,我的朋友。记住,电脑是“愚蠢”的。你制定规则,它会完全遵循,并且除非你声明函数具有参数,否则程序不会使用它。实际上,如果调用未预先声明的参数类型的函数,程序将崩溃,在调试中,它也无法编译(如果我没记错的话),因为电脑不知道“该怎么做”(这就是你在这里的原因)。 - Jader J Rivera
@JaderJRivera:OP明确声明:“当您在C中声明一个不接受参数的函数,但您没有使用void关键字时,'函数调用可以传递任何想要的参数'。” - Undefined
@JakeWilson 对不起,那是真的,但似乎在C有标准之前和void被发明之前就使用了这种方法。这种类型的代码在我们现在的日子里肯定不会使用,并且在C99中被正确地删除了(我是正确的吗??)。您可以在此其他问题中找到更多答案。 - Jader J Rivera
2
(1) 这段代码无法编译;在函数定义中,void e 不是有效的参数声明。 (2) main 应该声明为 int main(void)int main(int argc, char *argv[]) 或等价形式,而不是 int main()。 (3) “F” 不能保证是70。 - Eric Postpischil
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接