本文主要讲解“c 32位程序和64位程序有什么区别”。本文的讲解内容简单明了,易学易懂。请跟随边肖的思路,一起学习学习“c 32位程序和64位程序有什么区别”。
代码上的区别
其实对于32位程序和64位程序来说,代码差别不大。严格来说,甚至是一样的。主要区别在于一些基本数据类型占用不同的字节长度(注意:这仅适用于类似Unix的平台)。
键入32位占用字节64位占用字节长48无符号长48指针48。当然这里的long包括它定义的一些类型,比如time_t,它的长度也是不同的。还有一个关于time _ t的有趣问题《什么是2038问题》。
此外,默认对齐字节数不同,32位程序为4字节,64位程序默认为8字节。字节对齐请参考《理一理字节对齐的那些事》。
可执行文件上的区别
让我们举一个小例子,看看它们之间有什么区别。
//来源:微信官方账号编程朱吉//作者:守望老师test . c # includes dio . hstructettest { inta;longb};int main(void){ printf(' sizeof(long)=% zu \ n ',sizeof(long));//long类型printf所占用的字节数(' sizeof(无符号长)=% zu \ n ',sizeof(无符号长));//unsignedlong类型structuretest={ 1,2}占用的字节数;printf(' sizeof(StructTest)=% zu \ n ',sizeof(test));//用于测试printf ('sizeof(指针)=% zu \ n ',sizeof(测试))的对齐字节数;//指针返回所占用的字节数0;}如果你的系统是64位,默认会编译成64位程序,如果需要编译成32位程序,需要带-m32参数。如果你的系统是32位的,你不能直接运行64位的程序,但是如果是64位的,你可以运行32位的程序。(其实下载软件需要选择位数的时候,要注意。如果您的系统有32位,但您下载了64位包,它自然不可用,但可以反转。)
编译32位程序以运行:
$ gcc-o测试32测试。c-m32美元。/test32sizeof (long)=4sizeof(无符号long)=4sizeof(结构测试)=8sizeof(指针)=4个编译位64位程序运行:
$ gcc-o测试64测试。c美元。/test64sizeof (long)=8sizeof(无符号long)=8 sizeof(struct test)=16 sizeof(指针)=8通过运行结果,我们也可以看到上面提到的差异。
那么可执行文件本身有什么区别呢?
$re
adelf -h test32 ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 (...)
可以看到Class属性标识为ELF32。
而对于64位:
readelf -h test64 ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64
它的属性为ELF64。实际上我们可以通过readelf发现很多信息。
例如你在进行交叉编译后出现链接错误或者最后的执行程序在目标机器无法运行,则可以查看Machine部分,看看程序是否能在你想要的平台运行。
例如64位程序中的Machine中显示的是Advanced Micro Devices X86-64,至少说明它在arm平台是没法正常运行的。
一个程序最大能申请多少内存空间?
还记得这道面试题吗?如果你只是回答Linux理论最大不超过3G,windows不超过G,那肯定是不完整的,这里必须要区分32位程序和64位程序。
这一点在《解引用NULL为什么会挂死?》中已经有所提及。32位决定了其虚拟地址空间的最大值为2^32,即4G,除去操作系统占用的1G左右,剩下3G左右,当然了这里面3G包含了所有代码,数据等,总结就是,最终能使用的不超过3G。不到3G的地址空间。(注这里并不表示它只能访问计算机4G的内存,而是表示最大寻址范围为4G)。那么64位的虚拟地址空间扩展到了17179869184G,所以,看出差别了吗?
通过上面简单的分析可以发现,64位程序理论能使用的内存是惊人的,而32位程序却非常有限,除此之外,还有一个在《什么是2038问题》》中提到的问题,就是2038年后,32位程序将很难正常使用时间相关的处理。
当然了,64位系统通常能够支持更高精度的浮点运算。
同时支持32位和64位代码编写原则
基于前面提到的原因,很多传统系统都开始着手移植到64位系统上,而如果原先代码就非常规范的话,移植工作还算比较轻松,链接64位库,编译成64位程序即可,但是如果没有遵循以下原则,那么工作量就比较大了:
依赖long类型和指针类型占用空间大小以及其表示范围
当然,对于这个原则,其表现可能非常多。
long和int混用
例如:
void test(long len) { int localLen = len; xxxx; }
这里很明显可能会发现截断。最常见的就是:
int len = sizeof(xxx);
当然,这里大多数情况下也不会有太大问题,直到其长度大于int表示范围。
慎用掩码定义
我们可能经常需要定义一些掩码:
long mask = OxFFFFFFFFL;
在 32 位系统上,这会将所有位都置位(每位全为 1),但是在 64 位系统上,只有低 32 位被置位了。结果是这个值是 0x00000000FFFFFFFF。
如果希望所有位置1,那么可以:
long mask = 1L << ((sizeof(long) * 8) - 1);
打印指针
32下,这样的没问题的:
int a = 10; int *p = &a; printf("%x",p);
但是64位下,打印不完全。自然要使用:
printf("%p",p);
传送结构体数据
在32位和64位系统中,其默认对齐字节数是不一样的。
strcut test { int a; long b; }
如果对方是64位,发送过来上述结构体数据,而你的是32位程序,可想而知,结果并不会如你所愿。前面占用空间16字节,而后者占用空间8字节。
显示定义long
如果你的数据类型是long,那么可以使用L显示说明:
long i = 1 << a;
上面的写法建议换成:
long i = 1L << a;
避免数据被截断。
感谢各位的阅读,以上就是“c++32位程序和64位程序的区别有哪些”的内容了,经过本文的学习后,相信大家对c++32位程序和64位程序的区别有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/62648.html