色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 學(xué)習(xí)筆記 > 嵌入式學(xué)習(xí)筆記:C高級(jí)函數(shù)快速學(xué)

嵌入式學(xué)習(xí)筆記:C高級(jí)函數(shù)快速學(xué) 時(shí)間:2018-09-12      來(lái)源:未知

c高級(jí)可以說(shuō)是就比較難了,尤其是c高級(jí)函數(shù)這是學(xué)習(xí)的難點(diǎn),那么如何快速學(xué)c高級(jí)函數(shù)呢,下面總結(jié)了一些函數(shù)知識(shí)點(diǎn)及案例,可以快速學(xué)哦。

1.1定義

返回值類(lèi)型 函數(shù)名(類(lèi)型 形參, 類(lèi)型 形參, ...)

{

語(yǔ)句

語(yǔ)句

return 返回值

}

函數(shù)名:標(biāo)識(shí)符:用一眼要能看懂函數(shù)的功能的標(biāo)識(shí)符來(lái)表示函數(shù)名

返回值類(lèi)型:需要返回的返回值類(lèi)型

當(dāng)不需要返回值時(shí),返回值類(lèi)型為void,return后邊需要加返回值

當(dāng)返回值類(lèi)型為指針時(shí),稱(chēng)為指針函數(shù)

形參: 接收外部參數(shù)的局部變量

不需要接收參數(shù)時(shí), 寫(xiě)為void

6.2函數(shù)的調(diào)用

變量 = 函數(shù)名(實(shí)參1, 實(shí)參2, ......);

實(shí)參:傳給函數(shù)的變量或常量值。

運(yùn)行過(guò)程:為形參分空間,把實(shí)參賦值給形參

運(yùn)行函數(shù)中的程序

返回調(diào)用函數(shù),運(yùn)行調(diào)用點(diǎn)的下一行

補(bǔ)充:多窗口:vsp

1.3函數(shù)的作用范圍

1.3.1 提前聲明,擴(kuò)大定義域(extern)

實(shí)例:

1.3.2 在文件中,調(diào)用另一個(gè)文件中定義的函數(shù)

編譯命令:gcc a.c b.c -g:編譯兩個(gè)文件的時(shí)候,執(zhí)行依然是a.out

1.3.3. 禁止別的文件調(diào)用本文件的函數(shù)(static)

注意:用了statics的話,不同文件中是可以存在相同的文件名的。

stati將函數(shù)的作用范圍限制在本文件中

1.4變量的作用范圍(這里詳細(xì)的打開(kāi)內(nèi)存分配的部分及逆行講解)

1.4.1. 定義

全局變量:定義在函數(shù)外的變量,也可以理解為定義在{}外的變量。

局部變量:定義在函數(shù)內(nèi)的變量,也可以理解為定義在{}內(nèi)的變量。

需要定義在{}的開(kāi)始。

1.4.2 作用域(默認(rèn)作用范圍)

全局變量:從定義開(kāi)始到文件的結(jié)束

局部變量:從定義開(kāi)始到與之前一個(gè)對(duì)應(yīng)的{ }結(jié)束。

注意:小作用范圍的變量,屏蔽大作用范圍的變量

解釋?zhuān)?/p>

這里的擴(kuò)大作用范圍是針對(duì)全局變量來(lái)說(shuō)的,局部變量不能擴(kuò)大

方法:1)使用的位置在定義之前

2)使用的位置子其他文件

3)限制全局變量的作用范圍到默認(rèn)作用域

4)函數(shù)的作用域是從定義開(kāi)始,到本文件結(jié)束(針對(duì)文件來(lái)說(shuō))

實(shí)例:

1.5內(nèi)存的分配

1.5.1.程序未運(yùn)行時(shí)(size a.out可以看到信息)

text:存放CPU可執(zhí)行的機(jī)器指令,由于程序被經(jīng)常使用,防止其被意外修改,代碼區(qū)通常是只讀的。

data: 存放被初始化的全局變量、靜態(tài)變量(全局靜態(tài)變量和局部靜態(tài)變量)、常量數(shù)據(jù)(如字符串常量)。

