【问题标题】:Declare a void function in C在 C 中声明一个 void 函数
【发布时间】:2013-11-20 08:52:40
【问题描述】:

我正在学习 C 并且我正在学习函数。所以,我读到当我实现自己的函数时,我必须在 main() 之前声明它。如果我错过了声明,编译器将收到一条错误消息。

当我研究这个例子时(查找数字是否为素数),

#include <stdio.h>

void prime();               // Function prototype(declaration)

int main()
{
   int num, i, flag;

   num = input();            // No argument is passed to input()

   for(i=2,flag=i; i<=num/2; ++i,flag=i)
   {
      flag = i;

      if(num%i==0)
      {
         printf("%d is not prime\n", num);
         ++flag;
         break;
      }
   }

  if(flag==i)
     printf("%d is prime\n", num);

  return 0;

}

int input()  /* Integer value is returned from input() to calling function */
{
    int n;
    printf("\nEnter positive enter to check: ");
    scanf("%d", &n);
    return n;
 }

我注意到声明了一个函数 prime(),但在 main 中,调用了一个函数 input(),并且函数 input() 在底部实现。好的,我认为这是一个错误,我将名称从 prime 更改为 input。

但是如果我删除了声明并且我没有在其中放置任何声明,那么程序编译时不会出错并且运行顺利。 (我在 Ubuntu 上编译并运行它。)

是否需要声明一个不带参数的 void 函数?

【问题讨论】:

  • 一个没有参数的函数应该是void f(void), IIRC。 void f() 可以接受 任何 参数(是的,这就是令人惊叹的 C 语言)。
  • prime() 永远不会被调用,是吗?所以不需要原型,因为它从来没有被调用过
  • 您好像没有在任何地方打电话给prime?如果不调用,则不需要(之前)声明它。
  • 另外,教自己总是if等中使用花括号。即使只有一个语句。
  • 您的评论不正确。 void prime(); 只是一个声明;它不是原型。

标签: c function declare


【解决方案1】:

如果您在使用位置之前没有函数的前向声明,编译器将为您创建隐式声明 - 带有签名 int input()。它将采用您调用的函数的名称,并假定该函数返回 int,并且它可以接受 任何 参数(如注释中所述的 Bartek)。

对于这个函数,隐式声明与真实声明匹配,所以你没有问题。但是,您应该始终小心这一点,并且您应该始终更喜欢前向声明而不是隐式声明(无论它们是否相同)。因此,除了前向声明 void prime() 函数(假设您将在某处使用它)之外,还应该前向声明 int input()

要了解如何传递任意数量的参数,请考虑以下几点:

#include <stdio.h>

// Takes any number of the arguments
int foo();

// Doesn't takes any arguments
int bar(void)
{
    printf("Hello from bar()!\n");
    return 0;
}

int main()
{
    // Both works

    // However, this will print junk as you're not pushing
    // Any arguments on the stack - but the compiler will assume you are
    foo();

    // This will print 1, 2, 3
    foo(1, 2, 3);

    // Works
    bar();

    // Doesn't work
    // bar(1, 2, 3);

    return 0;
}

// Definition
int foo(int i, int j, int k)
{
    printf("%d %d %d\n", i, j, k);
    return 0;
}

因此,在函数的定义 中,您正在描述函数参数。但是,函数的声明告诉编译器不要对参数进行任何检查。

【讨论】:

  • 还有一个问题。您说 void prime() 可以接受任何参数。在这种情况下,我怎么知道,传递的参数与函数内的变量如何匹配? – Nat95 2 分钟前@NemanjaBoric
  • 我怀疑这会编译。在 C 中,重新定义是不允许的。
  • @hacks 这将编译,因为没有 redefinition - 第一个语句是 declaration,第二个语句是 definition。尝试使用-std=c99 -Wall -Wextra 编译它。
  • @hacks 哦,对不起,我这里的东西和我的编辑器不同——谢谢你的建议!
  • @hacks 是的,抱歉,情况就像那部电影一样 - 在编辑中迷失了
【解决方案2】:

不声明原型并依赖默认参数/返回类型提升是危险的,并且是旧 C 的一部分。在 C99 及更高版本中 在没有首先提供函数的声明或定义的情况下调用函数是非法的

我的问题是,是否有必要声明一个不带参数的 void 函数?

是的。为此,您必须将void 放在函数括号中。

void foo(void);  

声明一个类似

的函数
void foo();  

意味着它可以接受任意数量的参数。

【讨论】:

  • 还有一个问题。你说void foo() 可以接受任意数量的参数。在这种情况下,我怎么知道,传递的参数与函数内部的变量如何匹配?
  • @Nat95;所有参数都显式转换为int 类型。
【解决方案3】:

如果没有使用 prime,则省略声明。

代码不会编译为 C++,因为编译器会抱怨函数 input 已使用但未声明。 C 编译器可能会发出警告,但 C 更宽松,并且会将输入隐式声明为 int input(),这意味着您可以将任何值传递给 input,并且 input 返回一个 int

在使用函数之前总是提供函数声明是一种很好的风格。只有这样做,编译器才能查看您传递的参数是否太少、太多或输入错误,以及如何正确处理返回值(可能是 shortchar 而不是 int)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-17
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    相关资源
    最近更新 更多