C语言自动类型转换:int型数据 + float数据 → double型?纠正教材中的错误用法!

网友投稿 1166 2022-05-25

目录

前言

一、官方标准证明(C89、C99、C11)

二、代码证明

三、一些教材上的错误的用法来源 与 K&R(非正式)标准

四、参考博文

五、C语言各个版本PDF下载

前言

笔者之前看到一些教材关于自动类型转换章节的知识点写到:1.float型数据参与运算时,先转换为double型数据再计算;2.float型数据 与 int型数据运算,先将两者转换为double型,再运算。与笔者的实操结果不符,于是经过充分的查阅后,发现上述知识点已经是30年前过时老掉牙的用法了。今天笔者通过官方标准、代码证明、错误来源 来充分证明。

一、官方标准证明(C89、C99、C11)

距今为止,C语言官方标准共发展了四代:C89、C99、C11、C17

C89、C99、C11这三代标准中均对于float + float → float 、 int + float → float 作出了明确说明。由于笔者暂未找到C17官方标准文档,再加之C17相较于C11未发生语法改动,因此本文暂不作C17标准的讨论。

1.C89

首先,C89是由美国国家标准协会(ANSI)在 1989年正式公布的标准,该标准定义了C语言和C标准库。

p.s:

国际标准化组织(ISO)采用了这套C标准,因此ISO C和ANSI C是完全相同的标准。

ANSI于1989年批准该标准,因此通常称之为C89。

ISO于1990年批准该标准,因而又有C90的叫法。

C89标准中的6.2.1.5章节中有说明:float + float → float 、 int + float → float。如下:

由于我国的C标准采用的是此版本,所以相当于C89的官方中文翻译版。

2.C99

在后来1999年出台的C99标准中关于float + float →float、 int + float → 的规定并无变化。(翻译放在英文原文的下方)

3.C11

2011年出台的C11标准中6.3.1.8章节中自动类型转换的规定与C99标准的此部分规定完全一致:

综上,C89、C99、C11标准中对于float + float → float、 float + int → float 的说明都是一样的。

因此,自动类型转换规则应该是下图这样的:(C99标准的unsigned与long的混合情况暂不重要 不讨论- -)仅供参考欢迎补充

二、代码证明

编译器为DEV C++,采用标准为C99。

测试代码如下:

/* 编译器:DEV C++ 采用标准:C99 */ #include int main() { // 1. int + float →float 而不是 int + float →double int int_a = 1; float float_a = 2.5; printf("%f\n",int_a + float_a); //3.500000 printf("%d",sizeof(int_a + float_a)); //4 // 备注:第一个printf结果为3.500000说明int转为了实型,而非float转为了int。与争议点无关,仅供自己测试 。 // 第二个printf结果为4说明int转为了float(4字节),而非int和float都转为了double(8字节) // 2.float + float →float 而不是 float + flaot →double float float_b = 1.5; printf("%f\n",float_a + float_b); //4.000000 printf("%d\n",sizeof(float_a + float_b)); //4 // 备注:第一个printf结果为4.000000,与本次话题无关,仅供自己测试 。 // 第二个printf结果为4说明int转为了float(4字节),而非int和float都转为了double(8字节) //======================以下三点为补充测试======================== // 3. char + short → int 而不是 char + short →short char char_a = 1 ; short short_a = 1; printf("%d,%d\n",sizeof(char_a),sizeof(short_a)); // 1,2 printf("%d\n",sizeof(char_a + short_a)); //4 // 备注:char 1字节 ,short 2字节 , 此例说明char + short 运算,都转为了int // 4. long + float → float 而不是 long + float →double long long_a = 1; // float_a在例1中已定义 printf("%f\n",long_a + float_a); //3.500000 printf("%d\n",sizeof(long_a + float_a)); //4 // 备注:第一个printf结果为3.500000说明long转为了实型,而非float转为了long 。与争议点无关,仅供自己测试 。 // 第二个printf结果为4说明long转为了float(4字节),而非long和float都转为了double(8字节) // 5.double + float →double double double_a = 1.5; printf("%f\n",double_a + float_a); //4.000000 printf("%d\n",sizeof(double_a + float_a)); //8 // 备注:第一个printf结果为4.000000,与本次话题无关,仅供自己测试 。 // 第二个printf结果为4说明int转为了float(4字节),而非int和float都转为了double(8字节) }

三、一些教材上的错误的用法来源 与 K&R(非正式)标准

float + float → double,int + float → double的用法来源于由C语言设计者丹尼斯·里奇于1978 年出版的《The C Programming Language》第 1 版。笔者暂未找到第一版的资源。

此时的 C 语言还没有统一的标准,来自C语言之父的《The C Programming Language》第 1 版可算作“正式”的标准,所以此时的 C 也称为“K&R” C。

当时的教材就是根据这本书作为标准而编写的。

10年后的1988年,C语言之父丹尼斯·里奇出版了《The C Programming Language》第 2版(如下面的四张图),书中将原用法更改为float + float → float , int + float → float 。(原文:修改了“普通算术类型转换”,特别地,“整型总是转换为unsigned 类型,浮点数总是转换为 double 类型”已更改为“提升到最小的足够大的类型”。)

1989年,考虑到标准化的重要,ANSI(American National Standards Institute)制定了第一个 C 标准,在1989年被正式采用(American National Standard X3.159-1989),故称为 C89,也称为 ANSI C。

该标准随后被 ISO 采纳,成为国际标准(ISO/IEC 9899:1990)。

最后,笔者想吐槽一句:30多年前早已被废弃的用法,这都1202年了,一些教材居然还不修改 ~~

四、参考博文

1. 出现矛盾:c语言中float会自动转换为double? - 知乎

https://www.zhihu.com/question/51829080/answer/1219171602

C语言自动类型转换:int型数据 + float数据 → double型?纠正教材中的错误用法!

2.C语言标准—C89、C99、C11、C17、C2x ...

https://blog.csdn.net/lu_embedded/article/details/115535432

3.C2x将成为C语言的下一个ISO标准?:

https://blog.csdn.net/cpongo4/article/details/89030403

4.c语言之标准(K&RC 、c89、c99、c11)

https://blog.csdn.net/qq_31029351/article/details/53290990

5.如何使DEV C++支持C99标准?

https://blog.csdn.net/qq_40834200/article/details/104714963

五、C语言标准各个版本PDF下载

【阿里云盘】

https://www.aliyundrive.com/s/ZfaViMu1Xru

【百度网盘】

链接:https://pan.baidu.com/s/1g6nrTMWUtWr-6VdzGeAjMw

提取码:1234

--来自百度网盘超级会员V1的分享

C 语言

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:华为云Welink助力长沙企业加速复工复产
下一篇:为什么建议大家使用 Linux 开发?
相关文章