当前位置:首页 > 开发 > 编程语言 > C/C++ > 正文

C/C++, 类型转换 发生了什么?

发表于: 2012-04-12   作者:ChuanSu   来源:转载   浏览次数:
摘要: C语言中,数据类型间的转换,主要体现在内存间的转换,或者可以说体现在 bit 的转换,数据类型在内存的中都是以 bit 的形式体现的。 C/C++ char   1 byte short  2 bytes int    4 bytes long   4 bytes float&nbs
C语言中,数据类型间的转换,主要体现在内存间的转换,或者可以说体现在 bit 的转换,数据类型在内存的中都是以 bit 的形式体现的。
C/C++
  • char   1 byte
  • short  2 bytes
  • int    4 bytes
  • long   4 bytes
  • float  4 bytes
  • double 8 bytes

来看几个简单的例子,就会明白数据类型在转换的时候究竟发生了什么。
char ch ='A';
short s = ch;
printf("%d",s);

在console中的结果是 65。

在内存中 variable ch 是这样存储的
                65               

在内存中,数据类型都是以二进制的形式存储的,所以当看到一个十进制的数字的时候,应该时刻想着强大的数字 2
65 = 64 +1 = 2^6+2^0
char ch 占1个byte
0 1 0 0 0 0 0 1

short s = ch; 这行代码发生了什么?首先我们知道short是占2个bytes
           
所以  char ch
0 1 0 0 0 0 0 1
short s             
0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1

从上面表格可以看出 在将char ch赋值给 short s 时 只是将char ch的 8个bit copy到 short s 的低8位,而short s多余的8-bit 空间,就 just padded(填补)在这里由0填补.

再来看个例子,
int i = pow(2,23)+pow(2,21)+pow(2,14)+7;//2^23+2^21+2^14+7
short s = i;
printf("%d",s);

结果一定是 short s = 2^14+7.

上面之所以写成2的指数的形式,是为了方便书写2进制,来看下 int i 的存储形式
0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1

short s
0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1

int 型 在内存中占32 bit 但是short 型只有16 bit的空间来储存,那么以16 bit的空间去存储32 bit 的 pattern, 显然不可以,所以在C/C++ 中,就简单的将int型的低位16位 copy到 short的16位 内存空间。至于高位16位没有发生移动。这个又叫做 bit pattern copy。
所有short s = 2^14+7。

再来看个简单的例子。
short s = -1;
int i = s;
printf("%d",i);

variable short s的存储形式 为
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

注意,最高位的 1, 仅仅为一个 符号,sign,只起到标记+/-的作用。在 http://chuansu.iteye.com/blog/1435150有详细的介绍,在这不多讲了。

当 evaluate int i = s;时, int i 的内存又是如何的?
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1


在讲到第一个例子的时候,我们提到过,对于short 多余的8 bit的空间 用0填充了。
这里,因为int型 有32-bit的足够大的储存空间,所有根据bit pattern copy,就可以简单的将上面short s =-1的 16-bit copy到 int型的 32-bit储存空间,而不丢失信息。
如果和第一个例子一样,将剩余的16-bit都用0填充,那么对于int i的最高位,也就是标记位,为0,表示正数,这就不相符了。所以在C/C++中,就简单的将 short s最高位的sign 1 扩展到其余的16-bit. 这个就称作 sign extention。

最后看一道我们学校的 考试题
引用
What is the output of the following program (1P)
# include <stdio.h>

int main(void){

	unsigned char uc1 = 0x256;
	unsigned char uc2 = 12;
	printf("%d %d | %x %x\n",
			uc1,uc2,uc1,uc2);
	
	return 0;
}

16进制与2进制的相互转化一定要熟悉掌握
0x256
现转化2 -> 0010;
     5 -> 0101;
     6 -> 0110;
所以0x256 的 二进制形式为 0010 0101 0110。
由上面说到的 bit pattern copy 可以知道
unsigned char uc1 = 0x256. 只能将低8位 copy 到 char uc1的8位存储空间中。
所有 char uc1
0 1 0 1 0 1 1 0

然后转化为 10进制 就为 2^1+2^2+2^4+2^6 = 86; %d(10进制) uc1 = 86;
%x,是指 去掉0x的16进制数, uc1 = 86; 由10进制转化为16进制,以2进制为桥梁,
86 的二进制为0101 0110
然后每四个bit一组 分别转化16进制 0101 -> 2^0+2^2 = 5;
                             0110 -> 2^1+2^2 = 6;
所以86的16进制为 56。 %x uc1 = 56;

同理可得出 %d uc2 = 12; %x uc2 = C。

本文主要介绍了 在C/C++ 类型转化时发生了什么? int short char间的转化。
那么float double与 int或者 short 发生转化时又是怎样的?以及float double在内存中又是怎么存储的?

未完-待续。


C/C++, 类型转换 发生了什么?

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
《C++ Primer》中提到: “可以用 单个形参来调用 的构造函数定义了从 形参类型 到 该类类型 的一个
//===================================================================== //TITLE: // C++ VS C#
C++不像Java和C#一样在进行数据类型转换时直接调用一些类方法就可以了,使用起来很简单。   一个
这里以signed/unsigned char, signed/unsigned short, signed/unsigned int类型为例, 讨论一下基本
C#的类型转换分为两类:隐式类型转换(implicit conversions)和显式类型转换(explicit conversion
dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用。 >>>
学过编程的朋友都知道类型转换,并且也都清楚“隐式转换”、“显式转换”、“装箱”、“拆箱”等概
  上次说了关于表达式的一些内容,说到还有一些关于数据类型转换的内容,今天我们接着八一八C++中
常用C++类型总结 1、基本类型 ANSI C/C++基本数据类型: 说明: (1)类型修饰符signed和unsigned用
//===================================================================== //TITLE: // main函数
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号