Bss:存放未初始化的全局變量 (初始化成0,計(jì)算機(jī)并不認(rèn)為這是做了初始化操作,所以初始化成0的全局變量會(huì)被放在bss區(qū)中)

注意:BSS區(qū)的數(shù)據(jù)在程序開(kāi)始執(zhí)行之前被內(nèi)核初始化為0或空指針(NULL)。

具體:

1.5.2.程序運(yùn)行時(shí)

程序運(yùn)行時(shí)占用5個(gè)區(qū):代碼區(qū)、初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)、未初始化數(shù)據(jù)區(qū)、堆區(qū)、棧區(qū)

(1)代碼區(qū)(text)

代碼區(qū)指令根據(jù)程序設(shè)計(jì)流程依次執(zhí)行,對(duì)于順序指令,則只會(huì)執(zhí)行一次,如果反復(fù),則需使用跳轉(zhuǎn)指令,如果進(jìn)行遞歸,則需借助棧來(lái)實(shí)現(xiàn)。

代碼區(qū)包括操作碼和要操作的對(duì)象(或?qū)ο蟮牡刂芬?,如果是立即數(shù)(即具體的數(shù)值,如2),將直接包含在代碼中;如果是局部數(shù)據(jù),將在棧中分配空間,然后引用該數(shù)據(jù)的地址;如果是BSS區(qū)和數(shù)據(jù)區(qū),在代碼中同樣引用該數(shù)據(jù)的地址。

(2) 全局初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)(data)

在編譯的時(shí)候就會(huì)初始化,并且只初始化一次。上面已經(jīng)說(shuō)過(guò),在程序編譯時(shí),該區(qū)域已經(jīng)被分配好了,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在,當(dāng)程序結(jié)束時(shí),才會(huì)被釋放。

(3)未初始化數(shù)據(jù) 區(qū)(BSS):在運(yùn)行時(shí)改變其值。初始化0不算初始化。

(4)棧區(qū)(stack)

存放函數(shù)的參數(shù)值和局部變量,由編譯器自動(dòng)分配釋放,其操作方式類(lèi)似于數(shù)據(jù)結(jié)構(gòu)的棧。其特點(diǎn)是不需要程序員去考慮內(nèi)存管理的問(wèn)題,很方便;同時(shí)棧的容量很有限,在Linux系統(tǒng)中,棧的容量只有8M,并且當(dāng)相應(yīng)的范圍結(jié)束時(shí)(如函數(shù)),局部變量就不能再使用。

(5)堆區(qū)(heap)

有些操作對(duì)象只有在程序運(yùn)行時(shí)才能確定,這樣編譯器在編譯時(shí)就無(wú)法為他們預(yù)先分配空間,只有程序運(yùn)行時(shí)才分配,這就是動(dòng)態(tài)內(nèi)存分配。堆區(qū)就是用于動(dòng)態(tài)內(nèi)存分配(如malloc的動(dòng)態(tài)內(nèi)存分配),堆在內(nèi)存中位于bss區(qū)和棧區(qū)之間,一般由程序員申請(qǐng)和釋放(free釋放或程序停止)。

實(shí)例:

注意:

(1):堆區(qū)的內(nèi)存需要程序員自己釋放。

(2):棧區(qū)在范圍結(jié)束時(shí),編譯器就會(huì)釋放了,所以要注意棧區(qū)中數(shù)據(jù)的生命周期。

(3):棧區(qū)容量有限,注意不要使用超大局部變量,比如超大數(shù)組。

(4):bss區(qū)中的數(shù)據(jù),你不進(jìn)行初始化的話,系統(tǒng)會(huì)幫我們初始化成0。但其他區(qū)域的數(shù)據(jù),系統(tǒng)不會(huì)為我們做什么,尤其注意堆區(qū)和棧區(qū)中的數(shù)據(jù),未經(jīng)初始化的變量則有可能是臟數(shù)據(jù)。

1.6變量的生命周期

1.6.1分類(lèi)

1. data和bss中的變量的生命周期:程序的開(kāi)始到程序的結(jié)束。==>全局變量,靜態(tài)(全局/局部)變量

2. 棧中的變量的生命周期:函數(shù)的開(kāi)始到函數(shù)的結(jié)束。==>局部變量,形參

