5

我在 mac os x 上用 c 语言编程。我正在使用来自 math.h 的 sqrt,函数如下:

int start = Data -> start_number;
double localSum;

for (start; start <= end; start++) {
    localSum += sqrt(start);
}

这行得通,但为什么呢?为什么我没有收到警告?在 sqrt 的手册页上,它需要一个 double 作为参数,但我给它一个 int - 它是如何工作的?

谢谢

4

4 回答 4

11

不会导致精度损失的类型转换可能不会引发警告。它们是隐式转换的。

int --> double //no loss in precision (e.g 3 became 3.00)
double --> int //loss in precision (e.g. 3.01222 became 3)

触发警告和不触发警告的因素在很大程度上取决于编译器和提供给它的标志,但是,大多数编译器(至少我使用过的那些)不考虑隐式类型转换dangerous足以保证警告,因为它是语言规范中的一个特性。


警告或不警告:

C99 Rationale 将其视为指南

探索这个(隐式转换)问题的重要成果之一是理解高质量的编译器可能会很好地寻找这些有问题的代码并提供(可选的)诊断,并且尽职尽责的讲师可能会很好地警告程序员这些问题隐式类型转换。

C99 基本原理(2003 年 4 月):第 45 页

于 2012-11-01T13:59:14.987 回答
3

编译器知道 的原型sqrt,因此它可以并且将在调用函数之前生成将int参数转换为的代码。double

反之亦然,如果您将 a 传递double给带参数的函数(具有已知原型)int,编译器将生成所需的转换代码。

编译器是否警告此类转换取决于编译器和您在命令行上请求的警告级别。

对于int -> double通常(具有 32 位(或 16 位)int和 64 位doublesIEEE754 格式)是无损的转换,如果可能的话,获得该转换的警告可能很难。

对于double -> int使用 gcc 和 clang 的转换,您需要使用 专门询问此类警告-Wconversion,否则它们将默默地编译代码。

于 2012-11-01T14:12:32.410 回答
1

Int 可以安全地自动向上转换为 double,因为没有数据丢失的风险。反过来是不正确的。要将 double 转换为 int,您必须显式转换它。

于 2012-11-01T13:59:59.623 回答
0

C 编译器使用 double 和 int 进行一些自动转换。您还可以执行以下操作:

int start = Data -> start_number;
int localSum;

for (start; start <= end; start++) {
   localSum += sqrt(start);
}

即使 localSum 是一个 int 这仍然可以工作,但它总是会削减任何超出点的内容。
例如,如果 sqrt() 的返回值为 1.365,它将被存储为简单的 1。

于 2012-11-01T14:02:49.337 回答