最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

C語言中最難啃的硬骨頭非這三個(gè)莫屬

2022-05-21 20:15 作者:大方老師單片機(jī)課堂  | 我要投稿

C語言中難啃的硬骨頭非這三個(gè)莫屬


\\\插播一條:我自己在今年年初錄制了一套還比較系統(tǒng)的入門單片機(jī)教程,想要的同學(xué)找我拿就行了免費(fèi)的--)。最近比較閑,帶做畢設(shè),帶學(xué)生參加省級(jí)以上比///綠色圖標(biāo)【?で】liutianwang123

正文開始\\\///



C語言在嵌入式學(xué)習(xí)中是必備的知識(shí),審核大部分操作都要圍C語言進(jìn)行,而其中有三難啃的硬骨幾乎是公認(rèn)級(jí)別的。

0x01指針

指針公認(rèn)最難理解的概念,也是讓很多初學(xué)者選擇放棄的直接原因。

指針之所以難理解,因?yàn)橹羔槺旧砭褪且粋€(gè)變量,是一個(gè)非常特殊的變量,專門存放地址的變量,這個(gè)地址需要給申請(qǐng)空間才能裝東西,而且因?yàn)槭莻€(gè)變量可以中間賦值,這么一倒騰很多人就開始犯暈了,繞不開彎了。C語言之所以被很多高手所喜歡,就是指針的魅力,中間可以靈活的切換,執(zhí)行效率超高,這點(diǎn)也是讓小白暈菜的地方。

指針是學(xué)習(xí)繞不過去的知識(shí)點(diǎn),而且學(xué)C語言,下一步緊接著切換到數(shù)據(jù)結(jié)構(gòu)和算法,指針是切換的重點(diǎn),指針搞不定下一步進(jìn)行起來就很難,會(huì)讓很多人放棄繼續(xù)學(xué)習(xí)的勇氣。

指針直接對(duì)接內(nèi)存結(jié)構(gòu),常見C語言里面的指針亂指,數(shù)組越界根本原因就是內(nèi)存問題。在指針這個(gè)點(diǎn)有無窮無盡的發(fā)揮空間。很多編程的技巧都在此集結(jié)。

指針還涉及如何申請(qǐng)釋放內(nèi)存,如果釋放不及時(shí)就會(huì)出現(xiàn)內(nèi)存泄露的情況,指針是高效好用,但不徹底搞明白對(duì)于有些人來說簡直就是噩夢。

在概念方面問題可以參見此前推文《對(duì)C語言指針最詳盡的講解》,那么在指針方面可以參見一下大神的經(jīng)驗(yàn):

復(fù)雜類型說明

要了解指針,多多少少會(huì)出現(xiàn)一些比較復(fù)雜的類型。所以先介紹一下如何完全理解一個(gè)復(fù)雜類型。

要理解復(fù)雜類型其實(shí)很簡單,一個(gè)類型里會(huì)出現(xiàn)很多運(yùn)算符,他們也像普通的表達(dá)式一樣,有優(yōu)先級(jí),其優(yōu)先級(jí)和運(yùn)算優(yōu)先級(jí)一樣。

所以筆者總結(jié)了一下其原則:從變量名處起,根據(jù)運(yùn)算符優(yōu)先級(jí)結(jié)合,一步一步分析。

下面讓我們先從簡單的類型開始慢慢分析吧。

int p;

這是一個(gè)普通的整型變量

int p;

首先P處開始,先與結(jié)合,所以說P是一個(gè)指針。然后再int結(jié)合,說明指針?biāo)赶虻膬?nèi)容的類型int型,所P是一個(gè)返回整型數(shù)據(jù)的指針

int p[3];

首先P處開始,先[]結(jié)合,說P是一個(gè)數(shù)組。然后int結(jié)合,說明數(shù)組里的元素是整型的,所P是一個(gè)由整型數(shù)據(jù)組成的數(shù)組。

int *p[3];

