那曲檬骨新材料有限公司

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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

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

淺析嵌入式C語(yǔ)言的高級(jí)用法

5RJg_mcuworld ? 來(lái)源:未知 ? 作者:胡薇 ? 2018-09-25 15:44 ? 次閱讀

1、內(nèi)存管理

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

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

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

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

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

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

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

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

圖1

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

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

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

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

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

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

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

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

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

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

3>再上面就是堆,動(dòng)態(tài)存儲(chǔ)區(qū),這里是上增長(zhǎng);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

我們來(lái)看一個(gè)代碼示例:

#include

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

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

intmain()

{

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

chars[] = "abc";//棧

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

char*p3 = "123456";//123456

太阳城在线| 沾益县| 金界百家乐官网的玩法技巧和规则| 百家乐群121398015| 乐百家乐官网彩现金开户| 大发888游戏充值| 至尊百家乐20111110| 属鸡和属猪做生意好吗| 通州区| 大发8888娱乐场| 百家乐出老千视频| 百家乐官网视频游戏网址| 大发888| 百家乐赔率计算| 百家乐游戏机子| 真人百家乐官网的玩法技巧和规则| 百家乐官网代理博彩正网| 乐九| 棋牌新闻| 赌球网址| 百家乐怎么稳赢| 百家乐闲拉长龙| 兰桂坊百家乐官网的玩法技巧和规则 | 百家乐官网法则| 百家乐官网赌博凯时娱乐| 百家乐官网园胎教网| 新加坡百家乐的玩法技巧和规则| 百家乐官网路单走势图| 百家乐官网投注方法多不多| 法老王娱乐城| 任你博| bet365直播| 大发888注册送钱| 百家乐筹码片| 百家乐最好投注| 百家乐真人视屏游戏| A8百家乐娱乐城| 百家乐官网娱乐网网77scs| 百家乐官网网站加盟| 百家乐官网赌场老千| 冀州市|