使用程序获取整型数据和浮点型数据在内存中的表示。

C++中整型(int)、短整型(short int)、单精度浮点数(float)、双精度浮点数(double)在内存中所占字节数不同,因此取值范围也不同。

例如(vc++6.0编译环境下)

short   int  a=2; //此时短整型a在内存中占2个字节

int  b=2;//此时整型b在内存中占4个字节

并且有符号(signed)的整型存放数的二进制补码(正数的原码、反码、补码都相同,负数的补码是对应的反码加1),最高位为符号位,其余为数值位。

无符号(unsigned)的整型存放的都是0和正数,即无符号整型中不能存放负数,所以不存在符号位,所以所有位都是数值位。

整型数和浮点数在内存中的存储方式也是不同的,浮点数在内存中的存储分为尾数和阶码(指数),所以即使int和float数都在内存中占4个字节,但表数范围是完全不同的。

例如:作为整数的19和作为浮点数的19.0在内存中的编码是完全不同的,就因为计算机在处理整数和浮点数的方式是不同的。

 

(1)以下程序来查看float类型的数据在内存中的表示。

方法1:

  1. //查看float类型的变量在内存中的存储方式
  2. #include<iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. int i;
  7. float f;
  8. cout<<"float单精度浮点数在计算机内存中储存格式如下:"<<endl;
  9. cout<<"1位符号位,8位表示指数,23位表示尾数"<<endl<<endl;
  10. cout<<"请输入一个单精度浮点数(float):";
  11. cin>>f;
  12. unsigned int*pa =(unsigned int*)(&f);
  13. cout<<"float类型的浮点数"<<f<<"在内存的存储方式为:"<<endl;
  14. for(i=31;i>=0;i--)
  15. cout<<(*pa>>i & 1)<<(i==31||i==23?"-":" ");
  16. cout<<"\n";
  17. return 0;
  18. }

运行结果

 

方法2

  1. //查看float类型数据在内存中的存储方式
  2. #include<iostream>
  3. using namespace std;
  4. void binary_print( unsigned char c)
  5. {
  6. for(int i = 0; i < 8; ++i)
  7. {
  8. if((c << i) & 0x80)
  9. cout << '1';
  10. else
  11. cout << '0';
  12. }
  13. cout << ' ';
  14. }
  15. int main()
  16. {
  17. float a;
  18. unsigned char c_save[4];
  19. int i;
  20. void *f;
  21. f = &a;
  22. cout<<"float单精度浮点数在计算机内存中储存格式如下:"<<endl;
  23. cout<<"1位符号位,8位表示指数,23位表示尾数"<<endl<<endl;
  24. cout<<"请输入一个浮点数:";
  25. cin>>a;
  26. cout<<endl;
  27. for(i=0;i<4;i++)
  28. {
  29. c_save[i] =  *(( unsigned char*)f+i);
  30. }
  31. cout<<"float类型的浮点数"<<a<<"在计算机内存中储存格式如下:"<<endl;
  32. for(i=4;i!=0;i--)
  33. binary_print(c_save[i-1]);
  34. cout<<endl;
  35. return 0;
  36. }

运行结果

(2)以下程序来查看double类型的数据在内存中的表示。

  1. //查看double型浮点数在内存中的存储形式
  2. #include<iostream>
  3. using namespace std;
  4. void binary_print( unsigned char c)
  5. {
  6. for(int i = 0; i < 8; ++i)
  7. {
  8. if((c << i) & 0x80)
  9. cout << '1';
  10. else
  11. cout << '0';
  12. }
  13. cout << ' ';
  14. }
  15. int main()
  16. {
  17. double d;
  18. unsigned char c_save[8];
  19. int i;
  20. void *f;
  21. f = &d;
  22. cout<<"double双精度浮点数在计算机内存中储存格式如下:"<<endl;
  23. cout<<"1位符号位,11位表示指数,52位表示尾数"<<endl<<endl;
  24. cout<<"请输入一个双精度浮点数(double):";
  25. cin>>d;
  26. cout<<endl;
  27. for(i=0;i<8;i++)
  28. {
  29. c_save[i] =  *(( unsigned char*)f+i);
  30. }
  31. cout<<"双精度浮点数"<<d<<"在计算机内存中储存格式如下:"<<endl;
  32. for(i=8;i!=0;i--)
  33. binary_print(c_save[i-1]);
  34. cout<<endl;
  35. return 0;
  36. }

