C/C++类型转换到底发生了什么[转]

— 转载
C/C++中, 浮点数,float以及 double 在内存中是怎样存储的?

假如,我有32-bit

C语言中,数据类型间的转换,主要体现在内存间的转换,或者可以说体现在 bit 的转换,数据类型在内存的中都是以 bit 的形式体现的。
C/C++

  • char 1 byte
  • short 2 bytes
  • int 4 bytes
  • long 4 bytes
  • float 4 bytes
  • double 8 bytes

来看几个简单的例子,就会明白数据类型在转换的时候究竟发生了什么。

1
2
3
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

01000001

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

所以 char ch

01000001

short s

0000000001000001

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

1
2
3
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

0100000000000111

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

再来看个简单的例子。

1
2
3
short s = -1;  
int i = s;
printf("%d",i);

variable short s的存储形式 为

1111111111111111

注意,最高位的 1, 仅仅为一个 符号,sign,只起到标记+/-的作用。这有详细的介绍 , 这里就不多讲了

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

在讲到第一个例子的时候,我们提到过,对于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)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 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

01010110

然后转化为 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在内存中又是怎么存储的?

转自: http://chuansu.iteye.com/blog/1484742