6.6.2對(duì)靜態(tài)局部變量的說(shuō)明:

有時(shí)希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保留原值,即其占用的存儲(chǔ)單元不釋放,在下一次該函數(shù)調(diào)用時(shí),該變量保留上一次函數(shù)調(diào)用結(jié)束時(shí)的值。這時(shí)就應(yīng)該指定該局部變量為靜態(tài)局部變量(static local variable)。

(1) 靜態(tài)局部變量在靜態(tài)存儲(chǔ)區(qū)內(nèi)分配存儲(chǔ)單元。在程序整個(gè)運(yùn)行期間都不釋放。而自動(dòng)變量(即動(dòng)態(tài)局部變量)屬于動(dòng)態(tài)存儲(chǔ)類(lèi)別,存儲(chǔ)在動(dòng)態(tài)存儲(chǔ)區(qū)空間(而不是靜態(tài)存儲(chǔ)區(qū)空間),函數(shù)調(diào)用結(jié)束后即釋放。

(2) 為靜態(tài)局部變量賦初值是在編譯時(shí)進(jìn)行值的,即只賦初值一次,在程序運(yùn)行時(shí)它已有初值。以后每次調(diào)用函數(shù)時(shí)不再重新賦初值而只是保留上次函數(shù)調(diào)用結(jié)束時(shí)的值。而為自動(dòng)變量賦初值,不是在編譯時(shí)進(jìn)行的,而是在函數(shù)調(diào)用時(shí)進(jìn)行,每調(diào)用一次函數(shù)重新給一次初值,相當(dāng)于執(zhí)行一次賦值語(yǔ)句。

(3) 如果在定義局部變量時(shí)不賦初值的話,對(duì)靜態(tài)局部變量來(lái)說(shuō),編譯時(shí)自動(dòng)賦初值0(對(duì)數(shù)值型變量)或空字符(對(duì)字符型變量)。而對(duì)自動(dòng)變量來(lái)說(shuō),如果不賦初值,則它的值是一個(gè)不確定的值。這是由于每次函數(shù)調(diào)用結(jié)束后存儲(chǔ)單元已釋放,下次調(diào)用時(shí)又重新另分配存儲(chǔ)單元,而所分配的單元中的值是不確定的。

(4) 雖然靜態(tài)局部變量在函數(shù)調(diào)用結(jié)束后仍然存在,但其他函數(shù)是不能引用它的,也就是說(shuō),在其他函數(shù)中它是“不可見(jiàn)”的。

具體解釋?zhuān)?/p>

初始化全局變量未初始化全局變量局部變量靜態(tài)全局變量靜態(tài)局部變量

占用存儲(chǔ)空間data

bss棧datadata

初始化次數(shù)初始化一次

初始化一次每次調(diào)用都初始化初始化一次初始化一次

作用域默認(rèn)作用域,可擴(kuò)大默認(rèn)作用域,可擴(kuò)大默認(rèn)作用域默認(rèn)作用域默認(rèn)作用域

生命周期程序開(kāi)始->程序結(jié)束 程序開(kāi)始->程序結(jié)束定義開(kāi)始,函數(shù)結(jié)束程序開(kāi)始->程序結(jié)束程序開(kāi)始->程序結(jié)束

補(bǔ)充:register變量

register int r_local = 6;要求編譯器盡量放在寄存器,register變量是不能做取地址操作的

register使用寄存器變量會(huì)提升速度,也并不是說(shuō)我們盡可能地多地定義register變量就能加快程序的運(yùn)行速度,畢竟CPU中寄存器是有限的,

如果你把變量指定為register變量,意味著可用于別的用途的寄存器就減少了,如程序運(yùn)算產(chǎn)生的中間結(jié)果,它們的應(yīng)用又很頻繁,

在寄存器不足的情況下,只好借助于內(nèi)存,這樣反倒會(huì)降低程序的運(yùn)算速度。

在現(xiàn)今的C版本中,大多已沒(méi)有定義register變量的必要,因?yàn)榫幾g程序忽略register修飾符,而根據(jù)寄存器的使用情況和變量的情況決定是否把變量解釋為register變量。

