【问题标题】:Function prototypes and argument coercion函数原型和参数强制
【发布时间】:2014-04-21 00:27:16
【问题描述】:

来自我的 C++ 教科书

函数原型的一个重要特性是参数强制 - 即,强制参数为参数声明指定的适当类型。例如,一个程序可以调用一个函数 一个整数参数,即使函数原型指定了一个 双参数 - 该函数仍然可以正常工作。

我试过了

#include <iostream>

// void foo(double);

void foo(double a) {

   std::cout << sizeof(a) << std::endl;
}

int main (void){

   int a = 1;
   std::cout << sizeof(a) << std::endl;
   foo(a);

   return 0;
}

如果有或没有原型,它会先正确打印 4 然后 (内部函数) 8.

我的编译器是否会在不存在的情况下检查函数定义 原型(可能不是严格的 C++ 标准,但 也有用)还是我错过了什么?

【问题讨论】:

  • 这里有什么困惑?您在main 中有一个int,在foo 中有一个double;它们的尺寸不同(在您的平台上)。
  • 我的困惑来自我的教科书陈述,因为我没有使用原型
  • 我认为混淆是关于prototype这个词。你把prototype理解为declaration,但是prototype是一个函数的签名,而这里,你的函数的definition直接有prototype,前面的declaration是没用的。跨度>
  • @AntiClimacus 发布的代码是最后一次完成的测试。以前我把函数定义放在main下面。但是我不明白一件事:您在这里说第 5 行 void foo(double a) { 用作原型? PS。最后,我认为我的书不如其他地方准确。
  • @LucaBraglia:阅读这篇文章:stackoverflow.com/questions/1410563/… 并记住 prototype 包含在声明和定义中。

标签: c++ function-prototypes


【解决方案1】:

这里的一切都应该如此。考虑一下您通过sizeof 调用输出的内容。您正在输出变量的大小。现在您必须了解的是,当您将a 传递给您的函数foo 时,a 会隐式转换为doubledoubleint 具有相同的值,但它们是不同的类型。在您的架构上,int 的大小为 4 个字节,double 的大小为 8 个字节。

基本上,当您的教科书说编译器将强制参数声明为参数声明指定的适当类型时,它的意思是它会查看您的 int a 并找到它作为双精度的含义(它将是 4在这两种情况下)。编译器这样做是因为它看到函数foo 需要doublefoo 得到int。它不会更改主函数中 a 的类型。 a in main 始终是 inta 在您的 foo 函数中始终是 double

见:http://en.cppreference.com/w/cpp/language/implicit_cast 有关隐式转换的更多信息。

【讨论】:

  • 添加到这个。 static_cast &lt; double &gt;,而不是隐式转换(向上转换),将使编译器理解向上转换,因此没有抱怨。这种明确的向上转换,将解决警告。
【解决方案2】:

这里实际发生的是编译器意识到foo 接受double 参数,并将int 参数转换为double。输出显示double 在这个特定系统中是 8 个字节,int 是 4 个字节——两者都很普通。请注意,foo 中的 amain 中的 a 不同。它们是不同的东西,即使它们被称为相同的东西。

【讨论】:

    【解决方案3】:

    函数foo 实例化一个新的临时值,也恰好被称为a,它是使用您传递给它的int 的double 类型。然后,您正在打印这个新的临时替身的大小。大小为 8,因为在您的平台上,双精度为 8。

    【讨论】:

      【解决方案4】:

      您教科书幻灯片中的下一张幻灯片清楚地解释了您的编译器正在做什么。看看吧:
       有时,参数值与 函数原型中的参数类型可以通过 在调用函数之前编译到正确的类型。
       这些转换按照 C++ 的升级规则进行。
       提升规则指明了如何在类型之间进行转换,无需 丢失数据。
       int 可以在不改变其值的情况下转换为 double。
       但是,转换为 int 的 double 会截断小数 双精度值的一部分。
       请记住,双变量可以容纳很多 比 int 变量大,所以数据的丢失可能是 相当大。

      【讨论】:

        猜你喜欢
        • 2015-10-20
        • 2020-05-12
        • 2013-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 2019-06-14
        相关资源
        最近更新 更多