首先P處開始,先[]結(jié)合,因?yàn)槠鋬?yōu)先級(jí)比高,所P是一個(gè)數(shù)組。然后再與結(jié)合,說明數(shù)組里的元素是指針類型。之后再int結(jié)合,說明指針?biāo)赶虻膬?nèi)容的類型是整型的,所P是一個(gè)由返回整型數(shù)據(jù)的指針?biāo)M成的數(shù)組。

int (*p)[3];

首先P處開始,先與結(jié)合,說P是一個(gè)指針。然后再[]結(jié)("()"這步可以忽略,只是為了改變優(yōu)先級(jí)),說明指針?biāo)赶虻膬?nèi)容是一個(gè)數(shù)組。之后再int結(jié)合,說明數(shù)組里的元素是整型的。所P是一個(gè)指向由整型數(shù)據(jù)組3個(gè)整數(shù)的指針。

int **p;

首先P開始,先與結(jié)合,說P是一個(gè)指針。然后再與結(jié)合,說明指針?biāo)赶虻脑厥侵羔?。之后?/span>int結(jié)合,說明該指針?biāo)赶虻脑厥钦蛿?shù)據(jù)。由于二級(jí)指針以及更高級(jí)的指針極少用在復(fù)雜的類型中,所以后面更復(fù)雜的類型我們就不考慮多級(jí)指針了,最多只考慮一級(jí)指針。

int p(int);

P處起,先()結(jié)合,說P是一個(gè)函數(shù)。然后進(jìn)()里分析,說明該函數(shù)有一個(gè)整型變量的參數(shù),之后再與外面int結(jié)合,說明函數(shù)的返回值是一個(gè)整型數(shù)據(jù)。

int (*p)(int);

P處開始,先與指針結(jié)合,說P是一個(gè)指針。然后()結(jié)合,說明指針指向的是一個(gè)函數(shù)。之后再()int結(jié)合,說明函數(shù)有一個(gè)int型的參數(shù),再與最外層int結(jié)合,說明函數(shù)的返回類型是整型,所P是一個(gè)指向有一個(gè)整型參數(shù)且返回類型為整型的函數(shù)的指針。

int (p(int))[3];

可以先跳過,不看這個(gè)類型,過于復(fù)雜。P開始,先()結(jié)合,說P是一個(gè)函數(shù)。然后進(jìn)()里面,int結(jié)合,說明函數(shù)有一個(gè)整型變量參數(shù)。然后再與外面的結(jié)合,說明函數(shù)返回的是一個(gè)指針。之后到最外面一層,先[]結(jié)合,說明返回的指針指向的是一個(gè)數(shù)組。接著再與結(jié)合,說明數(shù)組里的元素是指針,最后再int結(jié)合,說明指針指向的內(nèi)容是整型數(shù)據(jù)。所P是一個(gè)參數(shù)為一個(gè)整數(shù)據(jù)且返回一個(gè)指向由整型指針變量組成的數(shù)組的指針變量的函數(shù)。

說到這里也就差不多了。理解了這幾個(gè)類型,其它的類型對(duì)我們來說也是小菜了。不過一般不會(huì)用太復(fù)雜的類型,那樣會(huì)大大減小程序的可讀性,請(qǐng)慎用。這上面的幾種類型已經(jīng)足夠我們用了。

細(xì)說指針

指針是一個(gè)特殊的變量,它里面存儲(chǔ)的數(shù)值被解釋成為內(nèi)存里的一個(gè)地址。

要搞清一個(gè)指針需要搞清指針的四方面的內(nèi)容:指針的類型、指針?biāo)赶虻念愋?、指針的值或者叫指針?biāo)赶虻膬?nèi)存區(qū)、指針本身所占據(jù)的內(nèi)存區(qū)。讓我們分別說明。

先聲明幾個(gè)指針放著做例子:

1int*ptr;

2char*ptr;

3int**ptr;

4int(*ptr)[3];

5int*(*ptr)[4];

指針的類型

從語法的角度看,小伙伴們只要把指針聲明語句里的指針名字去掉,剩下的部分就是這個(gè)指針的類型。這是指針本身所具有的類型。

讓我們看看上述例子中各個(gè)指針的類型:

1intptr;//指針的類型int

2charptr;//指針的類型char

3intptr;//指針的類型int

