函数原型和参数强制

Function prototypes and argument coercion

本文关键字:参数 原型 函数      更新时间:2023-10-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++标准,但也很有用(还是我错过了什么?

一切都在这里。考虑一下您在sizeof呼叫中输出的内容。您正在输出变量的大小。现在你要明白的是,当你把a传递给你的函数foo时,a被隐式转换为doubledoubleint具有相同的值,但它们是不同的类型。在体系结构上,int的大小为 4 个字节,double的大小为 8 个字节。

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

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

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

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

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