1. 程式人生 > >C語言:位元組排序與記憶體四區(I)

C語言:位元組排序與記憶體四區(I)

I.位元組排序概念:

位元組順序是指佔記憶體多於一個位元組型別的資料在記憶體中的存放順序,通常有小端(Little-endian)、大端(Big-endian)兩種位元組順序。小端位元組序指低位元組資料存放在記憶體低地址處,高位元組資料存放在記憶體高地址處;大端位元組序是高位元組資料存放在低地址處,低位元組資料存放在高地址處。
測試程式碼:

   #include<stdio.h>
   #include<stdlib.h>
   int main(int argc,char **argv){
     int int_variable = 0x12345678
; unsigned char *char_p=(unsigned char *)&int_variable; /* *將int的變數int_variable強制型別轉換為unsigned char,這樣 *就可以使用下標運算子“[]”的形式打印出int型變數int_variable */ printf("%x\n",char_p[0]); //以十六進位制的形式打印出變數值 printf("%x\n",char_p[1]); printf("%x\n",char_p[2]); printf("%x\n"
,char_p[3]); system("pause"); return 0; }

大端與小端中的位元組資料在記憶體中的存放形式分別如下圖所示:
這裡寫圖片描述

地址從i開始,以上面程式碼中的int變數值0x12345678為例作為示範;

II.記憶體四區

在講解記憶體四區之前,完全有必須對c中的變數種類進行說明一下:
一.c與中有3中作用域:
1.全域性變數
在函式外宣告的變數為全域性變數,全域性變數在任何地方都是可見的。
2.檔案內部的靜態變數
關鍵字:static ,宣告為static(靜態)的變數其作用域只限定於在當前的原始碼檔案中,對外面的其他原始碼檔案是不可見的。
3.區域性變數
在函式內或者是函式中宣告的變數為區域性變數,區域性變數只能在宣告它的語句塊中被應用,外面的檔案是不能引用的。

二. 儲存器
1.靜態儲存器(static storage duration)
靜態變數包括:全域性變數、檔案內的static變數、指定static的區域性變數。
2,自動儲存器
沒有指定static的區域性變數,

在c中對變數進行進行操作,其實就是間接地對記憶體進行操作,這是因位變數的本質:就是記憶體的別名,變數就相當於一個門牌號(變數具有兩張面孔)。總結出:c中有3種記憶體區域的壽命。
1.靜態變數
壽命:從程式執行開始,到程式執行結束
2.自動變數
壽命:從宣告該語句塊到該語句塊結束
3.使用malloc()分配的記憶體區域
壽命:到free()為止。

知道了變數在記憶體中的作用域和生命週期以後,再來看這些變數在記憶體中是如何被分配的。通過以下程式碼來作說明,該程式碼中包含了以上作業域和生命週期的變數。

#include<stdio.h>
#include<stdlib.h>

int global_variable;
static int st_file_variable;

void func1(void){
   int func1_variable;
   static int func1_static_variable;
   printf("&func1_variable:%p\n",&func1_variable);
   printf("&func1_static_variable:%p\n",&func1_static_variable);
}

void func2(void){
   int func2_variable;
   printf("&func2_variable:%p\n",&func2_variable);
}

int main(int argc,char *argv[]){
    int *int_p;//定義指向int的指標變數int_p,用來動態malloc申請記憶體

    printf("&func1:%p\n",&func1); //輸出函式func1的首地址
    printf("&func2:%p\n",&func2); //輸出函式func2的首地址
    printf("&string_numbers:%p\n","abcdefg");//輸出字串常量地址
    printf("&global_variable:%p\n",&global_variable); //全域性變數
   printf("&st_file_variable:%p\n",&st_file_variable);
   //輸出靜態變數
   func1();//輸出函式func1中的區域性變數
   func2();//輸出函式func2中的區域性變數func2_variable

   int_p=(int *)malloc(sizeof(int));
   //通過malloc動態申請記憶體,記憶體的首地址返回給int_p指標
   printf("malloc_address:%p\n",int_p);//輸出記憶體地址
   system("pause");
   return 0;
}

執行結果:
這裡寫圖片描述

由於輸出的變數地址太多,看不出什麼規律,因此把上面的執行結果中的地址重新排列後,整理出如下表:
這裡寫圖片描述

通過該表中的變數的地址可分析:
1.兩個函式的地址(指向函式的指標)和字串常量被分配在非常靠近的位置;
2.靜態檔案變數和函式內的靜態變數、以及全域性變數被分配在非常靠近的位置;
3.malloc()分配的記憶體地址空間,和自動變數的地址距離得非常遠;
4.而兩個函式中的自動變數的地址完全一樣。

畫個圖來形象的描述下:
這裡寫圖片描述

未完待續···············