4int(ptr)[3];//指針的類型int()[3]

5int*(ptr)[4];//指針的類型int(*)[4]

怎么樣?找出指針的類型的方法是不是很簡單?

指針?biāo)赶虻念愋?/span>

當(dāng)通過指針來訪問指針?biāo)赶虻膬?nèi)存區(qū)時(shí),指針?biāo)赶虻念愋蜎Q定了編譯器將把那片內(nèi)存區(qū)里的內(nèi)容當(dāng)做什么來看待。

從語法上看,小伙伴們只需把指針聲明語句中的指針名字和名字左邊的指針聲明*去掉,剩下的就是指針?biāo)赶虻念愋汀?/span>

上述例子中各個(gè)指針?biāo)赶虻念愋停?/span>

1intptr; //指針?biāo)赶虻念愋?/span>int

2char*ptr; //指針?biāo)赶虻牡念愋?/span>char*

3int*ptr; //指針?biāo)赶虻牡念愋?/span>int*

4int(*ptr)[3]; //指針?biāo)赶虻牡念愋?/span>int(*)[3]

5int*(*ptr)[4]; //指針?biāo)赶虻牡念愋?/span>int*(*)[4]

在指針的算術(shù)運(yùn)算中,指針?biāo)赶虻念愋陀泻艽蟮淖饔谩?/span>

指針的類(即指針本身的類)和指針?biāo)赶虻念愋褪莾蓚€(gè)概念。當(dāng)小伙伴們對(duì)C越來越熟悉時(shí),就會(huì)發(fā)現(xiàn),把與指針攪和在一起""這個(gè)概念分"指針的類""指針?biāo)赶虻念?/span>"兩個(gè)概念,是精通指針的關(guān)鍵點(diǎn)之一。

筆者看了不少書,發(fā)現(xiàn)有些寫得差的書中,就把指針的這兩個(gè)概念攪在一起了,所以看起書來前后矛盾,越看越糊涂。

指針的值

即指針?biāo)赶虻膬?nèi)存區(qū)或地址。

指針的值是指針本身存儲(chǔ)的數(shù)值,這個(gè)值將被編譯器當(dāng)作一個(gè)地址,而不是一個(gè)一般的數(shù)值。

32位程序里,所有類型的指針的值都是一個(gè)32位整數(shù),因32位程序里內(nèi)存地址全都32位長。指針?biāo)赶虻膬?nèi)存區(qū)就是從指針的值所代表的那個(gè)內(nèi)存地址開始,長度si zeof(指針?biāo)赶虻念?/span>)的一片內(nèi)存區(qū)。

以后,我們說一個(gè)指針的值XX,就相當(dāng)于說該指針指向了XX為首地址的一片內(nèi)存區(qū)域;我們說一個(gè)指針指向了某塊內(nèi)存區(qū)域,就相當(dāng)于說該指針的值是這塊內(nèi)存區(qū)域的首地址。

指針?biāo)赶虻膬?nèi)存區(qū)和指針?biāo)赶虻念愋褪莾蓚€(gè)完全不同的概念。在例一中,指針?biāo)赶虻念愋鸵呀?jīng)有了,但由于指針還未初始化,所以它所指向的內(nèi)存區(qū)是不存在的,或者說是無意義的。

以后,每遇到一個(gè)指針,都應(yīng)該問問:這個(gè)指針的類型是什么?指針指的類型是什么?該指針指向了哪里?

指針本身所占據(jù)的內(nèi)存區(qū)

指針本身占了多大的內(nèi)存?只要用函數(shù)sizeof(指針的類)測一下就知道了。32位平臺(tái)里,指針本身占據(jù)4個(gè)字節(jié)的長度。指針本身占據(jù)的內(nèi)存這個(gè)概念在判斷一個(gè)指針表達(dá)式是否是左值時(shí)很有用。

0x02函數(shù)

面向過程對(duì)象模塊的基本單位,以及對(duì)應(yīng)各種組合,函數(shù)指針,指針函數(shù)