运行结果

从上两个例子可以看出float的17.625与double的17.625在内存中存放的字节数不同,存储格式也不同。

 

(3)以下程序来查看多种类型的数据在内存中的表示。

方法1

  1. //C++中整型和单精度浮点数在内存中所占字节数不同,取值范围也不同
  2. //以下程序来查看不同类型的数据在内存中的表示
  3. #include <iostream>
  4. using namespace std;
  5. int main()
  6. {
  7. int i;
  8. int sa;
  9. cout<<"请输入一个短整数(-32768~32767) sa=";
  10. cin>>sa;
  11. int *psa=reinterpret_cast<int *>(&sa);
  12. cout<<sa<<"在内存中的存储形式为: ";
  13. for( i=15;i>=0;i--)
  14. cout<<(*psa>>i&1)<<(i==8?" ":"");
  15. cout<<endl<<endl;
  16. int a;
  17. cout<<"请输入一个整数 a=";
  18. cin>>a;
  19. int *pa=reinterpret_cast<int *>(&a);
  20. cout<<a<<"在内存中的存储形式为: ";
  21. for( i=31;i>=0;i--)
  22. cout<<(*pa>>i&1)<<(i==24||i==16||i==8?" ":"");
  23. cout<<endl<<endl;
  24. float f;
  25. cout<<"请输入一个正浮点数(单精度) f=";
  26. cin>>f;
  27. int *pf=reinterpret_cast<int *>(&f);
  28. cout<<f<<"在内存中的存储形式为: ";
  29. for( i=31;i>=0;i--)
  30. cout<<(*pf>>i&1)<<(i==24||i==16||i==8?" ":"");
  31. cout<<endl;
  32. cout<<"按数符(1位)-指数(8位)-尾数(23位)显示为:"<<endl;
  33. for( i=31;i>=0;i--)
  34. cout<<(*pf>>i&1)<<(i==31||i==23?" ":"");
  35. cout<<endl<<endl;
  36. float ff;
  37. cout<<"请输入一个负浮点数(单精度) ff=";
  38. cin>>ff;
  39. int *pff=reinterpret_cast<int *>(&ff);
  40. cout<<ff<<"在内存中的存储形式为: ";
  41. for( i=31;i>=0;i--)
  42. cout<<(*pff>>i&1)<<(i==24||i==16||i==8?" ":"");
  43. cout<<endl;
  44. cout<<"按数符(1位)-指数(8位)-尾数(23位)显示为:"<<endl;
  45. for( i=31;i>=0;i--)
  46. cout<<(*pff>>i&1)<<(i==31||i==23?" ":"");
  47. cout<<endl;
  48. return 0;
  49. }

运行结果


 

