【问题标题】:Understanding Function Prototype in C理解 C 中的函数原型
【发布时间】:2015-05-24 03:53:12
【问题描述】:

为什么下面的程序运行良好?

int main()
{
    int x;
    x = foo();
    printf("%d",x);
    getchar();
    return 0;
}

int foo()
{
    return 2;
}

而不是这个程序?

//double function(void);

int main(){
    double val;
    val = function();
    printf("%ul\n",val);
}

double function(void){
    double num;
    num = DBL_MAX;
    printf("%ul\n",num);
    return num;
}

据我了解,这两种情况下的函数定义在main() 之前都没有。那么为什么在第一种情况下无论如何都会调用该函数,即使编译器在main() 之前没有定义它,而在第二种情况下没有?

【问题讨论】:

  • 请注意,旧的 C 标准 (C99) 和当前的 C 标准 (C11) 都说程序应该生成诊断。只有过时的 (C89/C90) 标准允许第一个程序工作,而第二个程序总是失败。如果你喜欢处理损坏的代码,那很好——写到更草率的 C89 标准。宽松的规则是历史的必然。如果没有松懈,标准就不可能成功。但是旧标准已有 15 年的历史,当您使用没有原型的函数时,您应该使用它并让编译器发出警告。如果您的编译器不会,请使用更好的编译器。
  • @JonathanLeffler , %ul 可以用作 double 吗?
  • printf() 格式字符串中?不; %ul 格式化 unsigned int 后跟不属于转换规范的字母 l。如果您的意思是%lu,则格式为unsigned long。当您将 double 作为参数列表中的相应值传递时,两者都没有用(甚至不可靠)。
  • @JonathanLeffler,哎呀!我认为%ul 需要unsigned long。我对%ul%lu 感到困惑。那么,如果一个人用%lu 打印double,你是说它是UB?
  • @CoolGuy:是的,绝对是 UB 尝试使用任何整数格式打印 double。例如,可以想象浮点值在与整数值不同的寄存器中传递,因此当它看到整数格式时,它从完全错误的位置读取。使用 M68k 芯片的计算机用于在 An 寄存器中返回指针,在 Rn 寄存器中返回整数;如果你没有告诉它一个函数返回了一个指针,编译器会生成从错误位置读取的代码。我不记得这些芯片是如何处理浮点返回的。等等。

标签: c function


【解决方案1】:

由于隐式函数声明,编译器默认未指定类型为int

第一种情况是巧合,但不是第二种情况。

【讨论】:

    【解决方案2】:

    任何被称为函数 C 的东西默认都是 int 类型,没有参数(例如在您的第一种情况下)。如果编译器随后找到符合要求的函数,则没有错误。

    第二种情况,编译器编译main(),以为函数是int,但发现不正确,报错!

    评论:Jonathan Leffler 评论:

    仅在 C89/C90 中。不在 C99 中;不在 C11 中。当然,也有部分厂商 只执行 C89;一个值得注意的例子是微软!

    【讨论】:

    • 仅在 C89/C90 中。不在 C99 中;不在 C11 中。当然,有些厂商仍然只实现 C89;一个值得注意的例子是微软!
    • 这很有趣!我会添加到回复中(这些cmet有时容易被删除。
    【解决方案3】:

    在 C 中,如果定义了一个函数,则其隐式返回类型为 int

    • 在第一种情况下,函数的返回类型是int,因此main() 可以识别函数并编译没有任何错误。

    • 在第二种情况下,函数的返回类型是double,所以main()无法识别函数从而产生错误,因此您需要声明函数的原型。

    在 C89 之前的旧版本中,如果未提及返回类型,则其被隐式视为 int

    在 C99 标准中,即使返回类型为 int,也不允许省略返回类型。

    更多详情您可以查看:implicit return type C

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多