数据模型(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语言中移位操作符实现的是逻辑左移和算术右移,但是算术左移和逻辑左移的效果相同,算术右移和逻辑右移的效果不同,要实现逻辑右移可将操作数强制类型转化为无符号数

数据模型(LP32 ILP32 LP64 LLP64 ILP64 )的更多相关文章

  1. 数据模型LP32 ILP32 LP64 LLP64 ILP64

    各个C++实现所选择采用的基础类型的大小统称为"数据模型".有四种广泛采用的数据模型: 32 位系统: LP32 或 2/4/4(int 为 16-bit,long 和指针为 32 ...

  2. 关于LP64,ILP64,LLP64,ILP32,LP32字长(数据)模型

    太长不看: 1.32位Windows和类Unix使用ILP32字长模型,64位Windows使用ILP64模型,64位类Unix使用LP64字长模型. 2.根据1,long在32位和64位Window ...

  3. [转]关于int整形变量占有字节问题

    int的长度由处理器(16位,32位,64位)和比哪一期决定. 首先从处理器来讲 :16位处理器中的int 占有16位 即2个字节                         32位处理器中int ...

  4. 【C语言】32位,64位机器sizeof区别

    float, double : 采用IEEE标准浮点数格式,格式固定 float 32bit, double 64bit int一般和CPU寄存器长度有关,不过也和编译器,汇编器有关 由于C ,C++ ...

  5. 【转】将 Linux 应用程序移植到 64 位系统上

    原文网址:http://www.ibm.com/developerworks/cn/linux/l-port64.html 随着 64 位体系结构的普及,针对 64 位系统准备好您的 Linux® 软 ...

  6. ARM-常见考题和知识点

    1. ARMv7 7中状态,ARMv8对应的状态 2. TEE知识 3. ARM寄存器及作用 4. ARM内部总线AHB APB 5. 1. Thumb | Arm指令区别 编写Thumb指令时,先要 ...

  7. ILP32、ILP64、LP64、LLP64、64位系统

    Data Type     ILP32      ILP64     LP64      LLP64char              8             8            8     ...

  8. int 和 long的区别

    数据模型决定了C语言中基本数据类型与数据宽度的对应关系.我们常用的32位模型称为ILP32,而64位模型有三种:LP64.LLP64和ILP64.在64位模型中,指针一定是64位的,但是int和lon ...

  9. Unix/Linux环境C编程入门教程(23) 字符数字那些事儿

    1.atoi 包含头文件: #include <stdlib.h> 函数原型: int atoi( const char *str ); 功能:将字符串str转换成一个整数并返回结果.参数 ...

随机推荐

  1. jmeter 分布式实战

    最近作者在公司部署公司的分布式压力测试情况的时候,遇到了问题,什么问题呢,各种错误,于是大晚上的为了不耽误压测,我们就两个同事两台电脑搞,可是还是不行的呢,我要研究研究这个是什么梗,于是乎,大晚上加班 ...

  2. 一款简单而不失强大的前端框架——【Vue.js的详细入门教程①】

    ↓— Vue.js框架魅力 —↓ 前言       Vue.js 是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.V ...

  3. Matlab入门学习(文件读写)

    一.save,load >> a=[ ]; >> b=[ ] b = >> save('b.mat','a','b');%a file named b.mat wi ...

  4. Azure Powershell使用已有Image创建ARM非托管磁盘虚拟机

    生成Image映像文件,记录好Image的URL(下面URL为测试URL,具体请参考实际):ImageURL:https://hlmrgstoragen.blob.core.chinacloudapi ...

  5. oracle pl/sql 分页

    一.无返回值的存储过程 古人云:欲速则不达,为了让大家伙比较容易接受分页过程编写,我还是从简单到复杂,循序渐进的给大家讲解.首先是掌握最简单的存储过程,无返回值的存储过程. 案例:现有一张表book, ...

  6. Finally-操作返回值

    Finally中操作返回会出现一个问题?直接看代码 static int M1() { ; try { result = result + ; //======引发异常的代码========== , ...

  7. Linux入门之常用命令(14) kill

    Linux kill 命令使用详解 功能说明:删除执行中的程序或工作. 语 法:kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>] 补充说明: ...

  8. 关于select的一个错误---属性选择器

    错误: jquery 获取下拉框 text='1'的 option 的value 属性值  我写的var t= $("#selectID option[text='1']).val() ; ...

  9. #翻译#原文来自Database.System.Concepts(6th.Edition.2010)2.6Relational Operations,原文作者Abraham Silberschaz , Henry F. Korth , S. Sudarshan

    2.6关系操作 所有的过程关系查询语言都提供一组操作,这些操作可以应用于单个关系或一对关系.这些操作具有良好的和期望的属性,它们的结果总是一个单一的关系.这个属性允许一个以模块化的方式组合其中的几个操 ...

  10. Theano学习-scan循环

    \(1.Scan\) 通用的一般形式,可用于循环 减少和映射(对维数循环)是特殊的 \(scan\) 对输入序列进行 \(scan\) 操作,每一步都能得到一个输出 \(scan\) 能看到定义函数的 ...