linux C编程(四)int占用字节数/大小端模式/数据类型自动转换/结构体内存占用

来源:互联网 发布:53端口攻击 编辑:程序博客网 时间:2024/06/03 12:29

数据类型占用字节数

首先强调,不同数据类型的内存占用大小不固定,与编译器有关,与CPU的位数和操作系统的位数无关。但编译器仍然受CPU的字长影响。具体常用的标准如下:

type 32字长 64字长 char 8 8 short 16 16 int 32 32 long 64 64 pointer 32 64

对于16位或者8位的单片机而言有的可能采用16位作为int

大小端模式

定义

小端模式:数据的高字节保存在内存的高地址中,低字节保存在内存的低地址中
大端模式:数据的高字节保存在低地址中,低字节保存在高地址中
例如对于占4个字节的int数据0x12345678来说,其大小端的存储模式如下图

记忆:“小端低低”~
intel的CPU为小端模式,大部分的arm,DSP也为小端模式,有的ARM支持硬件选择大小端模式

大小端存储示意

如何测试编译器是大/小端

考虑如下代码

#include <stdio.h>int main(){  short int x;  char x0,x1;  x = 0x1122;  x0 = ((char *)&x)[0];//低地址单元  x1 = ((char *)&x)[1];//高地址单元  if(x0 = 0x22)    printf("Little Endian\n");  else    printf("Big Endian\n");  return 0;}

需要考虑大小端问题的场合

1.所写程序需要向不同的硬件平台迁移,迁移平台可能是大端也可能是小端。在编程之前,为了保证可移植性,需要事先考虑。

2.不同类型机器之间通过网络传送二进制数据时。字符串通信时不需这种情况。

数据类型自动转换

自动转换主要发生在不同类型的数据进行的混合运算中。遵循以下规则:
(1)若参与运算的类型不一致,先全部转为同一类型,然后进行运算
(2)转换按照数据长度增加的方向进行,以保证不降低精度
(3)short与char在参与运算时全部都要先自动转换成int类型或者更高的类型(不论是否由变量的混合)
(4)赋值运算时默认将右边类型转为左边类型,精度可能降低,float转int遵循去掉小数点,不是四舍五入

char,short -> int -> unsigned -> long -> double
float -> double

结构体内存占用

考虑以下结构体在64位编译器上占用的内存大小

#pragma pack(4)//PPB = 4struct{int ld;//4个字节,align = min(4,PPB)=4,offset = 0,occupy 0~3 byteschar color[5];//1个字节,align = min(1,PPB)=1,offset = 4,occupy 4~8 bytesunsigned short age;//2个字节,align = min(2,PPB)=2,offset = 10,occupy 10~11 byteschar *name;//8个字节,align = min(8,PPB)=4,offset = 8,occupy 12~19 bytesvoid (*jump)(void);//8个字节,align = min(8,PPB)=4,occupy 20~27 bytes}Garfield;#pragma pack()

由上面的分析可得该结构体内容占用空间为28字节。由于28字节正好是min(PPB,sizeof(char *))的整数倍,因此最终的结构体占用空间也为28字节。

综上,结构体内存对齐原则:
(1)结构体中的每个元素都认为内存是以它自己的大小来划分的,因此元素的偏移位置一定是在自己宽度的整数倍上开始。(首变量偏移为0)
(2)在按照(1)中放置后,结构体的整体大小需要为结构体中宽度最大的变量的宽度的整数倍。不满足则需补齐。
(3)若使用#pragma pack(PPB)指令对齐,则(1)中的个元素的偏移位置为PPB与本身宽度的较小值。原则(2)中的宽度最大变量的宽度也要换为min(PPB,宽度最大变量的宽度)。

0 0
原创粉丝点击