一個(gè)函數(shù)就是一個(gè)業(yè)務(wù)邏輯塊,是面向過程,單元模塊的最小單元,而且在函數(shù)的執(zhí)行過程中,形參,實(shí)參如何交換數(shù)據(jù),如何將數(shù)據(jù)傳遞出去,如何設(shè)計(jì)一個(gè)合理的函數(shù),不單單是解決一個(gè)功能,還要看是不是能夠復(fù)用,避免重復(fù)造輪子。

函數(shù)指針和指針函數(shù),表面是兩個(gè)字面意思的互換實(shí)際上含義截然不同,指針函數(shù)比較好理解,就是返回指針的一個(gè)函數(shù),函數(shù)指針這個(gè)主要用在回調(diào)函數(shù),很多人覺得函數(shù)都沒還搞明白,回調(diào)函數(shù)更暈菜了。其實(shí)可以通俗的理解指向函數(shù)的指針,本身是一個(gè)指針變量,只不過在初始化的時(shí)候指向了函數(shù),這又回到了指針層面。沒搞明白指針再次深入的向前走特別難。


C語言的開發(fā)者們?yōu)楹髞淼拈_發(fā)者做了一些省力氣的事情,他們編寫了大量代碼,將常見的基本功能都完成了,可以讓別人直接拿來使用。但是那么多代碼,如何從中找到自己需要的呢?將所有代碼都拿來顯然是不太現(xiàn)實(shí)。

但是這些代碼,早已被早期的開發(fā)者們分門別類地放在了不同的文件中,并且每一段代碼都有唯一的名字。所以其實(shí)學(xué)習(xí)C語言并沒有那么難,尤其是可以在動(dòng)手鍛煉做項(xiàng)目中進(jìn)行。使用代碼時(shí),只要在對(duì)應(yīng)的名字后面加( )就可以。這樣的一段代碼就是函數(shù),函數(shù)能夠獨(dú)立地完成某個(gè)功能,一次編寫完成后可以多次使用。

很多初學(xué)者可能都會(huì)C語言中的函數(shù)和數(shù)學(xué)中的函數(shù)概念搞混淆。其實(shí)真相并沒有那么復(fù)雜C語言中的函數(shù)是有規(guī)律可循跡的,只要搞清楚了概念你會(huì)發(fā)現(xiàn)還挺有意思的。函數(shù)的英文名稱 Function,對(duì)應(yīng)翻譯過來的中文還的意思C語言中的函數(shù)也跟功能有著密切的關(guān)系。

我們來看一小C語言代碼:

#include

int main()

{

puts("Hello World");

return 0;

}

把目光放在4行代碼上,這行代碼會(huì)在顯示器上輸Hello World。前面我們已經(jīng)講過,puts后面要(),字符串也要放()中。

C語言中,有的語句使用時(shí)不能帶括號(hào),有的語句必須帶括號(hào)。帶括號(hào)的就是函數(shù)Function)。

C語言提供了很多功能,我們只需要一句簡單的代碼就能夠使用。但是這些功能的底層都比較復(fù)雜,通常是軟件和硬件的結(jié)合,還要要考慮很多細(xì)節(jié)和邊界,如果將這些功能都交給程序員去完成,那將極大增加程序員的學(xué)習(xí)成本,降低編程效率。

有了函數(shù)之后,C語言的編程效率就好像有了神器一樣,開發(fā)者們只需要隨時(shí)調(diào)用就可以了,像進(jìn)程函數(shù)、操作函數(shù)、時(shí)間日期函數(shù)等都可以幫助我們直接實(shí)現(xiàn)C語言本身的功能。

C語言函數(shù)是可以重復(fù)使用的。

函數(shù)的一個(gè)明顯特征就是使用時(shí)必須帶括號(hào)(),必要的話,括號(hào)中還可以包含待處理的數(shù)據(jù)。例puts("果果小師")就使用了一段具有輸出功能的代碼,這段代碼的名字 puts,"尚觀科"是要交給這段代碼處理的數(shù)據(jù)。使用函數(shù)在編程中有專業(yè)的稱呼,叫做函數(shù)調(diào)用Function Call)。

如果函數(shù)需要處理多個(gè)數(shù)據(jù),那么它們之間使用逗號(hào),分隔,例如:

