博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据模型(LP32 ILP32 LP64 LLP64 ILP64 )
阅读量:4947 次
发布时间:2019-06-11

本文共 2158 字,大约阅读时间需要 7 分钟。

数据模型(LP32 ILP32 LP64 LLP64 ILP64 )

 

32位环境涉及"ILP32"数据模型,是因为C数据类型为32位的int、long、指针。而64位环境使用不同的数据模型,此时的long和指针已为64位,故称作"LP64"数据模型。

现今所有64位的类Unix平台均使用LP64数据模型,而64位Windows使用LLP64数据模型,除了指针是64位,其他基本类型都没有变。

TYPE                    LP32    ILP32    LP64    ILP64    LLP64
CHAR                       8          8          8          8          8
SHORT                   16        16        16        16        16
INT                         16         32        32        64        32
LONG                     32        32         64        64        32
LONG LONG          64        64         64        64        64
POINTER                32       32          64        64        64

在这张表中,LP64,ILP64,LLP64是64位平台上的字长模型,ILP32和LP32是32位平台上的字长模型。

LP64意思是long和pointer是64位,

ILP64指int,long,pointer是64位,

LLP64指long long和pointer是64-bit的。

ILP32指int,long和pointer是32位的,

LP32指long和pointer是32位的。

 

float 都是4字节;

double 都是8字节;(C中直接写小数,默认是double型)

 

这 3 个 64 位模型(LP64、LLP64 和 ILP64)之间的区别在于非浮点数据类型。当一个或多个 C 数据类型的宽度从一种模型变换成另外一种模型时,应用程序可能会受到很多方面的影响。这些影响主要可以分为两类:

  • 数据对象的大小。编译器按照自然边界对数据类型进行对齐;换而言之,32 位的数据类型在 64 位系统上要按照 32 位边界进行对齐,而 64 位的数据类型在 64 位系统上则要按照 64 位边界进行对齐。这意味着诸如结构或联合之类的数据对象的大小在 32 位和 64 位系统上是不同的。
  • 基本数据类型的大小。通常关于基本数据类型之间关系的假设在 64 位数据模型上都已经无效了。依赖于这些关系的应用程序在 64 位平台上编译也会失败。例如,sizeof (int) = sizeof (long) = sizeof (pointer) 的假设对于 ILP32 数据模型有效,但是对于其他数据模型就无效了。

总之,编译器要按照自然边界对数据类型进行对齐,这意味着编译器会进行 “填充”,从而强制进行这种方式的对齐,就像是在 C 结构和联合中所做的一样。结构或联合的成员是根据最宽的成员进行对齐的。

 

 

 

 数据类型转换原则

 

 

 

 

结构体对齐,默认对齐原则:

1.数据类型对齐值:
        char型数据自身对齐值为1
        short为2,int、float为4,double为8(windows)
        解释:
                char变量只要有一个空余的字节即可存放
                short要求首地址能被2整除
                int、float、double同理
2.结构体的对齐值:
        其成员中自身对齐值最大的那个值。
        解释:
                结构体最终对齐按照数据成员中最长的类型的整数倍
指定对齐原则:
使用#pragma pack改变默认对其原则
格式:
#pragma pack (value)时的指定对齐值value。
结构体最终对齐按照指定对齐值的整数倍
注意:
1.value只能是:1 2 4 8等
2.指定对齐值与数据类型对齐值相比取较小值
如:如果指定对齐值:
设为1:则short、int、float等均为1
设为2:则char仍为1,short为2,int 变为2

 

移位运算

左移<<
        将一个数的二进制位左移,高位丢弃,低位补0
        例:a = a<<2 将a的二进制数左移2位,右补0
        若a=15,即二进制数0 0 0 01111
        左移2位得0 011110 0,(十进制数60)
>>算术右移
        有符号数,如果为正数,则左边移入0,右边丢弃
        如果为负数,左边移入1,右边丢弃
>>逻辑右移
        不关心正数、负数,左边均移入0,右边丢弃
        算术或者逻辑右移,由编译器决定

 

博主今天在写代码的时候遇到一个奇怪的问题,程序的要求是实现一个int的移位操作,不管左移还是右移,空出来的位置通通置0即逻辑移位。一开始没注意太多直接用了<<和>>移位操作符,结果却发现实现是错误的==!

经过查证发现,c语言中的移位操作符,在左移时执行的是逻辑移位,在右移时执行的是算术移位。那怎么用>>实现右移操作呢?
又经过查证得知,无符号数的移位操作都是执行的逻辑移位。那么要想用>>实现逻辑右移就可以将操作数强制类型转化为unsigned类型,如下:

int a = 0xfffffffe;

int b = (unsigned int)a >> 1;

执行的结果是2147483647即7fffffff,可见其右移后左端补的是0。
综上:C语言中移位操作符实现的是逻辑左移和算术右移,但是算术左移和逻辑左移的效果相同,算术右移和逻辑右移的效果不同,要实现逻辑右移可将操作数强制类型转化为无符号数

 

转载于:https://www.cnblogs.com/lsgxeva/p/7614856.html

你可能感兴趣的文章
C语言 memcpy二维数组的复制
查看>>
Infix to Postfix Expression
查看>>
win7任务栏还原为xp样式
查看>>
PYTHON_3和2
查看>>
json数组的取值方法
查看>>
2019-7-15 vue01day
查看>>
SELECT LOCK IN SHARE MODE and FOR UPDATE
查看>>
Perl/Nagios – Can’t locate utils.pm in @INC
查看>>
目录导航「深入浅出ASP.NET Core系列」
查看>>
Git常用命令拾遗
查看>>
Canvas的drawImage方法使用
查看>>
自定义适用于手机和平板电脑的 Dynamics 365(四):窗体脚本
查看>>
阴影效果参考网址
查看>>
华为交换机端口镜像
查看>>
简易爬虫(爬取本地数据)
查看>>
一位菜鸟的java 最基础笔记
查看>>
python 进程间通信
查看>>
字符串和编码
查看>>
servlet(一)
查看>>
异常实验
查看>>