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 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章