?01、ANSI C
在ANSI C中資料型別包括:整形,浮點型,指標和聚合型(如陣列和結構等)
?
整形:
字符,短整型,整型和長整型,他們都分別有有符號(singed)和無符號(unsingned)
取值范圍:
沒有帶signed或者unsigned,默認signed
?
長整型至少應該和整型一樣長,而整型至少應該和短整型一樣長
在32位環境中,各種資料型別的長度一般如下:
?
02、ARM C
具體我們以IAR為編譯器,版本7.2
注意:
在32位ARM中,字是32位,半字是16位,位元組是8位
?
可以看到以下關于整型的資料型別
?
下面使用typedef重新定義資料型別,沒有使用到long,因為都是32位的有一個int就夠了
typedef unsigned char uint8; //!< 無符號8位整型變數 typedef signed char int8; //!< 有符號8位整型變數 typedef unsigned short uint16; //!<無符號16位整型變數 typedef signed short int16; //!< 有符號16位整型變數 typedef unsigned int uint32; //!< 無符號32位整型變數 typedef signed int int32; //!<有符號32位整型變數 typedef float fp32; //!< 單精度浮點數(32位長度) typedef double fp64; //!< 雙精度浮點數(64位長度)
03、C語言記憶體分配方法
在標準C語言中,編譯出來的可執行程式分為代碼區(text)、資料區(data)和未初始化資料區(bss)3個部分,如下代碼
#include <stdlib.h> int a = 0; //a在全域已初始化資料區 char *p1; //p1在BSS區(未初始化全域變數) void main() { int b; //b在堆疊區 int c; //C為全域(靜態)資料,存在于已初始化資料區 char s[] = "abc"; //s為陣列變數,存盤在堆疊區, char *p2,*p3; //p2、p3在堆疊區 p2 = (char *)malloc(10);//分配得來的10個位元組的區域在堆區 p3 = (char *)malloc(20);//分配得來的20個位元組的區域在堆區 free(p2); free(p3); }
?
使用linux編譯之后得到的可執行檔案如下
?
可以看到代碼區(text)、資料區(data)和未初始化資料區(bss),
代碼段(text):存放代碼的地方,只能訪問,不能修改,代碼段就是程式中的可執行部分,直觀理解代碼段就是函式堆疊組成的,
資料段(data):全域變數和靜態區域變數存放的地方,也被稱為資料區、靜態資料區、靜態區:資料段就是程式中的資料,直觀理解就是C語言程式中的全域變數,注意是全域變數或靜態區域變數,區域變數不算,
未初始化資料區(bss):bss段的特點就是被初始化為0,bss段本質上也是屬于資料段,
那么問題來了,為什么要區分data段和bss段呢?
以下面代碼為例,a.c和b.c的差異只是有沒有給arr陣列賦值,
?
可以看到a.out的bss段大,b.out的data段大,但是b.out的檔案大小明顯比a.out的大很多,
?
那么就可以簡單理解為,data段會增大可執行檔案的大小,而bss段不會,
這里我說下自己的理解,我并沒有找到資料驗證:
data段是全域變數,但是需要初始化值,上面我的例子是全部初始全部為1,但也可能是1024*1024個不同的資料,而這些資料需要保存起來,表現出來也就是需要保存在可執行檔案中,
bss段也是全域變數,但不需要初始化值,只需要保存一下這個全部變數的保存的資料型別和大小即可,即使它的陣列容量是1024*1024,也不會占用很多可執行檔案的大小,
這里再說明一個問題:如果一個全部變數初始化為0,那么它也是bss段,不是data段,即使你代碼中把它初始化為0了,這點大家可以自行驗證,
關于資料段,也就是data段,也會分為RO data(只讀資料段)和RW data(讀寫資料段),
從字面意思就可以區分他們的意思,不同的是:
只讀資料段:程式使用的一些不會被更改的資料,使用這些資料的方式類似查表式的操作,由于這些變數不需要更改,因此只需要放置在只讀存盤器中即可,
讀寫資料段:程式中是可以被更改的資料,且初始化過的,所以需要放置在RAM中,且初始化的內容放在存盤器中(表現為放入可執行檔案中),
這樣又可以磁區只讀區和讀寫區域,如下所所示(當然bss段和下文的堆疊也是讀寫區)
?
上面說到“編譯出來的可執行程式分為代碼區(text)、資料區(data)和未初始化資料區(bss)3個部分”,那運行中就會多出來一些區域,這就是我們常說的堆疊,注意堆疊是兩個區域堆和堆疊,
堆疊:區域變數、函式一般在堆疊空間中,運行時自動分配&自動回收:堆疊是自動管理的,程式員不需要手工干預,方便簡單,是提前分配好的連續的地址空間,堆疊的增長方向是向下的,即向著記憶體地址減小的方向,
堆:堆記憶體管理者總量很大的作業系統記憶體塊,各行程可以按需申請使用,使用完釋放,程式手動申請&釋放:手工意思是需要寫代碼去申請malloc和釋放free,可以是不連續的地址空間,堆的增長方向是向上的,即向著記憶體地址增加的方向,
?
下面是簡單的演示代碼
?
#include <stdlib.h> #include <stdio.h> int bss_var; //未初始化全域資料存盤在BSS區 int data_var=42; //初始化全域資料存盤在資料區 int main(int argc,char *argv[]) { char *p ,*b; printf("Adr bss_var:0x%x\n",&bss_var); printf("Adr data_var:0x%x\n",&data_var); printf("the %s is at adr:0x%x\n","main",&main); p=(char *)alloca(32); //從堆疊中分配空間 if(p!=NULL) { printf("the p start is at adr:0x%x\n",p); printf("the p end is at adr:0x%x\n",p+31); } b=(char *)malloc(32*sizeof(char)); //從堆中分配空間 if(b!=NULL) { printf("the b start is at adr:0x%x\n",b); printf("the b end is at adr:0x%x\n",b+31); } free(b); //釋放申請的空間,以避免記憶體泄漏 while(1); }
?
運行結果如下
?
記憶體分配示意圖如下
??
?
??
點擊查看本文所在的專輯,STM32F207教程
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/383967.html
標籤:其他