pow(10, 2);

該函數(shù)用來102次方。

好了,看到這里你有沒有覺得其實(shí)C語言函數(shù)還是比較有意思的,而且并沒有那么復(fù)雜困難。以后再遇到菜鳥小白的時(shí)候,你一口一個(gè)C語言的函數(shù),說不定就能當(dāng)場引來無數(shù)膜拜的目光。

0x03結(jié)構(gòu)體、遞歸

很多在大學(xué)學(xué)習(xí)C語言的,很多課程都沒學(xué)完,結(jié)構(gòu)體都沒學(xué)到,因?yàn)閺恼鹿?jié)的安排來看好像,結(jié)構(gòu)體學(xué)習(xí)放在教材的后半部分了,弄得很多學(xué)生覺得結(jié)構(gòu)體不重要,如果只是應(yīng)付學(xué)校的考試,或者就是為了混個(gè)畢業(yè)證,的確學(xué)的意義不大。

如果想從事編程這個(gè)行業(yè),對(duì)這個(gè)概念還不了解,基本上無法構(gòu)造數(shù)據(jù)模型,沒有一個(gè)業(yè)務(wù)體是完全使用原生數(shù)據(jù)類型來完成的,很多高手在設(shè)計(jì)數(shù)據(jù)模型的時(shí)候,一般先把頭文件中的結(jié)構(gòu)體數(shù)據(jù)整理出來。然后設(shè)計(jì)好功能函數(shù)的參數(shù),以及名字,然后才真正開始c源碼。

如果從節(jié)省空間考慮結(jié)構(gòu)體里面的數(shù)據(jù)放的順序不一樣在內(nèi)存中占用的空間也不一樣,結(jié)構(gòu)體與結(jié)構(gòu)體之間賦值,結(jié)構(gòu)體存在指針那么賦值要特別注意,需要進(jìn)行深度的賦值。

遞歸一般用于從頭到位統(tǒng)計(jì)或者羅列一些數(shù)據(jù),在使用的時(shí)候很多初學(xué)者都覺得別扭,怎么還能自己調(diào)用自己?而且在使用的時(shí)候,一定設(shè)置好跳出的條件,不然無休止的進(jìn)行下去,真就成無線死循環(huán)了。

對(duì)于結(jié)構(gòu)體方面的知識(shí),可以參見此前推送的文章C語言結(jié)構(gòu)體struct)最全的講解(萬字干貨)》。具體也可以參見大佬的經(jīng)驗(yàn):

相信大家對(duì)于結(jié)構(gòu)體都不陌生。在此,分享出本人對(duì)C語言結(jié)構(gòu)體的研究和學(xué)習(xí)的總結(jié)。如果你發(fā)現(xiàn)這個(gè)總結(jié)中有你以前所未掌握的,那本文也算是有點(diǎn)價(jià)值了。當(dāng)然,水平有限,若發(fā)現(xiàn)不足之處懇請(qǐng)指出。代碼文test.c我放在下面。在此,我會(huì)圍繞以2個(gè)問題來分析和應(yīng)C語言結(jié)構(gòu)體:

.C語言中的結(jié)構(gòu)體有何作用

.結(jié)構(gòu)體成員變量內(nèi)存對(duì)齊有何講(點(diǎn))

對(duì)于一些概念的說明,我就不C語言教材上的定義搬上來。我們坐下來慢慢聊吧。

C語言中最難啃的硬骨頭非這三個(gè)莫屬的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
台北市| 郯城县| 章丘市| 德惠市| 舒兰市| 图木舒克市| 盐津县| 乾安县| 皮山县| 扎兰屯市| 明水县| 论坛| 寻甸| 天峻县| 曲阳县| 孟州市| 西宁市| 金昌市| 洛隆县| 莱阳市| 静海县| 常宁市| 兴义市| 湖州市| 蕲春县| 如东县| 景洪市| 龙口市| 瓦房店市| 淮南市| 永和县| 青海省| 开阳县| 岳池县| 杨浦区| 鲁甸县| 谷城县| 唐山市| 棋牌| 邮箱| 黎川县|