99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

淺析嵌入式C語言的高級用法

5RJg_mcuworld ? 來源:未知 ? 作者:胡薇 ? 2018-09-25 15:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1、內(nèi)存管理

我們需要知道——變量,其實是內(nèi)存地址的一個抽像名字罷了。在靜態(tài)編譯的程序中,所有的變量名都會在編譯時被轉(zhuǎn)成內(nèi)存地址。機器是不知道我們?nèi)〉拿值?,只知道地址?/p>

內(nèi)存的使用時程序設計中需要考慮的重要因素之一,這不僅由于系統(tǒng)內(nèi)存是有限的(尤其在嵌入式系統(tǒng)中),而且內(nèi)存分配也會直接影響到程序的效率。因此,我們要對C語言中的內(nèi)存管理,有個系統(tǒng)的了解。

在C語言中,定義了4個內(nèi)存區(qū)間:代碼區(qū);全局變量和靜態(tài)變量區(qū);局部變量區(qū)即棧區(qū);動態(tài)存儲區(qū),即堆區(qū);具體如下:

1>棧區(qū)(stack)— 由編譯器自動分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。

2>堆區(qū)(heap)— 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表。

3>全局區(qū)(靜態(tài)區(qū))(static)—全局變量和靜態(tài)變量的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的 另一塊區(qū)域。 - 程序結(jié)束后由系統(tǒng)釋放。

4>常量區(qū)—常量字符串就是放在這里的。 程序結(jié)束后由系統(tǒng)釋放。

5>程序代碼區(qū)—存放函數(shù)體的二進制代碼。我們來看張圖:

圖1

首先我們要知道,源代碼編譯成程序,程序是放在硬盤上的,而非內(nèi)存里!只有執(zhí)行時才會被調(diào)用到內(nèi)存中!我們來看看程序結(jié)構(gòu),ELF是是Linux的主要可執(zhí)行文件格式。ELF文件由4部分組成,分別是ELF頭(ELF header)、程序頭表(Program header table)、節(jié)(Section)和節(jié)頭表(Section header table)。具體如下:

1>Program header描述的是一個段在文件中的位置、大小以及它被放進內(nèi)存后所在的位置和大小。即要加載的信息;

2>Sections保存著object 文件的信息,從連接角度看:包括指令,數(shù)據(jù),符號表,重定位信息等等。在圖中,我們可以看到Sections中包括:

text 文本結(jié) 存放指令;

rodata 數(shù)據(jù)結(jié) readonly;

data 數(shù)據(jù)結(jié) 可讀可寫;

3>Section頭表(section header table)包含了描述文件sections的信息。每個section在這個表中有一個入口;每個入口給出了該section的名字,大小,等等信息。相當于 索引!

而程序被加載到內(nèi)存里面,又是如何分布的呢?我們看看上圖中:

1正文和初始化的數(shù)據(jù)和未初始化的數(shù)據(jù)就是我們所說的數(shù)據(jù)段,正文即代碼段;

2>正文段上面是常量區(qū),常量區(qū)上面是全局變量和靜態(tài)變量區(qū),二者占據(jù)的就是初始化的數(shù)據(jù)和未初始化的數(shù)據(jù)那部分;

3>再上面就是堆,動態(tài)存儲區(qū),這里是上增長;

4>堆上面是棧,存放的是局部變量,就是局部變量所在代碼塊執(zhí)行完畢后,這塊內(nèi)存會被釋放,這里棧區(qū)是下增長;

5>命令行參數(shù)就是001之類的,環(huán)境變量什么的前面的文章已經(jīng)講過,有興趣的可以去看看。

我們知道,內(nèi)存分為動態(tài)內(nèi)存和靜態(tài)內(nèi)存,我們先講靜態(tài)內(nèi)存。

1.1靜態(tài)內(nèi)存

存儲模型決定了一個變量的內(nèi)存分配方式和訪問特性,在C語言中主要有三個維度來決定:存儲時期 、作用域 、鏈接。

1、存儲時期存儲時期:變量在內(nèi)存中的保留時間(生命周期)存儲時期分為兩種情況,關鍵是看變量在程序執(zhí)行過程中會不會被系統(tǒng)自動回收掉。

1) 靜態(tài)存儲時期 Static在程序執(zhí)行過程中一旦分配就不會被自動回收。通常來說,任何不在函數(shù)級別代碼塊內(nèi)定義的變量。無論是否在代碼塊內(nèi),只要采用static關鍵字修飾的變量。

2) 自動存儲時期 Automatic除了靜態(tài)存儲以外的變量都是自動存儲時期的,或者說只要是在代碼塊內(nèi)定義的非static的變量,系統(tǒng)會肚臍自動非配和釋放內(nèi)存;

2、作用域作用域:一個變量在定義該變量的自身文件中的可見性(訪問或者引用)在C語言中,一共有3中作用域:1) 代碼塊作用域在代碼塊中定義的變量都具有該代碼的作用域。從這個變量定義地方開始,到這個代碼塊結(jié)束,該變量是可見的;

2) 函數(shù)原型作用域出現(xiàn)在函數(shù)原型中的變量,都具有函數(shù)原型作用域,函數(shù)原型作用域從變量定義處一直到原型聲明的末尾。

3) 文件作用域一個在所有函數(shù)之外定義的變量具有文件作用域,具有文件作用域的變量從它的定義處到包含該定義的文件結(jié)尾處都是可見的;

3、鏈接鏈接:一個變量在組成程序的所有文件中的可見性(訪問或者引用);C語言中一共有三種不同的鏈接:1) 外部鏈接如果一個變量在組成一個程序的所有文件中的任何位置都可以被訪問,則稱該變量支持外部鏈接;

2) 內(nèi)部鏈接如果一個變量只可以在定義其自身的文件中的任何位置被訪問,則稱該變量支持內(nèi)部鏈接。

3) 空鏈接如果一個變量只是被定義其自身的當前代碼塊所私有,不能被程序的其他部分所訪問,則成該變量支持空鏈接

我們來看一個代碼示例:

#include

inta = 0;// 全局初始化區(qū)

char*p1;//全局未初始化區(qū)

intmain()

{

intb;//b在棧區(qū)

chars[] = "abc";//棧

char*p2; //p2在棧區(qū)

char*p3 = "123456";//123456