您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > C/C++/C#

C语言的类型转换 Conversion and Casting

时间:2020-07-21 09:37:21  来源:  作者:
C语言的类型转换 Conversion and Casting

 

通常,在语句和表达式中应使用类型相同的变量和常量。但是,如果使用混合类型,最好先了解一些基本的类型转换规则。

1 类型转换规则

1.当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int,如有必要会被转换成unsigned-int(如果short与int的大小相同,unsigned short就比int大。这种情况下,unsigned short会被转换成unsigned int)。在K&R那时的C中,float会被自动转换成double(目前的C不是这样)。由于都是从较小类型转换为较大类型,所以这些转换被称为升级(promotion)。

2.涉及两种类型的运算,两个值会被分别转换成两种类型的更高级别。

3.类型的级别从高至低依次是long-double、double、float、unsigned-long-long、long-long、unsigned-long、long、unsigned-int、int。例外的情况是,当long和int的大小相同时,unsigned-int比long的级别高。之所以short和char类型没有列出,是因为它们已经被升级到int或unsigned-int。

4.在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型。这个过程可能导致类型升级或降级(demotion)。所谓降级,是指把一种类型转换成更低级别的类型。

5.当作为函数参数传递时,char和short被转换成int,float被转换成double。

类型升级通常都不会有什么问题,但是类型降级会导致真正的麻烦。原因很简单:较低类型可能放不下整个数字。例如,一个8位的char类型变量存储整数101没问题,但是存不下22334。

如果待转换的值与目标类型不匹配怎么办?这取决于转换涉及的类型。待赋值的值与目标类型不匹配时,规则如下。

1.目标类型是无符号整型,且待赋的值是整数时,额外的位将被忽略。例如,如果目标类型是8位unsigned-char,待赋的值是原始值求模256。

2.如果目标类型是一个有符号整型,且待赋的值是整数,结果因实现而异。

3.如果目标类型是一个整型,且待赋的值是浮点数,该行为是未定义的。

2 浮点数的类型转换

如果把一个浮点值转换成整数类型会怎样?当浮点类型被降级为整数类型时,原来的浮点值会被截断。例如,23.12和23.99都会被截断为23,-23.5会被截断为-23。程序清单5.14演示了这些规则。

#include <stdio.h>
int main(void)
{
    char ch;
    int i;
    float fl;
    fl = i = ch = 'C';
     /* line 9 */
    printf("ch = %c, i = %d, fl = %2.2fn", ch, i, fl); /* line 10 */
    ch = ch + 1;
     /* line 11 */
    i = fl + 2 * ch;
     /* line 12 */
    fl = 2.0 * ch + i;
     /* line 13 */
    printf("ch = %c, i = %d, fl = %2.2fn", ch, i, fl); /* line 14 */
    ch = 1107;
     /* line 15 */
    printf("Now ch = %cn", ch);
     /* line 16 */
    ch = 80.89;
     /* line 17 */
    printf("Now ch = %cn", ch);
     /* line 18 */
    return 0;
}

运行convert.c后输出如下:

ch = C, i = 67, fl = 67.00
ch = D, i = 203, fl = 339.00
Now ch = S
Now ch = P

在我们的系统中,char是8位,int是32位。程序的分析如下。

- 第9行和第10行:字符'C'被作为1字节的ASCII值存储在ch中。整数变量i接受由'C'转换的整数,即按4字节存储67。最后,fl接受由67转换的浮点数67.00。

- 第11行和第14行:字符变量'C'被转换成整数67,然后加1。计算结果是4字节整数68,被截断成1字节存储在ch中。根据%c转换说明打印时,68被解释成'D'的ASCII码。

- 第12行和第14行:ch的值被转换成4字节的整数(68),然后2乘以ch。为了和fl相加,乘积整数(136)被转换成浮点数。计算结果(203.00f)被转换成int类型,并存储在i中。

- 第13行和第14行:ch的值('D',或68)被转换成浮点数,然后2乘以ch。为了做加法,i的值(203)被转换为浮点类型。计算结果(339.00)被存储在fl中。

- 第15行和第16行:演示了类型降级的示例。把ch设置为一个超出其类型范围的值,忽略额外的位后,最终ch的值是字符S的ASCII码。或者,更确切地说,ch的值是1107%256,即83。

- 第17行和第18行:演示了另一个类型降级的示例。把ch设置为一个浮点数,发生截断后,ch的值是字符P的ASCII码。

3 强制类型转换运算符

通常,应该避免自动类型转换,尤其是类型降级。但是如果能小心使用,类型转换也很方便。我们前面讨论的类型转换都是自动完成的。然而,有时需要进行精确的类型转换,或者在程序中表明类型转换的意图。这种情况下要用到强制类型转换(cast),即在某个量的前面放置用圆括号括起来的类型名,该类型名即是希望转换成的目标类型。圆括号和它括起来的类型名构成了强制类型转换运算符(cast operator),其通用形式是:

(type)

用实际需要的类型(如,long)替换type即可。

考虑下面两行代码,其中mice是int类型的变量。第2行包含两次int强制类型转换。

mice = 1.6 + 1.7;
mice = (int)1.6 + (int)1.7