方法2

  1. //C++中整型和单精度浮点数在内存中所占字节数不同,取值范围也不同
  2. //以下程序来查看不同类型的数据在内存中的表示
  3. #include<iostream>
  4. using namespace std;
  5. void binary_print( unsigned char c)
  6. {
  7. for(int i = 0; i < 8; ++i)
  8. {
  9. if((c << i) & 0x80)
  10. cout << '1';
  11. else
  12. cout << '0';
  13. }
  14. cout << ' ';
  15. }
  16. int main()
  17. {
  18. unsigned char c_save[8];
  19. int i;
  20. void *f;
  21. //short int整型数的存储
  22. int sn;
  23. f = &sn;
  24. cout<<"请输入一个短整型数(short int):";
  25. cin>>sn;
  26. cout<<endl;
  27. for(i=0;i<2;i++)
  28. {
  29. c_save[i] =  *(( unsigned char*)f+i);
  30. }
  31. cout<<"short int类型的整数"<<sn<<"在计算机内存中储存格式如下:"<<endl;
  32. for(i=2;i!=0;i--)
  33. binary_print(c_save[i-1]);
  34. cout<<endl<<endl;
  35. //int整型数的存储
  36. int n;
  37. f = &n;
  38. cout<<"请输入一个整型数(int):";
  39. cin>>n;
  40. cout<<endl;
  41. for(i=0;i<4;i++)
  42. {
  43. c_save[i] =  *(( unsigned char*)f+i);
  44. }
  45. cout<<"int类型的整数"<<n<<"在计算机内存中储存格式如下:"<<endl;
  46. for(i=4;i!=0;i--)
  47. binary_print(c_save[i-1]);
  48. cout<<endl<<endl;
  49. //float单精度浮点数的存储
  50. float a;
  51. f = &a;
  52. cout<<"float单精度浮点数在计算机内存中储存格式如下:"<<endl;
  53. cout<<"1位符号位,8位表示指数,23位表示尾数"<<endl<<endl;
  54. cout<<"请输入一个单精度浮点数(float):";
  55. cin>>a;
  56. cout<<endl;
  57. for(i=0;i<4;i++)
  58. {
  59. c_save[i] =  *(( unsigned char*)f+i);
  60. }
  61. cout<<"float类型的浮点数"<<a<<"在计算机内存中储存格式如下:"<<endl;
  62. for(i=4;i!=0;i--)
  63. binary_print(c_save[i-1]);
  64. cout<<endl<<endl;
  65. //double双精度浮点数的存储
  66. double d;
  67. f = &d;
  68. cout<<"double双精度浮点数在计算机内存中储存格式如下:"<<endl;
  69. cout<<"1位符号位,11位表示指数,52位表示尾数"<<endl<<endl;
  70. cout<<"请输入一个双精度浮点数(double):";
  71. cin>>d;
  72. cout<<endl;
  73. for(i=0;i<8;i++)
  74. {
  75. c_save[i] =  *(( unsigned char*)f+i);
  76. }
  77. cout<<"双精度浮点数"<<d<<"在计算机内存中储存格式如下:"<<endl;
  78. for(i=8;i!=0;i--)
  79. binary_print(c_save[i-1]);
  80. cout<<endl<<endl;
  81. return 0;
  82. }

运行结果


补充:

(1)举例将17.625换算成 float型【转】

首先,将17.625换算成二进制位:10001.101  ( 0.625 = 0.5+0.125, 0.5即 1/2, 0.125即 1/8 如果不会将小数部分转换成二进制,请参考其他书籍。) 再将10001.101 向右移,直到小数点前只剩一位 成了 1.0001101 x 2的4次方(因为右移了4位)。此时 我们的底数M和指数E就出来了:

底数部分M,因为小数点前必为1,所以IEEE规定只记录小数点后的就好,所以此处底数为  0001101 。

指数部分E,实际为4,但须加上127,固为131,即二进制数10000011

符号部分S,由于是正数,所以S为0.

综上所述,17.625的 float 存储格式就是:

0 10000011 00011010000000000000000

转换成16进制:0x41 8D 00 00

所以,一看,还是占用了4个字节。

 

(2)void类型

void的含义 
  void的字面意思是“无类型”,void  *则为“无类型指针”,void  *可以指向任何类型的数据。 
void真正发挥的作用在于:对函数返回的限定; 对函数参数的限定。 
void的使用 
    下面给出void关键字的使用规则:

 规则一:如果函数没有返回值,那么应声明为void类型

  在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。但是许多程序员却误以为其为void类型
        我们在编写C/C++程序时,对于任何函数都必须一个不漏地指定其类型。如果函数没有返回值,一定要声明为void类型。这既是程序良好可读性的需要,也是编程规范性的要求。另外,加上void类型声明后,也可以发挥代码的“自注释”作用。代码的“自注释”即代码能自己注释自己。
      规则二:如果函数无参数,那么应声明其参数为void 
      规则三:小心使用void指针类型
    按照ANSI(American  National   Standards   Institute)标准,不能对void指针进行算法操作 
      规则四:如果函数的参数可以是任意类型指针,那么应声明其参数为void   
      规则五:void不能代表一个真实的变量

