为什么没有参数的函数起作用,但是以void作为参数的函数却不起作用?

问题描述 投票:0回答:3

[在以下代码中,我正在使用PI外部的函数来计算main()。两者之间的唯一区别是:

  • 第一个代码。我没有传递任何参数:void calculate_pi ();
  • 第二代码。我明确地说没有要传递的参数:calculate_pi (void);

我本以为第二个更好,但事实并非如此。为什么是这样?谢谢!

第一密码:

#include <stdio.h>
#include <stdlib.h>

void calculate_pi ();

int main(void)
{

    calculate_pi ();

    return 0;
}

void calculate_pi ()
{
    int i, signo;
    double pi_approx = 1, pi_final;

    for (i = 1; i < 1000000; ++i)
        {
            signo = (i%2) ? -1 : 1;
            pi_approx = pi_approx + (float) signo / (2*i+1);
        }

    pi_final = pi_approx * 4;
    printf("%.10f\n", pi_final);
}

第二代码:

#include <stdio.h>
#include <stdlib.h>

void calculate_pi (void);

int main(void)
{

    calculate_pi (void);

    return 0;
}

void calculate_pi (void)
{
    int i, signo;
    double pi_approx = 1, pi_final;

    for (i = 1; i < 1000000; ++i)
        {
            signo = (i%2) ? -1 : 1;
            pi_approx = pi_approx + (float) signo / (2*i+1);
        }

    pi_final = pi_approx * 4;
    printf("%.10f\n", pi_final);
}
c function arguments parameter-passing void
3个回答
0
投票

[[0]中声明一个带有空参数列表的函数是一种旧的C语法,它没有指定参数类型。在新代码中应避免使用它。优选地,用参数列表,例如void calculate_pi();来声明函数。新语法提供了更好的类型信息,并允许编译器检查参数类型并提供有用的警告和错误消息。

因为C使用int foo(char *x);来声明没有指定参数类型的函数,所以需要使用不同的语法来指定函数具有no参数。根据[C 2018 6.7.6.3 10:

,使用()作为特殊情况来表示这一点

(void)类型的未命名参数的特殊情况是列表中的唯一项,它指定该函数没有参数。

因此,声明void并不表示void calculate_pi(void);接受calculate_pi参数;它表示void没有任何参数。这是声明不带参数的函数的首选方法。

由于该函数不接受任何参数,因此应使用calculate_pi对其进行不带任何参数的调用。

calculate_pi()不是有效的C表达式。函数参数必须是一个值,但是calculate_pi(void)是类型,并且类型void不能作为函数参数出现。因此,现代C语言中的首选代码是声明该函数不包含任何参数:

void

并且不带任何参数调用它:

void calculate_pi(void);

0
投票

[在函数的声明/定义中使用calculate_pi(); 作为参数类型与在实际调用函数时作为参数是有区别的。

在此情况下,

void只能用作参数,而不能用作函数调用中的参数。无论如何都不能使用类型为void的表达式,因为它实际上根本不产生任何值。否则程序将调用void

“绝对不能使用void表达式(具有void类型的表达式)的(不存在)值,并且不得将隐式或显式转换(除void之外)应用于此类表达式。任何其他类型都将作为void表达式求值,其值或指示符将被丢弃。(对void表达式的副作用进行求值。)“

来源:C18,6.3.2.2 / 1

您需要将undefined behavior称为calculate_pi,而不是calculate_pi()

calculate_pi(void)

我本以为第二个更好,但事实并非如此。

确实最好在声明/定义处使用int main (void) { calculate_pi(); return 0; } 而不是使用空参数列表,因为严格认为带有空参数列表的声明不是原型。

C标准规定(强调我的::)>

“对于标识符指定的每个不同实体,该标识符仅在称为其范围的程序文本区域内可见(即,可以使用。)由同一标识符指定的不同实体要么具有不同的范围,要么具有不同的名称空间,共有四种作用域:函数,文件,块和函数原型(一个函数原型是一个声明其参数类型的函数的声明

。)“

因此,如果您指定一个空的参数列表,例如f.e,则某些编译器会发出警告。 lang做:

警告:此函数声明不是原型[-Wstrict-prototypes]

但是在这种情况下,问题出在其他地方,如上所述。


旁注:

  • 如果默认情况下提供void作为参数,则编译器通常会引发错误,因此甚至不应该编译您的代码。请考虑换用最新的,符合标准的编译器,例如GCC或Clang。

-1
投票

基于@KamilCuk的注释,那么正确的代码应为:

© www.soinside.com 2019 - 2024. All rights reserved.