第1行使用自动类型转换。首先,1.6和1.7相加得3.3。然后,为了匹配int类型的变量,3.3被类型转换截断为整数3。第2行,1.6和1.7在相加之前都被转换成整数(1),所以把1+1的和赋给变量mice。本质上,两种类型转换都好不到哪里去,要考虑程序的具体情况再做取舍。

一般而言,不应该混合使用类型(因此有些语言直接不允许这样做),但是偶尔这样做也是有用的。C语言的原则是避免给程序员设置障碍,但是程序员必须承担使用的风险和责任。

4 总结 C的一些运算符

下面是我们学过的一些运算符。

赋值运算符:

  • = 将其右侧的值赋给左侧的变量算术运算符:
  • + 将其左侧的值与右侧的值相加
  • - 将其左侧的值减去右侧的值
  • - 作为一元运算符,改变其右侧值的符号
  • * 将其左侧的值乘以右侧的值
  • / 将其左侧的值除以右侧的值,如果两数都是整数,计算结果将被截断
  • % 当其左侧的值除以右侧的值时,取其余数(只能应用于整数)
  • ++ 对其右侧的值加1(前缀模式),或对其左侧的值加1(后缀模式)
  • -- 对其右侧的值减1(前缀模式),或对其左侧的值减1(后缀模式)

其他运算符:

sizeof 获得其右侧运算对象的大小(以字节为单位),运算对象可以是一个被圆括号括起来的类型说明符,如sizeof(float),或者是一个具体的变量名、数组名等,

如sizeof foo(类型名) 强制类型转换运算符将其右侧的值转换成圆括号中指定的类型,如(float)9把整数9转换成浮点数9.0。



Tags:C语言 类型转换   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
通常,在语句和表达式中应使用类型相同的变量和常量。但是,如果使用混合类型,最好先了解一些基本的类型转换规则。1 类型转换规则1.当类型转换出现在表达式时,无论是unsigned还是...【详细内容】
2020-07-21  Tags: C语言 类型转换  点击:(314)  评论:(0)  加入收藏
▌简易百科推荐
一、简介很多时候我们都需要用到一些验证的方法,有时候需要用正则表达式校验数据时,往往需要到网上找很久,结果找到的还不是很符合自己想要的。所以我把自己整理的校验帮助类分...【详细内容】
2021-12-27  中年农码工    Tags:C#   点击:(1)  评论:(0)  加入收藏
引言在学习C语言或者其他编程语言的时候,我们编写的一个程序代码,基本都是在屏幕上打印出 hello world ,开始步入编程世(深)界(坑)的。C 语言版本的 hello world 代码:#include <std...【详细内容】
2021-12-21  一起学嵌入式    Tags:C 语言   点击:(10)  评论:(0)  加入收藏
读取SQLite数据库,就是读取一个路径\\192.168.100.**\position\db.sqlite下的文件<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/...【详细内容】
2021-12-16  今朝我的奋斗    Tags:c#   点击:(21)  评论:(0)  加入收藏
什么是shellshell是c语言编写的程序,它在用户和操作系统之间架起了一座桥梁,用户可以通过这个桥梁访问操作系统内核服务。 它既是一种命令语言,同时也是一种程序设计语言,你可以...【详细内容】
2021-12-16  梦回故里归来    Tags:shell脚本   点击:(16)  评论:(0)  加入收藏
一、编程语言1.根据熟悉的语言,谈谈两种语言的区别?主要浅谈下C/C++和PHP语言的区别:1)PHP弱类型语言,一种脚本语言,对数据的类型不要求过多,较多的应用于Web应用开发,现在好多互...【详细内容】
2021-12-15  linux上的码农    Tags:c/c++   点击:(17)  评论:(0)  加入收藏
1.字符串数组+初始化char s1[]="array"; //字符数组char s2[6]="array"; //数组长度=字符串长度+1,因为字符串末尾会自动添&lsquo;\0&lsquo;printf("%s,%c\n",s1,s2[2]);...【详细内容】
2021-12-08  灯-灯灯    Tags:C语言   点击:(46)  评论:(0)  加入收藏
函数调用约定(Calling Convention),是一个重要的基础概念,用来规定调用者和被调用者是如何传递参数的,既调用者如何将参数按照什么样的规范传递给被调用者。在参数传递中,有两个很...【详细内容】
2021-11-30  小智雅汇    Tags:函数   点击:(19)  评论:(0)  加入收藏
一、问题提出问题:把m个苹果放入n个盘子中,允许有的盘子为空,共有多少种方法?注:5,1,1和1 5 1属同一种方法m,n均小于10二、算法分析设f(m,n) 为m个苹果,n个盘子的放法数目,则先对...【详细内容】
2021-11-17  C语言编程    Tags:C语言   点击:(46)  评论:(0)  加入收藏
一、为什么需要使用内存池在C/C++中我们通常使用malloc,free或new,delete来动态分配内存。一方面,因为这些函数涉及到了系统调用,所以频繁的调用必然会导致程序性能的损耗;另一...【详细内容】
2021-11-17  深度Linux    Tags:C++   点击:(37)  评论:(0)  加入收藏
OpenCV(Open Source Computer Vision Library)是一个(开源免费)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android、ios等操作系统上,它轻量级而且高效---由一系列...【详细内容】
2021-11-11  zls315    Tags:C#   点击:(50)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条