void体现了一种抽象,这个世界上的变量都是“有类型”的,譬如一个人不是男人就是女人(还有人妖?)。 
   void的出现只是为了一种抽象的需要,如果你正确地理解了面向对象中“抽象基类”的概念,也很容易理解void数据类型。正如不能给抽象基类定义一个实例,我们也不能定义一个void(让我们类比的称void为“抽象数据类型”)变量。

(3)

  int *pf=reinterpret_cast<int *>(&f);

 

转自百度

reinterpret_cast

 
  reinterpret_cast是C++里的强制类型转换符。

 

  操作符修改了操作数类型,但仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换

 

  例如:int *n= new int ;

 

  double *d=reinterpret_cast<double*> (n);

 

  在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析。

 

  因此, 需要谨慎使用 reinterpret_cast.

 

  == ===========================================

 

  == static_cast .vs. reinterpret_cast

 

  == ================================================

 

  reinterpret_cast是为了映射到一个完全不同类型的意思,这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的,这是所有映射中最危险的。(这句话是C++编程思想中的原话)

 

  static_cast和reinterpret_cast的区别主要在于多重继承,比如

 

  class A { public: int m_a; };

 

  class B { public: int m_b; };

 

  class C : public A, public B {};

 

  那么对于以下代码:

 

  C c;

 

  printf("%p, %p, %p\r\n", &c, reinterpret_cast<B*>(&c), static_cast <B*>(&c));

 

  前两个的输出值是相同的,最后一个则会在原基础上偏移4个字节,这是因为static_cast计算了父子类指针转换的偏移量,并将之转换到正确的地址(c里面有m_a,m_b,转换为B*指针后指到m_b处),而reinterpret_cast却不会做这一层转换。

 

  因此, 你需要谨慎使用 reinterpret_cast.

 
 

reinterpret_cast<char*>(&st)   和  (char *)(&st)     有什么区别?

第1.  reinterpret_cast勉强算有点类型检查,如果你把一个不是地址的东西给他转就会出错

第2.  reinterpret_cast只做指针类型转换的这件事情,而不做其它转换, 这看起来是个缺点?其实这防止你不小心做错事, 比如把一个const的指针不小心转成非const了

第3.  reinterpret_cast这个形式容易找, (char*)这个形式没法查找。

C形式的类型转换的问题就是它太强大了, 强大就容易被滥用,滥用的结果就是类型检查形同虚设。 所以C++推荐用新形式的,比较弱些的转换, 确保你知道你自己在做什么而不是对所有类型不匹配用一个转换了事

 

