【问题标题】:To use a function prototype or not是否使用函数原型
【发布时间】:2021-01-07 00:06:16
【问题描述】:

什么时候应该使用函数原型/声明,或者总是包含它们是一种好习惯?例如:

int square_num(int num);

int main(void) {
    return square_num(3);
}

int square_num(int num) {
    return num * num;
}

对比

int square_num(int num) {
    return num * num;
}

int main(void) {
    return square_num(3);
}

什么被认为是最佳实践,还是逐个案例?

【问题讨论】:

  • 这取决于上下文。对于这样的简单程序。我会把square_num() 放在第一位,避免使用原型。在大型应用程序中,我可能想先记录所有功能。

标签: c


【解决方案1】:

在这种特殊情况下,它是必需的。因为函数是在定义之后使用的,所以必须在之前声明。

如果您在调用之前定义了square_num,您就不需要原型了。

附带说明,如果在定义之前使用旧的预标准 C,则它具有 隐式函数声明 的概念。这样的函数foo 将被隐式定义为int foo(),即一个函数采用未知数量的参数并返回int。一些编译器仍然允许这样做,但你不应该依赖这种行为。

【讨论】:

    【解决方案2】:

    Nit:“原型”指的是函数声明的特定样式,而不是声明本身。指定参数列表中参数类型的函数声明或定义是原型:

    int square_num(int num); // declaration using prototype syntax
    int square_num();        // declaration using non-prototype syntax
    
    int square_num(int num)  // definition using prototype syntax
    {
      return num * num;
    }
    
    int square_num(num)      // definition using non-prototype syntax
      int num;
    {
      return num * num;
    }
    

    您应该始终使用原型语法,除非您必须支持古代 K&R 实现。

    您要问的是,为同一源文件中定义的函数单独声明是否是一种好习惯。

    这在很大程度上是一个口味问题,但我强烈建议使用第二种样式并在使用之前定义函数。如果您需要更改函数的返回类型或参数,它可以减轻您的维护负担,因为您只需要在一个地方进行更改。听起来可能不多,但对于大型项目,它可以节省一些胃灼热。

    这确实意味着您的代码“向后”读取,但 IMO 的权衡是值得的。

    【讨论】:

    • "支持古老的 K&R 实现" 在这种情况下,添加诸如 int square_num(int num) 之类的原型实际上可以破坏代码。传递给具有完整原型的函数(如 int square_num(int num))的参数将不会进行默认参数提升。但是像int square_num(num) int num; { ... } 这样以 K&R 风格定义的函数需要在此类提升之后传递所有参数。
    【解决方案3】:

    规则很简单:在代码中使用函数之前,应该使用适当的原型定义或声明函数。

    问题中的两种程序风格都是正确的,使用哪一种是个人品味或当地惯例的问题。我个人更喜欢第二种,并将square 定义为static

    如果函数square在另一个模块中使用,它应该在两个模块包含的头文件中声明。

    相互递归的函数要求在使用前至少声明其中一个。

    旧版本的 C 标准允许编译器推断使用时尚未定义的函数原型,因为它采用未指定数量的参数并具有 int 返回类型。最新版本的 C 标准不再允许这种容易出错的行为。

    【讨论】:

    • 当然,在哪种情况下应该使用第一种形式而不是第二种形式。还是没关系?
    • 没关系,纯粹是喜好问题。这里唯一有意义的是是不是static,这两种情况都应该是。
    猜你喜欢
    • 2018-07-25
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多