1.7函數(shù)的傳參

1.7.1 指針參數(shù)

補(bǔ)充:還有種應(yīng)用場(chǎng)景,就是需要使用結(jié)構(gòu)體作為參數(shù)的時(shí)候,因?yàn)樾螀⑾牡氖菞5目臻g,棧的空間是有限的,如果結(jié)構(gòu)體比較大,一般不建議直接將結(jié)構(gòu)體作為形參,而是通過(guò)指針對(duì)其進(jìn)行訪問(wèn)。

1.7.2 數(shù)組參數(shù)

int atoil(char str[10])

int atoil(char str[])

int atoil(char *str)

這三種定義的形式不同,但是達(dá)到的效果是一模一樣的,不管使用哪一種定義,編譯器都會(huì)將其轉(zhuǎn)換成第三種形式。

1.8指針函數(shù) VS 函數(shù)指針

1.8.1 指針函數(shù)(pointfunc.c)

確定方法:

(1)確定目標(biāo)類(lèi)型 int buf[5]

(2)確定指針類(lèi)型 在目標(biāo)類(lèi)型基礎(chǔ)上加* 加在變量名位置 int (*)[5]

(3)定義指針變量 int (*p)[5]

實(shí)例:

1.8.2 函數(shù)指針:首先是指針,指向的是函數(shù)。

(1) 定義

void swap(int *a, int *b)

void (*pfunc)(int *, int *);

(2) 賦值

pfunc = &swap;

pfunc = swap; (函數(shù)名, 就是函數(shù)的指針常量)

注意:函數(shù)類(lèi)型和函數(shù)指針類(lèi)型兼容,上邊兩種定義形式可以隨便選擇使用

(3) 調(diào)用

(*pfunc)(&a, &b);//將swap理解成函數(shù)

pfunc(&a, &b); //將swap理解成函數(shù)指針,這兩種調(diào)用隨便選擇,跟上邊的定義是沒(méi)有關(guān)系的。

實(shí)例:

補(bǔ)充:strcmp 比較字符串大小 qsort 可以快速排序

用法:

shrcmp

strcmp()函數(shù)是通過(guò)兩個(gè)字符串一個(gè)一個(gè)字符比較的(最多比較次數(shù)為第二個(gè)參數(shù)的長(zhǎng)度+1)

例如strcmp("hello","here");

首先比較第一個(gè)字符'h'= 'h'相等

接著比較第二個(gè)字符'e'= 'e'相等

比較第三個(gè)字符 'l'>'e',返回一個(gè)正值

如果字符串完全相等會(huì)回0

qsort:

qsort是萬(wàn)能數(shù)組排序函數(shù),必須要學(xué)會(huì)使用,簡(jiǎn)單的數(shù)組自然不用說(shuō),這里主要討論一下字符串?dāng)?shù)組的使用。

首先看一下qsort的原型:

void qsort(void *base, size_t nmemb, size_t size,

int(*compar)(const void *, const void *));

正確使用這個(gè)函數(shù)要注意幾點(diǎn):

1.base要傳數(shù)組的首地址

2.size傳的是每個(gè)元素的大小

3.正確編寫(xiě)compar函數(shù)

下面是實(shí)際應(yīng)用:

一個(gè)字符串?dāng)?shù)組:*str[MAX],假設(shè)里面現(xiàn)在保存了n個(gè)字符串了。

首先要正確理解什么是字符串?dāng)?shù)組,簡(jiǎn)單的說(shuō),可以理解成它就是一個(gè)數(shù)組,只不過(guò)其中的元素是一串字符串,而訪問(wèn)這些字符串,得用指針,也就是它們的地址,比如*name[]={"james","henry"},那么訪問(wèn)其中的字符串就是name[0],name[1]...這里就有個(gè)容易混淆的地方了,對(duì)于字符串?dāng)?shù)組,那么每個(gè)元素的大小到底是多少呢?對(duì)name[0]來(lái)說(shuō),到底是字符串“james”的長(zhǎng)度5,還是char*的大小4呢?答案應(yīng)該是4,因?yàn)樽址當(dāng)?shù)組里面保存的是各個(gè)字符串的指針,所以回到上面所說(shuō)的第二點(diǎn)注意,用qsort的時(shí)候應(yīng)該要傳sizeof(char *);

