c语言中的类型转换

原创 2006年04月05日 00:17:00

    首先引出一个问题,这是我在编写模拟器程序的时候遇到的,我们有如下的类型转换:

       int16_t     v16s;
       uint16_t   v16u;
       int32_t     v32s;
       uint32_t   v32u;

       v16s = 0xf08b;     v16u = (uint16_t)v16s; //请问此时v16s和v16u在二进制表示形式上有什么不同吗? No.1
       v32s = (int32_t)v16s;      v32u = (uint32_t)v16s; //请问此时v32s和v32u在二进制表示形式上相同吗? No.2
       v16s = 0x0f8b;  v32s=(int32_t)v16s;   v32u=(uint32_t)v16s; //请问此时v32s和v32u的值又是多少? No.3
       v32s = 0xffff0fb8; v16s=(int16_t)v32s; v16u=(uint16_t)v32s;//请问此时v16s和v16u的值是多少? No.4
       v16s = 0xf08b; v16u=0xf08b;  v32s=(int32_t)v16s; v32u=(uint32_t)v16u; //请问此时v32s和v32u的值是多少? No.5

首先告诉大家答案:

  1. No.1:请问此时v16s和v16u在二进制表示形式上有什么不同吗?
    二者在二进制表示形式上没有区别,都是0xf08b,所以如果不进行运算操作,在同样长度的简单数据类型之间进行强制类型转换是不必要的,编译器会略去你的工作,不信的话,你可以查看生成的汇编代码,对于No.1问题对转换语句,根本就不生成代码!!
  2. No2:请问此时v32s和v32u在二进制表示形式上相同吗?
    二者在二进制表示形式上是相同的!都是0xfffff08b!这里可能会犯错的地方在 v32u=(uint32_t)v16s这个语句上,我就是这么犯的错误。按照我错误的理解是:0xf08b → 0x0000f08b!这是不对的!原因后面再告诉你(当然如果你C语言学的够好,就觉得我再弄小儿科了^_^,照顾一下后进者)。
  3. No.3:请问此时v32s和v32u的值又是多少?
    此时v32s和v32u的值都是 0x00000f8b!
  4. No.4:请问此时v16s和v16u的值是多少?
    此时v16s和v16u的值都是0x0fb8!
  5. No.5:此时v32s的值是0xfffff08b,v32u的值是0x0000f08b。在进行自动类型转换的时候,如果原来的数是无符号数,那么在扩展的时候,高位填充的是0;如果是有符号数,那么高位填充的时符号位!这一点有点类似于“>>”操作符,当无符号数右移的时候,高位填充的是0;有符号数右移的时候,高位填充的是符号位。
    好了,下面我就来告诉你,为什么是上面的结果。这就需要我们回头复习一下C语言的有关类型转换的操作。C语言的类型转换,可以分为两种:自动类型转换(隐式类型转换,有编译器帮你去完成)和强制类型转换(你知道自己想要什么,所以才转换)。
    对于自动类型转换,最常见的就是混合运算以及赋值运算,还有一种就是函数值的类型转换
  1. 赋值运算:自动把“=”右边的表达式的类型转换成“=”右边的变量的类型,例如 int a=4.5; a的值实际是4!
  2. 混合运算:就是一个运算表达式当中包含了多个类型,这时候就需要有类型转换。当运算符两边的操作数类型不同时,其中一个操作数就要经过类型转换以和另一个操作数的类型相一致,然后才能进行运算。
    变换操作数采取就高不就低的原则,即级别低的操作数先被转换成和级别高的操作数具有同一类型,然后再进行运算,结果的数据类型和级别高的操作数相同。

           高        double    ←←    float
           ↑          ↑             
           ↑         long     
           ↑          ↑
           ↑        unsigned
           ↑          ↑
           低         int
          ←←    char,short

                 自动转换顺序表

  3. 函数返回值的类型转换: int f1(){ return 36.8;}
    强制类型转换运算符
    可以利用强制类型转换运算符将一个表达式转换成所需类型:
    例如:
  (double)a       (将a转换成double类型)
     (int)(x+y)      (将x+y的值转换成整型)
     (float)(5%3)    (将5%3的值转换成float型)
     (int)(1.5+2.3) = ? 
      (int)1.5+2.3=?
    注意,表达式应该用括号括起来。如果写成(int)x+y 则只将x转换成整型,然后与y相加。

    讲到这里,您或许就明白了,哦,原来我们是使用了强制类型转换的语法,但是程序实质上却是自动类型转换! 所以在执行了语句:v16s = 0xf08b;  v32s=(int32_t)v16s;    v32u=(uint32_t)v16s; 后v32s和v32u的二进制表示形式才是一样的!
    对于从高到低的强制转换,实质上就是一个截断的操作,只把低端需要的部分保留,其余的部分直接扔掉了。所以对于语句:
