VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 187|回复: 2

[分享] 32位和64位下各种数据类型大小的对比

[复制链接]
51_avatar_middle
online_admins Syc 发表于 2018-8-30 23:55:37 | 显示全部楼层 |阅读模式
今天一位学员遇到了这方面的问题,关于为什么 long 类型在 windows 上是 4个字节,在 linux 上是 8个字节?于是看到了这篇文章,感觉讲解的不错,转载过来,希望大家能从中学到东西!

1、基本数据类型大小的对比
关于数据类型的大小,总是记不住,这里也算有个记录,顺便看一下32位和64位之间的差别:

我写了一小段测试代码:
  1. // C++Test.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <iostream>  
  6. #include <string>  
  7. using namespace std;  

  8. int _tmain(int argc, _TCHAR* argv[])  
  9. {  
  10.     cout << "sizeof(char):" << sizeof(char) << endl;  
  11.     cout << "sizeof(short):" << sizeof(short) << endl;  
  12.     cout << "sizeof(int):" << sizeof(int) << endl;  
  13.     cout << "sizeof(long):" << sizeof(long) << endl;  
  14.     cout << "sizeof(long long):" << sizeof(long long) << endl;  
  15.     cout << "sizeof(unsigned int):" << sizeof(unsigned int) << endl;  
  16.     cout << "sizeof(float):" << sizeof(float) << endl;  
  17.     cout << "sizeof(double):" << sizeof(double) << endl;  
  18.     void* pointer;  
  19.     cout << "sizeof(pointer):" << sizeof(pointer) << endl;  
  20.   
  21.     system("pause");  
  22.     return 0;
  23. }
复制代码



看一下结果:

Win32 下:
sizeof(char):1
sizeof(short):2
sizeof(int):4
sizeof(long):4
sizeof(long long):8
sizeof(unsigned int):4
sizeof(float):4
sizeof(double):8
sizeof(pointer):4
请按任意键继续. . .

x64 下:
sizeof(char):1
sizeof(short):2
sizeof(int):4
sizeof(long):4
sizeof(long long):8
sizeof(unsigned int):4
sizeof(float):4
sizeof(double):8
sizeof(pointer):8

32位和64位系统在Windows下基本数据类型的大小都是一样的。
只有指针的大小不一样,32位指针大小为4byte,而64位的指针大小为8byte。

注:Linux下,long 型是 64位的,这一点是和Windows不同的地方。

PS:64位系统下是可以运行32位程序的。但是反过来的话是运行不了的。我在一台32位的机器上运行上面的64位的程序,就会弹出如下提示:
32位和64位下各种数据类型大小的对比

2、为什么 Win x64下 long 也为 4 byte?

我们知道,正常标准的话,long应该也是64位即 8byte。但是在 Windows 下,我们的结果却是 4byte。为什么会这样呢?这里引用MSDN的一段关于

x64下的解释:
Platform SDK: 64-bit Windows Programming
Abstract Data Models
Every application and every operating system has an abstract data model. Many applications do not explicitly expose this data model, but the model guides the way in which the application's code is written. In the 32-bit programming model (known as the ILP32 model), integer, long, and pointer data types are 32 bits in length. Most developers have used this model without realizing it. For the history of the Win32? API, this has been a valid (although not necessarily safe) assumption to make.

In 64-bit Microsoft? Windows?, this assumption of parity in data type sizes is invalid. Making all data types 64 bits in length would waste space, because most applications do not need the increased size. However, applications do need pointers to 64-bit data, and they need the ability to have 64-bit data types in selected cases. These considerations led to the selection of an abstract data model called LLP64 (or P64). In the LLP64 data model, only pointers expand to 64 bits; all other basic data types (integer and long) remain 32 bits in length.
Initially, most applications that run on 64-bit Windows will have been ported from 32-bit Windows. It is a goal that the same source, carefully written, should run on both 32- and 64-bit Windows. Defining the data model does not make this task easier. However, ensuring that the data model affects only pointer data types is the first step. The second step is to define a set of new data types that allow developers to automatically size their pointer-related data. This allows data associated with pointers to change size as the pointer size changes from 32 bits to 64 bits. Basic data types remain 32 bits in length, so there is no change in the size of data on the disk, data shared over a network, or data shared through memory-mapped files. This relieves developers of much of the effort involved in porting 32-bit code to 64-bit Windows.
These new data types have been added to the Windows API header files. Therefore, you can start using the new types now. For more information, see The New Data Types.