第二,編寫(xiě)compar函數(shù)比較字符串有地方要注意:

不能把strcmp本身傳給qsort,即不能寫(xiě)strcmp(p,q),因?yàn)樾螀⑹莄onst void*類(lèi)型,同理,寫(xiě)成strcmp((char *)p, (char *)q);也是無(wú)效的;正確的寫(xiě)法應(yīng)該是:strcmp(*(char **)p, *(char **)q);先強(qiáng)制轉(zhuǎn)換成char**,在用*減少一層間接尋址操作:

int compar_words(const void *p, const void *q)

{

return strcmp(*(char **)p, *(char **)q);

}

對(duì)于上面的應(yīng)用,最后使用qsort應(yīng)該是這樣:

qsort(str, n, sizeof(char *), compar);

實(shí)例:比較數(shù)組中的字符串的大小

 

1.9遞歸函數(shù)

定義:直接或間接調(diào)用自己

注意:遞歸程序的效率比較低,空間占用的也很多,唯一的理由是比較容易看懂。

例: 利用函數(shù)遞歸實(shí)現(xiàn)n!

1. 寫(xiě)出遞歸通用項(xiàng):n! = n * (n - 1)!

2. 寫(xiě)出遞歸結(jié)束條件:n = 1

3. 代碼實(shí)現(xiàn):假設(shè)函數(shù)已經(jīng)寫(xiě)好,可以用調(diào)用,不要去想計(jì)算機(jī)執(zhí)行的具體過(guò)程

4. 單步執(zhí)行, 掌握?qǐng)?zhí)行流程

實(shí)例:實(shí)現(xiàn)階乘 將輸入的字符串反向輸出。

上一篇:嵌入式學(xué)習(xí)筆記:shell腳本學(xué)習(xí)從入門(mén)到精通

下一篇:嵌入式學(xué)習(xí)筆記:c語(yǔ)言結(jié)構(gòu)體定義和使用

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專(zhuān)線:010-82525158 企業(yè)培訓(xùn)洽談專(zhuān)線:010-82525379 院校合作洽談專(zhuān)線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見(jiàn)科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5京公海網(wǎng)安備11010802025203號(hào)

回到頂部

主站蜘蛛池模板: 亚洲 中文 欧美 日韩在线观看 | 噼里啪啦动漫在线观看免费 | 又色又爽又黄18禁美女裸身无遮挡 | 国产又黄又硬又湿又黄的 | GOGOGO免费高清看中国国语 | 国产思思99re99在线观看 | www.av毛片| 毛片无码免费无码播放 | 亚洲国产成人手机在线观看 | 高H紫黑色的又粗又上翘 | 边摸边吃奶边做爽动态 | 午夜精品a片一区二区三区 gogogo高清在线观看免费中国 | 久久天天躁狠狠躁夜夜 | 免费h网站在线观看的 | 欧美午夜片欧美片在线观看 | 美女mm131爽爽爽作爱 | 正在播放酒店约少妇高潮 | 嫩草影院最新网址 | 国产精品女A片爽爽免费按摩 | 幻女bbwxxxx| 国语对白爽死我了 | 精品久久久爽爽久久久AV | 成人欧美一区二区三区A片 VIDEOS1080P内射少妇 | 成人亚洲欧美丁香在线观看 | 少妇做爰喷水高潮呻吟A片免费 | 三个男吃我奶头一边一个视频 | 成人444kkkk在线观看 | 亚洲伊人情人综合网站 | 熟女人妻AV完整一区二区三区 | 久爱WWW成人网免费视频 | 黄色在线亚洲 | 忍着娇喘人妻被中出中文字幕 | 涩涩涩久久久成人精品 | 日本久久小视频 | 一区二区三区人妻无码 | 天天看夜夜爽 | 亚洲av不卡一区二区三区 | 国产视频导航 | 人妻少妇乱子伦无码视频专区 | 亚州国产AV一区二区三区伊在 | 女人张开腿让男人桶个爽 |