v32s = 0xffff0fb8; v16s=(int16_t)v32s; v16u=(uint16_t)v32s; 执行之后v16s和v16u的二进制表示形式才是一样的!
    注:我一直强调的都是它们的二进制表示形式是否相同,而没有说它们的值是否相同,因为同样的二进制表示形式,你把它当作有符号数和无符号数的值在决大部分的情况下都是不同的(除了最高位为0的相同外,其他都不同)

    混合运算

 混合运算是指在一个表达式中参与运算的对象不是相同的数据类型,例如:
  2*3.1416*r 3.1416*r*r 3.6*a%5/(*b)+'f';
 如果r为int型变量,a为float型变量,b为double型变量,则以上三个表达式中涉及到的数据类型有整型、实型、字符型,这种表达式称为混合类型表达式。对混合类型表达式的求解要进行混合运算,此时首要的问题是对参与运算的数据进行类型转换。

下面给出类型转换的示例,以加深理解。设有如下变量说明:
  int a, j, y; float b; long d; double c;
  则对赋值语句:
  y=j+'a'+a*b-c/d;
  其运算次序和隐含的类型转换如下:
  ① 计算a*b,由于变量b为float型,所以运算时先由系统自动转换为double型,变量a为int型,两个运算对象要保持类型一致,变量a也要转换为double,运算结果为double型。
  ② 由于c为double型,将 d 转换成 double 型,再计算 c/d,结果为double型。
  ③ 计算j+'a',先将'a'(char型)转换成整型数再与j相加,结果为整型。
  ④ 将第1步和第3步的结果相加,先将第3步的结果(int)转换成double型再进行运算,结果为double型。
  ⑤ 用第4步的结果减第2步的结果,结果为double型。
  ⑥ 给y赋值,先将第5步的结果double型转换为整型(因为赋值运算左边变量y为整型),即将double型数据的小数部分截掉,压缩成int型,然后进行赋值。
  以上步骤中的类型转换都是C语言编译系统自动完成的。

C语言类型转换详解

前言:C语言的类型转换是很多初学者的难点,但也是语言的重点。在此,介绍一下C语言类型转换的知识。注意本文是以gcc编译器为基准。 一、            变量 1、 基本类型变量 说到基本类...
  • zhangzhi123456789
  • zhangzhi123456789
  • 2015年11月02日 17:07
  • 4532

深入理解C语言类型转换

C语言类型转换分为两种: 显式强制类型转换 隐式自动类型转换 也许有人遇到过一个负数经过类型转换后可能变成一个很大的整数之类,却不知道实质上是因为什么。希望下面的解释能够解决这个疑惑。下面从详细介绍一...
  • simple_the_best
  • simple_the_best
  • 2015年09月13日 21:50
  • 1624

C语言运算中的数据类型自动转换原则

1、隐式转换     C在以下四种情况下会进行隐式转换:        1、算术运算式中,低类型能够转换为高类型。        2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给...
  • cherish_2012
  • cherish_2012
  • 2014年03月14日 17:19
  • 24169

深入理解C语言-----各数据类型大小

首先看下C标准中“未明确定义”的三种类型Implementation-defined、Unspecified和Undefined。(以下内容部分摘自宋劲彬老师的文章) Implementation...
  • simon_uestc
  • simon_uestc
  • 2014年02月24日 11:31
  • 6534

C语言中的基本数据类型

IOS学写字 本文目录 一、变量二、类型修饰符三、不同编译器环境下基本数据类型的存储长度 说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上...
  • smxueer
  • smxueer
  • 2014年10月07日 16:39
  • 2598

C语言中的四种存储类型

首先来说说数据的类型,所有的数据都有两种类型,一是常见的数据类型,如int,float等,一种便是今天的重头戏,存储类型。总共有四种存储类型的变量,分别为自动变量(auto)、静态变量(static)...
  • u014041012
  • u014041012
  • 2015年06月11日 23:51
  • 1599

C语言系列(一)基本数据类型

C语言helloworld1.声明头文件,相当于java的导包。 //只有函数的声明,编译时会去找到函数的实现 #include 2.写main()方法 main(){ ...
  • u011974987
  • u011974987
  • 2016年08月06日 21:50
  • 2530

c语言数据类型

在标准头文件发明以前就有了用户自定义类型。 u_ 用户自定义, user u -- 无符号 unsigned 一般来说,一个C的工程中一定要做一些这方面的工作,因为你会涉及到跨平台,不同的平台...
  • shenwansan_gz
  • shenwansan_gz
  • 2015年02月10日 16:23
  • 965

c语言-数据类型-构造类型

利用计算机存处理单一的数据是比较容易,比如一个人的某一科成绩,直接创建一个变量存储相应的分数就可以了,但是要同时处理多个科目的时候,这时候就有点麻烦了,同时创建多个变量存储多个科目这样子显得有点奇怪不...
  • OnionOmelette
  • OnionOmelette
  • 2015年02月04日 18:47
  • 3496

C语言数据类型

原文:http://zhidao.baidu.com/question/116383335.html?an=0&si=1   C语言各种数据类型及其在系统中占的字节和取值范围2009-08-2...
  • he_you_min
  • he_you_min
  • 2015年07月23日 17:45
  • 955
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c语言中的类型转换
举报原因:
原因补充:

(最多只允许输入30个字)