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

数据类型占用字节数
首先强调,不同数据类型的内存占用大小不固定,与编译器有关,与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 = 4
struct{
int ld;
//4个字节,align = min(4,PPB)=4,offset = 0,occupy 0~3 bytes
char color[5];
//1个字节,align = min(1,PPB)=1,offset = 4,occupy 4~8 bytes
unsigned short age;
//2个字节,align = min(2,PPB)=2,offset = 10,occupy 10~11 bytes
char *name;
//8个字节,align = min(8,PPB)=4,offset = 8,occupy 12~19 bytes
void (*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,宽度最大变量的宽度)。
--------------------- 
作者:遍地流金 
来源:CSDN 
原文:https://blog.csdn.net/u012177034/article/details/52316863 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/qq_19004627/article/details/85848819
今日推荐