简单解释一下:
我们编程时很少关注数据类型真正的大小,毕竟即使不关注这个也可以编程,而且我们习惯了Win32,到64位下,只有指针因为寻址需要是必须变成64位的,64位的指针寻址范围是0~2^64-1,而其他的数据类型基本已经够用,如果把所有数据类型变成64位,明显是浪费空间。再者,为了让32位和64位程序兼容运行,能少修改还是少修改,所以Windows仅将指针大小进行了修改。这样,程序可以兼容运行。

3、指针的大小
我们看看指针到底有多大?指向不同类型对象的指针大小是不是会有不同?看一个小例子:
  1. // C++Test.cpp : 定义控制台应用程序的入口点。  
  2. //  

  3. #include "stdafx.h"  
  4. #include <iostream>  
  5. #include <string>  
  6. using namespace std;  
  7.   
  8. class Test  
  9. {  
  10.     int num;  
  11.     string name;  
  12. };

  13. //一个函数指针  
  14. typedef void(*pFunc)(void);  
  15. void PrintHello(void)  
  16. {  
  17.     cout << "hello world" << endl;  
  18. }


  19. int _tmain(int argc, _TCHAR* argv[])  
  20. {  
  21.     int* pInt;  
  22.     void* pVoid;  
  23.     Test* pTest = new Test();  
  24.     pFunc pfunc = PrintHello;  
  25.     cout << "sizeof(pInt):" << sizeof(pInt) << endl;  
  26.     cout << "sizeof(pVoid):" << sizeof(pVoid) << endl;  
  27.     cout << "sizeof(pTest):" << sizeof(pTest) << endl;  
  28.     cout << "sizeof(pFunc):" << sizeof(pfunc) << endl;  
  29.   
  30.     system("pause");  
  31.     return 0;  
  32. }
复制代码


结果:
Win32下:
sizeof(pInt):4
sizeof(pVoid):4
sizeof(pTest):4
sizeof(pFunc):4
请按任意键继续. . .

x64下:
sizeof(pInt):8
sizeof(pVoid):8
sizeof(pTest):8
sizeof(pFunc):8
请按任意键继续. . .

可见,不管指针指向张三李四还是王二麻子,都是一样大的。能够影响指针大小的,还是位数。32位下指针大小为4,64位下指针的大小为 8。

4、string的大小:
关于 string 的大小,我们写一小段代码测试一下:
  1. // C++Test.cpp : 定义控制台应用程序的入口点。  
  2.   
  3. #include "stdafx.h"  
  4. #include <iostream>  
  5. #include <string>  
  6. using namespace std;  
  7. //main  
  8. int _tmain(int argc, _TCHAR* argv[])  
  9. {  
  10.     string empty("");  
  11.     string name("hehe");  
  12.     string longstr("dfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");  
  13.     cout << sizeof(empty) << endl;  
  14.     cout << sizeof(name) << endl;  
  15.     cout << sizeof(longstr) << endl;  
  16.     cout << sizeof(string) << endl;  
  17.     system("pause");  
  18.     return 0;  
  19. }
复制代码


结果:
Win32下:
28
28
28
28
请按任意键继续. . .

x64下:
32
32
32
32
请按任意键继续. . .

32位和64位下 string 差 4byte,其实就是一个指针的差别。string内部并不保存字符串本身,而是保存了一个指向字符串开头的指针。




上一篇:发一套自己写的捕获异常并打印调用堆栈的代码

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

51_avatar_middle
online_vip zxnnnnn 发表于 2018-8-31 23:30:17 | 显示全部楼层
学习了!!!

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

08_avatar_middle
在线会员 SummerGull 发表于 2018-9-1 11:56:18 | 显示全部楼层
这我晓得。 看看就行 没必要很细致

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /1 下一条

QQ
QQ在线咨询
联系电话
13591366679
手机扫一扫 关注本站精彩内容
wxqrcode

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-9-20 19:36

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表