使用程序获取整型数据和浮点型数据在内存中的表示---gyy整理的更多相关文章

  1. Cocos2d-x 3.1.1 学习日志2--error:仅仅有静态常量整型数据成员才干够在类中初始化

        今天遇到比較低端的一个问题,就是成员的初始化问题,编译器也无法验证,不同的编译器有些能过有些不能过,我也不知道为什么,总是我们以vs为准吧,以为我们用的环境就是它,话不多说.解决方式例如以下: ...

  2. js获取整型数组最大值、最小值、平均值

    ---恢复内容开始--- let values = [];//数组(整型数字) //获取数组最大值function arrMaxNum(arr){ var maxNum = null; for (va ...

  3. jstree获取整棵树的json数据

    $("#树ID").jstree(true).get_json();

  4. C语言中字符型,整数型,浮点型在内存中如何存储

    ···void main() { unsigned char a = 97; printf("%p",&a); printf("%c,%d\n", a, ...

  5. 【转载】你真的会浮点数与整型数的"互转"吗?

    看了标题,你是不是觉得这TM是哪个iOS彩笔写的入门文章.好的,那咱们先来看看几个例题,看看你有没有白白点进来! int main() { float a = -6.0; int *b = & ...

  6. C语言之四则运算表达式求值(链栈)—支持浮点型数据,负数, 整型数据运算

     运算符间的优先级关系: 链栈结构体定义: 数据域使用字符串长度为20的字符数组(故需要注意判断读取的字符串是运算符还是数值) 可支持浮点型数据,负数, 整型数据的运算 float EvaluateE ...

  7. 剑指offer40:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字

    1 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 2 思路和方法 (1)异或:除了有两个数字只出现了一次,其他数字都出现了两次.异或运算中,任 ...

  8. Android jni 编程3(对基本类型一维整型数组的操作)总结版

    主要学习资料:黑马程序员的NDK方法使用(生产类库so)              jni编程指南中文版(已上传至博客园) 博主文章(它使用的是VS和eclipse联合开发):http://www.c ...

  9. 使用头文件climits中的符号常量获知整型数据的表数范围---gyy整理

    在头文件climits(limits.h)以宏定义的方式定义了各种符号常量来表示各种整型类型表示数的范围,如int的最大最小值,long的最大最小值等. 符号常量 表示 CHAR_BIT char 的 ...

随机推荐

  1. 开发者需要知道的11条HTML5小常识

    #HTML5: The Missing Manual# 如果说HTML是一部电影,那HTML5就是一次大转折.HTML本来是不会活过21世纪的.官方Web标准组织W3C在1998年对HTML就已经撒手 ...

  2. RestFul && HATEOAS && Spring-Data-Rest介绍

    1.什么是RestFul 经常上网的同学会发现,现代软件的一个重要趋势就是互联网化,几乎没有一款软件是纯粹的单机版了.通常的情况下,软件管理着服务器的资源以及这些资源的状态变化,用户通过在浏览器输入h ...

  3. DTCMS展示一级栏目并展示各自栏目下的二级栏目

    c#代码中 <!--C#代码--> <%csharp%> string parent_id=DTRequest.GetQueryString("parent_id&q ...

  4. HTML5 drag & drop 拖拽与拖放简介

    DataTransfer 对象:退拽对象用来传递的媒介,使用一般为Event.dataTransfer. draggable 属性:就是标签元素要设置draggable=true,否则不会有效果,例如 ...

  5. (转)[Erlang 0080] RabbitMQ :VHost,Exchanges, Queues,Bindings and Channels

    和RabbitMQ这个项目的缘分好奇怪,很长一段时间内是只关注源代码,真的是Erlang开源项目中的典范;现在要在项目中应用RabbitMQ,从新的视角切入,全新的感觉.仿佛旧情人换了新衣,虽是熟稔却 ...

  6. [OC] UITabBarController

    1. New CocoaTouch class -> Select Objective C -> named RootViewController 2. Disable APC error ...

  7. 用python实现了一下:甲乙两人互猜数字(数理逻辑)

    今天在园子里看到博客:超难面试题:甲乙两人互猜数字(数理逻辑).然后琢磨了半天,写了个Python程序实现算法,我得出来的结果是1,6或1,8或35,42的组合, 不知道是否正确,请高人指点? 下面列 ...

  8. 开始学习python

    刚刚离开学校,到公司实习,发现所有的技术都是崭新的,所有的工具都是熟悉中带着陌生. 就像是孤身一人到了一个曾经只闻其名的偌大城市,看什么都觉得新鲜,做什么都心有畏惧.幸好 搞软件并没有那么多人情世故, ...

  9. 1010. Radix (25)

    Given a pair of positive integers, for example, 6 and 110, can this equation 6 = 110 be true? The an ...

  10. The Black Hole of Numbers (strtoint+inttostr+sort)

    For any 4-digit integer except the ones with all the digits being the same, if we sort the digits in ...