性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

  • 回復(fù)
  • 收藏
  • 點(diǎn)贊
  • 分享
  • 發(fā)新帖

單片機(jī)入門:C語言講解(一)

好久沒來電源網(wǎng)發(fā)帖,學(xué)習(xí)電子技術(shù)的過程中積累了一點(diǎn)心得體會,總想直抒胸臆,可身邊沒幾個同行,只好跑到電源網(wǎng)寫點(diǎn)酸文,貽笑與大方之家。

既然是技術(shù)心得類的帖子,肯定存在理解不透徹的地方,肯定有自己沒有關(guān)注到的知識點(diǎn),還望大家海涵,及時斧正,謝謝。

先在此挖個坑,慢慢填吧,可能會虎頭蛇尾,但肯定會不定期更新。

全部回復(fù)(95)
正序查看
倒序查看
ltjltjltj
LV.1
2
2021-04-09 20:31
期待
0
回復(fù)
LV.1
3
2021-04-10 00:09
留名
0
回復(fù)
2021-04-10 17:17

    C語言參考書籍為《C primer Plus》第五版,《C語言深度解剖》,同時也融入了自己的一點(diǎn)感悟與心得。

    說心里話,C語言的書籍以及視頻教程看了很多,但還是覺得不夠透徹,理解不夠深入。希望熱心的網(wǎng)友能夠及時補(bǔ)充糾正。

    操作系統(tǒng)為ubuntu18.04_x86_64,編譯器采用的是gcc version 7.5.0 (ubuntu18.04_x86_64),后期的開發(fā)板驗(yàn)證采用的是金沙灘的51單片機(jī)開發(fā)板,編譯器為keil uversion 4(windows_xp_x86_32),單片機(jī)采用的是STC89C52單片機(jī)。

1
回復(fù)
2021-04-10 17:28

    我自己的初期架構(gòu)是寫一點(diǎn)51單片機(jī)相關(guān)的帖子,主要內(nèi)容為基于51單片機(jī)的C語言,匯編語言,單片機(jī)硬件結(jié)構(gòu),寄存器等。

    目前也沒有給自己定一個太過具體的任務(wù)計劃,主要目的有兩個,第一是通過發(fā)帖把單片機(jī)涉及的相關(guān)知識點(diǎn)梳理清楚,第二結(jié)合自己的學(xué)習(xí)心得幫幫那些想學(xué)單片機(jī)又苦于沒有找到適合的學(xué)習(xí)方法的朋友,希望我走過的學(xué)習(xí)彎路能給大家一些啟發(fā)。

1
回復(fù)
2021-04-10 17:41

    這篇帖子主要針對想靠單片機(jī)這門手藝吃飯的入門級工程師。搞了幾十年開關(guān)電源,射頻電子同時又自認(rèn)為單片機(jī)這玩意太簡單的大牛級工程師就別看了。特別希望得到搞了多年單片機(jī)開發(fā),樂于幫助后進(jìn)且恰巧看到帖子的工程師的指導(dǎo),謝謝。

    另外,不管什么類型的杠精都別看了,我真的不愿意和杠精抬扛,第一累,第二浪費(fèi)時間。

1
回復(fù)
蘭波
LV.8
7
2021-04-10 22:14
哈哈,你也玩軟的了?C語言我會一些。
0
回復(fù)
2021-04-12 20:42

    說心里話,很早就想寫一點(diǎn)有關(guān)C語言的學(xué)習(xí)文章,但是怎么寫,才能讓大家相對愉快地學(xué)習(xí),我也想了很久。為此我也翻了很多程序語言書籍,自認(rèn)為積累了一點(diǎn)學(xué)習(xí)經(jīng)驗(yàn),分享給大家,下面轉(zhuǎn)入正題。

    講解程序語言,教科書大多從瑣碎的語法結(jié)構(gòu)開始,這樣的講解方式直接把多數(shù)的學(xué)生拒之門外。回想我當(dāng)年學(xué)習(xí)C語言的經(jīng)歷,只能說苦不堪言。起初C語言的書籍是我的枕邊讀物,一般晚上入睡前翻一兩頁,相當(dāng)有助于睡眠。

    我們能不能站得更高一點(diǎn),嘗試著采用先整體后局部的方法講講C語言呢?換句話說,我們能否先將程序語言的框架搭起來,然后再根據(jù)功能需求用各種語法一步一步地完善框架,最終使其成為完整的程序。

    通俗點(diǎn)說,就是先建立骨架,再摸索著往骨架上填充血肉,接著嘗試關(guān)聯(lián)各個功能部件,最后大功告成。當(dāng)然過程肯定不會一帆風(fēng)順,必然存在諸多的問題,通過不斷地調(diào)試,最終問題都會解決,功能也會實(shí)現(xiàn)。

   

1
回復(fù)
2021-04-12 21:07

    不管何種程序語言,其最終的執(zhí)行機(jī)構(gòu)肯定是計算機(jī),那程序語言的各種語法規(guī)則必須要符合電子計算機(jī)的特性,才能保證其執(zhí)行不出錯。據(jù)此原則,程序語言的特性必然遵循電子計算機(jī)的功能特點(diǎn),當(dāng)然這里我并不準(zhǔn)備詳細(xì)分析計算機(jī)的硬件功能。

    這就帶來一個問題,電子計算機(jī)有什么特別之處能有助于我們更好的理解程序呢?這就要繞到另一個問題,電子計算機(jī)的運(yùn)行需要什么?答案是電,沒有電,一切的電子設(shè)備都得停工。

    那電有什么特點(diǎn)呢,入門類的電工書籍都會用“水”的特性來類比“電”的特性,這里我們也采用此類比法。

1
回復(fù)
2021-04-12 21:31

    我家住在長江邊上,每當(dāng)學(xué)不下去或者遇到解不開的心結(jié)時,我總會到江堤上走一走,轉(zhuǎn)一轉(zhuǎn),坐一坐,間或舉目遠(yuǎn)眺,心情不同,心境亦不同。此一法非常有助于我個人的心境提升。我的學(xué)習(xí)心得很多時候是悟出來的,而不是從書本上直接獲得的。當(dāng)然,各人有各人的學(xué)習(xí)方法,此處不表。

    話說一日,我苦苦思索程序如何運(yùn)行未果,遂暫時放一放。晚上一個人在江堤上散步,吹著江風(fēng),偶爾抬頭遠(yuǎn)望,只有江上漁船零星的燈火以及星星和月亮陪伴著我。我突然靈光乍現(xiàn),想通了白天苦苦思考的問題。那程序到底是怎么運(yùn)行的呢?

1
回復(fù)
2021-04-12 22:04

    其實(shí)程序的運(yùn)行不就和眼前的滾滾長江水一樣嗎?流動的長江水必然有其源頭以及盡頭。長江水在流經(jīng)不同地貌時,會產(chǎn)生很多的支流,不同的支流又會分化出諸多小支流。支流中有些繞過一段河道后又重新匯入長江,有些則成了一潭死水。

    如果從江水的源頭與盡頭看,我們可以粗略地認(rèn)為長江是以直線的運(yùn)動軌跡川流不息。看看長江的各個支流,我們可以說這是長江的流動分支。再瞧瞧江水繞過的各個灣灣碼頭,這不是在循環(huán)往復(fù)嗎?

    再看看程序的運(yùn)行,不也是一樣嗎。整體上看,程序從上往下依次執(zhí)行,再執(zhí)行過程中根據(jù)不同條件分化出諸多的節(jié)點(diǎn),有些節(jié)點(diǎn)執(zhí)行一次即可,有些節(jié)點(diǎn)需要執(zhí)行多次,有些節(jié)點(diǎn)則直接跳過。

    至此,程序的框架終于清晰了,再結(jié)合書本專業(yè)知識,我們總算弄通了程序是怎么運(yùn)行的。

    程序是由順序結(jié)構(gòu),分支結(jié)構(gòu)以及循環(huán)結(jié)構(gòu)組成的。如果對匯編語言有所了解或者熟悉C語言goto關(guān)鍵字的用法,我們甚至可以說程序語言只有一種結(jié)構(gòu),那就是跳轉(zhuǎn)結(jié)構(gòu)。再深入一點(diǎn),若理解了指針的概念,同時懂得一點(diǎn)計算機(jī)的組成原理,我們滿可以說,程序的本質(zhì)就是通過合理地規(guī)劃內(nèi)存,最大限度發(fā)揮計算機(jī)內(nèi)部各功能模塊的性能。

0
回復(fù)
2021-04-13 09:32

   插個題外話,可能是年齡大了,經(jīng)歷的事情也多,心態(tài)慢慢平和了,不知不覺間對古典詩詞以及水墨丹青有了些許興趣。個人覺得古代文人的藝術(shù)創(chuàng)作品更多的是寫意,此中意境只可意會而不可言傳。

    步入中年的我,興之所至,偶爾會乘汽渡在江上轉(zhuǎn)轉(zhuǎn),也曾體悟過“落霞與孤鶩齊飛,秋水共長天一色”。生活所迫,日常的瑣事過多,中國的大好河山還沒機(jī)會好好領(lǐng)略,也想?yún)⑼竻⑼浮?/strong>大漠孤煙直,長河落日圓”的意境。


0
回復(fù)
2021-04-13 20:39

    程序的框架分解完成,接下來聊聊程序的存儲規(guī)則。

    我們通常意義上敲的代碼實(shí)質(zhì)是靜態(tài)的或者說是未運(yùn)行的程序,這樣的程序只能放在ROM中,這里的ROM代指外存儲器,比如硬盤,F(xiàn)LASH,EMMC,EEPROM等。

    運(yùn)行的程序通常稱為進(jìn)程,它通過調(diào)用各類寄存器實(shí)現(xiàn)某一功能,對于單片機(jī)而言,講進(jìn)程就有點(diǎn)扯,因?yàn)槌R?guī)單片機(jī)速度很慢,一般僅僅用于實(shí)現(xiàn)某一特定功能,所以其進(jìn)程只有一個。真正的進(jìn)程概念是基于操作系統(tǒng)而言。操作系統(tǒng)中會涉及多個進(jìn)程的處理,這里就不擴(kuò)展了。上述對進(jìn)程的認(rèn)識只是我個人的粗略描述。

1
回復(fù)
2021-04-13 20:55

    進(jìn)程只能運(yùn)行于RAM中,單片機(jī)上電復(fù)位后,固化的微指***令將ROM中的程序加載到RAM中,這時程序就開始運(yùn)行了。那問題來了,大家有沒有想過進(jìn)程(運(yùn)行的程序)在內(nèi)存中是怎么分布的,或者說進(jìn)程是如何在大片的RAM區(qū)中運(yùn)行的?如果能考慮到這一層次的問題,恭喜你,總算對單片機(jī)有了一個相對深入的思考。

    學(xué)習(xí)C語言以及單片機(jī),很多的工程師的套路都是對照書籍或者例程敲代碼,雖然當(dāng)時按照例程實(shí)現(xiàn)了某一功能,但是脫離源碼后又不知道從何下手。于是嘗試著反復(fù)敲例程,重復(fù)了很多次后依然沒有理解單片機(jī)為何物。至此完成了從入門到放棄的過程。

   

        

1
回復(fù)
2021-04-13 21:10

    上述放棄學(xué)習(xí)單片機(jī)的工程師離單片機(jī)入門僅僅差一小步,那就是思考,準(zhǔn)確地說是帶著問題去思考。

    學(xué)習(xí)單片機(jī)的心態(tài)很重要,我是一個學(xué)習(xí)單片機(jī)失敗了很多次的LOSER(我對電子技術(shù)沒有多少興趣,堅(jiān)持至今是因?yàn)闆]有更好的謀生手段罷了,我比常人多了一點(diǎn)耐心,恒心),在此總結(jié)歸納一下我認(rèn)為正確的或者說是恰當(dāng)?shù)膶W(xué)習(xí)單片機(jī)的方法及心態(tài)。

    第一點(diǎn)是忘,忘掉過往已經(jīng)掌握的開關(guān)電源的系統(tǒng)知識(電源網(wǎng)的大多數(shù)受眾是電源工程師),對于射頻工程師,PLC工程師,上位機(jī)軟件工程類似。為什么有此一說呢,這是我嘗試著學(xué)習(xí)單片機(jī)失敗了多次后悟出來的。

    我們一旦有門技術(shù)傍身后,總會習(xí)慣性地靠這門擅長的手藝謀生,慢慢就形成了依賴,專業(yè)術(shù)語稱作思維舒適區(qū)。我們思想中總會有一個誤區(qū),認(rèn)為過往掌握的技能有助于我們學(xué)習(xí)后面的新知識。不自覺的我們就把以前的思維模式帶入到新的知識領(lǐng)域中。這就是最大的問題。

    

0
回復(fù)
2021-04-13 21:24
@hello-no1
    上述放棄學(xué)習(xí)單片機(jī)的工程師離單片機(jī)入門僅僅差一小步,那就是思考,準(zhǔn)確地說是帶著問題去思考。    學(xué)習(xí)單片機(jī)的心態(tài)很重要,我是一個學(xué)習(xí)單片機(jī)失敗了很多次的LOSER(我對電子技術(shù)沒有多少興趣,堅(jiān)持至今是因?yàn)闆]有更好的謀生手段罷了,我比常人多了一點(diǎn)耐心,恒心),在此總結(jié)歸納一下我認(rèn)為正確的或者說是恰當(dāng)?shù)膶W(xué)習(xí)單片機(jī)的方法及心態(tài)。   第一點(diǎn)是忘,忘掉過往已經(jīng)掌握的開關(guān)電源的系統(tǒng)知識(電源網(wǎng)的大多數(shù)受眾是電源工程師),對于射頻工程師,PLC工程師,上位機(jī)軟件工程類似。為什么有此一說呢,這是我嘗試著學(xué)習(xí)單片機(jī)失敗了多次后悟出來的。    我們一旦有門技術(shù)傍身后,總會習(xí)慣性地靠這門擅長的手藝謀生,慢慢就形成了依賴,專業(yè)術(shù)語稱作思維舒適區(qū)。我們思想中總會有一個誤區(qū),認(rèn)為過往掌握的技能有助于我們學(xué)習(xí)后面的新知識。不自覺的我們就把以前的思維模式帶入到新的知識領(lǐng)域中。這就是最大的問題。    

    單片機(jī)與開關(guān)電源,變頻器,射頻電子,PLC,上位機(jī)軟件編程等都是相對獨(dú)立的技能,不要指望學(xué)會了一門手藝后,就能觸類旁通其他的相關(guān)技能。這是我們開始學(xué)習(xí)單片機(jī)必須要有的思想覺悟。

    不信,你可以問問身邊精通單片機(jī),或者PLC,乃至JAVA編程的同事懂不懂開關(guān)電源的設(shè)計,大概率是不懂的。會抄個反激電源的單片機(jī)工程師不算,他那點(diǎn)淺薄的對開關(guān)電源的認(rèn)識不夠看。

    能夠?qū)㈤_關(guān)電源和單片機(jī)區(qū)分開來學(xué)習(xí),你已經(jīng)成功了一大步。單片機(jī)和開關(guān)電源是兩個不同的領(lǐng)域,雖然熟悉開關(guān)電源有助于我們理解單片機(jī)中涉及的硬件知識,但這遠(yuǎn)遠(yuǎn)不夠。

0
回復(fù)
2021-04-14 10:59
@hello-no1
   單片機(jī)與開關(guān)電源,變頻器,射頻電子,PLC,上位機(jī)軟件編程等都是相對獨(dú)立的技能,不要指望學(xué)會了一門手藝后,就能觸類旁通其他的相關(guān)技能。這是我們開始學(xué)習(xí)單片機(jī)必須要有的思想覺悟。    不信,你可以問問身邊精通單片機(jī),或者PLC,乃至JAVA編程的同事懂不懂開關(guān)電源的設(shè)計,大概率是不懂的。會抄個反激電源的單片機(jī)工程師不算,他那點(diǎn)淺薄的對開關(guān)電源的認(rèn)識不夠看。   能夠?qū)㈤_關(guān)電源和單片機(jī)區(qū)分開來學(xué)習(xí),你已經(jīng)成功了一大步。單片機(jī)和開關(guān)電源是兩個不同的領(lǐng)域,雖然熟悉開關(guān)電源有助于我們理解單片機(jī)中涉及的硬件知識,但這遠(yuǎn)遠(yuǎn)不夠。
對于電源來說,看行業(yè),比如做數(shù)控電源的話,單片機(jī)和開關(guān)電源都得精通才可以
0
回復(fù)
2021-04-16 18:28

    學(xué)習(xí)單片機(jī)需要具有的第二個心態(tài)是不急,有耐心。市面上有一些教材號稱一個禮拜掌握單片機(jī),這樣的教程針對的受眾通常是有一定基礎(chǔ)的,且資質(zhì)相對較好的朋友。如果沒有一定的知識儲備,個人建議還是按部就班的學(xué)習(xí)。

    知識是逐步緩慢積累的,快速上手的教程最大的副作用可能是營造了一種焦慮的環(huán)境,讓很多初學(xué)者再學(xué)過好幾遍仍找不著頭緒時,開始了自我否定,最終放棄。在此我送給那些一直徘徊在單片機(jī)入門階段的朋友一句話:“堅(jiān)持就是在快要放棄時再忍耐忍耐?!?/strong>

    我個人定義單片機(jī)技術(shù)為一門謀生的手藝,甚至可以說是安身立命的手段,那肯定不太容易掌握,否則滿大街的人都會玩,何談養(yǎng)家糊口一說。

    周圍也有很多電子工程師精通單片機(jī)技術(shù),那說明這門技術(shù)的學(xué)習(xí)掌握也沒有難于上青天。只要努力,理順?biāo)悸?,儲備了足夠的知識,找到適合自己的學(xué)習(xí)方法,肯定可以精通單片機(jī)技術(shù)。

    

0
回復(fù)
2021-04-16 18:49

    學(xué)習(xí)單片機(jī)技術(shù)需要具備的第三個心態(tài)是恒心,或者說是韌性。想學(xué)好單片機(jī)必然會遇到各種各樣稀奇古怪的問題,這時心態(tài)一定要足夠堅(jiān)韌,不能但凡遇到一點(diǎn)困難,一時半會解決不了就想著放棄。

    在某個問題上卡住了,如果以當(dāng)前的知識儲備確實(shí)解決不了,那就放一放,繼續(xù)往前走,千萬不能自設(shè)囚籠,鉆牛角尖把自己困在那里,這一點(diǎn)很重要。我自己屬于典型的一根筋,遇到問題總想著立馬解決,但身邊又缺少能夠及時給自己答疑解惑的朋友。在苦思冥想過一番仍不可得時,我就失去了繼續(xù)往前探索學(xué)習(xí)的興趣。等下一次再提起興趣時,又得從頭開始,周而復(fù)始,永遠(yuǎn)困在單片機(jī)入門學(xué)習(xí)的道路上。

    在學(xué)習(xí)的過程中明知會遇到各種問題而依舊選擇努力前行不失為勇者的表現(xiàn),在遇到超出自己能力范圍的問題而選擇適時地放一放,可謂是智者的選擇。

1
回復(fù)
2021-04-16 20:48

    C語言編寫的程序經(jīng)調(diào)試編譯后生成HEX文件燒寫進(jìn)單片機(jī)ROM中,單片機(jī)上電復(fù)位后,將ROM中的程序引導(dǎo)至RAM中(內(nèi)存中),單片機(jī)便開始正式工作了。我們知道程序都是在內(nèi)存中運(yùn)行的,為保證程序高效有序的運(yùn)行,內(nèi)存通常被人為的劃分為四個區(qū)域,這就引出上文提到的內(nèi)存四區(qū)的概念。

    內(nèi)存區(qū)域的劃分,我準(zhǔn)備梳理兩類,一類是C語言內(nèi)存四區(qū)的劃分,一類是單片機(jī)的內(nèi)存區(qū)域的劃分,實(shí)質(zhì)上大同小異。這一章講講C語言的內(nèi)存四區(qū),等寫到單片機(jī)的內(nèi)部框架章節(jié)時,再列舉單片機(jī)內(nèi)存區(qū)域的相關(guān)知識點(diǎn)。

    

1
回復(fù)
lkings
LV.6
21
2021-04-16 21:49
@hello-no1
   C語言編寫的程序經(jīng)調(diào)試編譯后生成HEX文件燒寫進(jìn)單片機(jī)ROM中,單片機(jī)上電復(fù)位后,將ROM中的程序引導(dǎo)至RAM中(內(nèi)存中),單片機(jī)便開始正式工作了。我們知道程序都是在內(nèi)存中運(yùn)行的,為保證程序高效有序的運(yùn)行,內(nèi)存通常被人為的劃分為四個區(qū)域,這就引出上文提到的內(nèi)存四區(qū)的概念。   內(nèi)存區(qū)域的劃分,我準(zhǔn)備梳理兩類,一類是C語言內(nèi)存四區(qū)的劃分,一類是單片機(jī)的內(nèi)存區(qū)域的劃分,實(shí)質(zhì)上大同小異。這一章講講C語言的內(nèi)存四區(qū),等寫到單片機(jī)的內(nèi)部框架章節(jié)時,再列舉單片機(jī)內(nèi)存區(qū)域的相關(guān)知識點(diǎn)。    
這么好的貼子怎么沒人頂,難道都是做硬件的多,樓主加油
2
回復(fù)
2021-04-18 13:24

    內(nèi)存的分配方式實(shí)質(zhì)是由不同的編譯器針對不同的單片機(jī)架構(gòu)再配合相應(yīng)的編程語言決定的。圖靈機(jī)模型中,內(nèi)存相當(dāng)于一段無限長的紙帶,指示著機(jī)器的下一步動作,周而復(fù)始,永不停息。

    但現(xiàn)實(shí)世界中,內(nèi)存是有限的,而機(jī)器只要不斷電,肯定會不知疲倦地占用內(nèi)存進(jìn)行運(yùn)算處理,經(jīng)過一定的機(jī)器周期,終會耗盡有限的內(nèi)存。站在哲學(xué)的角度,這就是有限與無限的矛盾。

    怎么辦呢,是否存在一種方法或者說策略使得有限近似于無限,答案是肯定的。合理的規(guī)劃內(nèi)存,同時及時釋放回收內(nèi)存,就能使有限的內(nèi)存用之不竭。這就是內(nèi)存區(qū)域劃分思想的來源。

1
回復(fù)
2021-04-18 14:53

    C語言中的內(nèi)存被分割為四個區(qū)域,分別對應(yīng)著代碼區(qū)(code),數(shù)據(jù)區(qū)(data),棧區(qū)(stack),堆區(qū)(heap)。不同區(qū)域的功能特性也不盡相同。首先講講代碼區(qū)(code).

    單片機(jī)上電復(fù)位后,編譯生成的HEX代碼經(jīng)由機(jī)器內(nèi)部固化的微指***令加載進(jìn)內(nèi)存,實(shí)質(zhì)上代碼被引導(dǎo)至內(nèi)存中的代碼區(qū),即code區(qū)。該段內(nèi)存的特性之一是不可以修改,專業(yè)術(shù)語為只讀。其次該區(qū)域內(nèi)容是可共享的(即某段可執(zhí)行代碼能夠訪問它)。

    C語言代碼區(qū)可共享的目的是針對頻繁調(diào)用的只讀數(shù)據(jù),使用此法可有效提高程序的訪問效率。代碼區(qū)設(shè)置為只讀的意義在于防止程序運(yùn)行過程中的意外而修改了某些指***令或數(shù)據(jù),導(dǎo)致不可預(yù)料的錯誤發(fā)生。

1
回復(fù)
2021-04-18 15:22

   51單片機(jī)代碼區(qū)如何配置可共享數(shù)據(jù)呢?使用51單片機(jī)特有的C語言關(guān)鍵字code,即可實(shí)現(xiàn)。C51中該類變量常用于存放一些復(fù)雜函數(shù)的固定值數(shù)據(jù),如各類真值表,三角函數(shù)值,反三角函數(shù)值,對數(shù)值,指數(shù)值等。

    為什么要這樣做呢?很多的8位機(jī),16位機(jī)內(nèi)部并沒有浮點(diǎn)運(yùn)算器,遇到復(fù)雜一些的運(yùn)算基本都不能勝任,而用戶僅僅關(guān)注最后的結(jié)果。我們在程序中預(yù)先給出運(yùn)算結(jié)果,當(dāng)涉及某一功能函數(shù)計算時,直接將代碼區(qū)中對應(yīng)的運(yùn)算結(jié)果調(diào)用顯示即可。此種方法既高效,又節(jié)省了大量機(jī)器資源。這種思想在單片機(jī)技術(shù)中被稱作查表執(zhí)行。

    51單片機(jī)中code關(guān)鍵字修飾的數(shù)據(jù),其特性為只讀。從單片機(jī)內(nèi)部資源的角度看,此類數(shù)據(jù)存儲至程序空間ROM中(C語言中則為代碼區(qū))。這樣可以大大節(jié)省單片機(jī)的RAM使用量,畢竟我們的單片機(jī)RAM空間比較小,而程序空間相對大的多。

  


1
回復(fù)
2021-04-18 15:54
    數(shù)據(jù)區(qū),顧名思義用于存放各種特性的數(shù)據(jù)。該區(qū)域存放的數(shù)據(jù)有全局變量(Global_Variable)、靜態(tài)變量(Static_Variable)、常量(Constant)。由于數(shù)據(jù)區(qū)存放此三類變量,所以又被稱為全局區(qū)或靜態(tài)區(qū)。至于全局變量,靜態(tài)變量以及常量該如何定義,它們之間的差異在后續(xù)講解C語言詳細(xì)語法時再介紹。

    數(shù)據(jù)區(qū)又可以細(xì)分為data區(qū),bss區(qū)及常量區(qū)。其中data區(qū)里主要存放的是已經(jīng)初始化的全局變量、靜態(tài)變量。bss區(qū)主要存放未初始化的全局變量、靜態(tài)變量。未初始化的數(shù)據(jù)在程序執(zhí)行前會被編譯器自動初始化為0或NULL。顧名思義常量區(qū)存放的是一些常量,如const關(guān)鍵字修飾的全局變量以及字符串常量等。

    數(shù)據(jù)區(qū)中的數(shù)據(jù)相較于代碼區(qū)中的數(shù)據(jù),其不僅可讀而且可寫??勺x表明該區(qū)域里的數(shù)據(jù)可被函數(shù)調(diào)用,可寫表明該區(qū)域中的數(shù)據(jù)能夠被改變。該區(qū)域數(shù)據(jù)的特點(diǎn)是只要內(nèi)存不掉電,數(shù)據(jù)就能一直存活。單片機(jī)中的各功能寄存器也有此類似特性。只要配置好寄存器相關(guān)數(shù)據(jù)后,寄存器中的數(shù)據(jù)就能一直存在,除非掉電。有很多場合的應(yīng)用需要保證寄存器中的數(shù)據(jù)不丟失,為防止外界電源斷電,單片機(jī)系統(tǒng)會接入備用電池。如實(shí)時時鐘,日歷,低功耗模式等。

    不同類型的變量在內(nèi)存中的存活時間各不相同,這一特性專業(yè)術(shù)語稱作變量的生命周期。其次可讀數(shù)據(jù)變量在內(nèi)存中能被哪些函數(shù)調(diào)用涉及到變量的調(diào)用范圍,專業(yè)術(shù)語叫變量的作用域。

0
回復(fù)
2021-04-18 15:59
@hello-no1
   其實(shí)程序的運(yùn)行不就和眼前的滾滾長江水一樣嗎?流動的長江水必然有其源頭以及盡頭。長江水在流經(jīng)不同地貌時,會產(chǎn)生很多的支流,不同的支流又會分化出諸多小支流。支流中有些繞過一段河道后又重新匯入長江,有些則成了一潭死水。   如果從江水的源頭與盡頭看,我們可以粗略地認(rèn)為長江是以直線的運(yùn)動軌跡川流不息??纯撮L江的各個支流,我們可以說這是長江的流動分支。再瞧瞧江水繞過的各個灣灣碼頭,這不是在循環(huán)往復(fù)嗎?   再看看程序的運(yùn)行,不也是一樣嗎。整體上看,程序從上往下依次執(zhí)行,再執(zhí)行過程中根據(jù)不同條件分化出諸多的節(jié)點(diǎn),有些節(jié)點(diǎn)執(zhí)行一次即可,有些節(jié)點(diǎn)需要執(zhí)行多次,有些節(jié)點(diǎn)則直接跳過。   至此,程序的框架終于清晰了,再結(jié)合書本專業(yè)知識,我們總算弄通了程序是怎么運(yùn)行的。   程序是由順序結(jié)構(gòu),分支結(jié)構(gòu)以及循環(huán)結(jié)構(gòu)組成的。如果對匯編語言有所了解或者熟悉C語言goto關(guān)鍵字的用法,我們甚至可以說程序語言只有一種結(jié)構(gòu),那就是跳轉(zhuǎn)結(jié)構(gòu)。再深入一點(diǎn),若理解了指針的概念,同時懂得一點(diǎn)計算機(jī)的組成原理,我們滿可以說,程序的本質(zhì)就是通過合理地規(guī)劃內(nèi)存,最大限度發(fā)揮計算機(jī)內(nèi)部各功能模塊的性能。
    不管何種程序語言,均由三種基本結(jié)構(gòu)組成。他們是順序結(jié)構(gòu),選擇(分支)結(jié)構(gòu),循環(huán)結(jié)構(gòu)。拿到一份寫好的源碼,我們首先會瀏覽一遍。通常的做法是從上到下快速滾動閱讀一遍,熟悉程序的大體框架。從總覽的高度看,CPU執(zhí)行程序是從頭至尾依次執(zhí)行的,我們可以說從全局的角度看,程序是由不同的功能語句組成的順序結(jié)構(gòu)。

    類人猿之所以能夠進(jìn)化為人類,我的理解是它們具備不斷試錯不斷學(xué)習(xí)的能力。在進(jìn)化的道路中每一次試錯都伴隨著一次成長過程。在緩慢的成長過程中,其心志得到不斷的進(jìn)化。當(dāng)積累到一定程度,量變引起質(zhì)變,類人猿終于成長為今天的你我。將人類的進(jìn)化過程映射到計算機(jī)技術(shù)上,雖有些扯,但多少有些相通性。   

0
回復(fù)
2021-04-18 15:59
@hello-no1
   其實(shí)程序的運(yùn)行不就和眼前的滾滾長江水一樣嗎?流動的長江水必然有其源頭以及盡頭。長江水在流經(jīng)不同地貌時,會產(chǎn)生很多的支流,不同的支流又會分化出諸多小支流。支流中有些繞過一段河道后又重新匯入長江,有些則成了一潭死水。   如果從江水的源頭與盡頭看,我們可以粗略地認(rèn)為長江是以直線的運(yùn)動軌跡川流不息??纯撮L江的各個支流,我們可以說這是長江的流動分支。再瞧瞧江水繞過的各個灣灣碼頭,這不是在循環(huán)往復(fù)嗎?   再看看程序的運(yùn)行,不也是一樣嗎。整體上看,程序從上往下依次執(zhí)行,再執(zhí)行過程中根據(jù)不同條件分化出諸多的節(jié)點(diǎn),有些節(jié)點(diǎn)執(zhí)行一次即可,有些節(jié)點(diǎn)需要執(zhí)行多次,有些節(jié)點(diǎn)則直接跳過。   至此,程序的框架終于清晰了,再結(jié)合書本專業(yè)知識,我們總算弄通了程序是怎么運(yùn)行的。   程序是由順序結(jié)構(gòu),分支結(jié)構(gòu)以及循環(huán)結(jié)構(gòu)組成的。如果對匯編語言有所了解或者熟悉C語言goto關(guān)鍵字的用法,我們甚至可以說程序語言只有一種結(jié)構(gòu),那就是跳轉(zhuǎn)結(jié)構(gòu)。再深入一點(diǎn),若理解了指針的概念,同時懂得一點(diǎn)計算機(jī)的組成原理,我們滿可以說,程序的本質(zhì)就是通過合理地規(guī)劃內(nèi)存,最大限度發(fā)揮計算機(jī)內(nèi)部各功能模塊的性能。
    想要讓計算機(jī)執(zhí)行不同的功能,最終必然需要將不同的功能轉(zhuǎn)化為計算機(jī)能夠識別的語句。計算機(jī)之所以能夠根據(jù)外界的變化執(zhí)行不同的動作,恰恰是因?yàn)樗邆湓囧e能力,也即是判斷能力。任何形式的程序語言都必須具備根據(jù)不同條件執(zhí)行不同語句的能力,此形式被描述為程序語言的選擇結(jié)構(gòu)。

    某種意義上說,循環(huán)結(jié)構(gòu)是特殊的選擇結(jié)構(gòu)。程序語言根據(jù)條件判斷依次往下執(zhí)行時,我們說這是典型的選擇結(jié)構(gòu)。當(dāng)程序語言根據(jù)條件判斷執(zhí)行若干動作后,又回至條件判斷的起點(diǎn),重新進(jìn)入條件判斷的流程,依此往復(fù)執(zhí)行…… 我們可以說這就是循環(huán)結(jié)構(gòu)。

    從上述角度解讀,我們可以認(rèn)為循環(huán)結(jié)構(gòu)是特殊的選擇結(jié)構(gòu)。當(dāng)然,如果循環(huán)結(jié)構(gòu)的判斷執(zhí)行條件僅只執(zhí)行一次,我們同樣可以說選擇結(jié)構(gòu)是特殊的循環(huán)結(jié)構(gòu)。換句話說,選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)之間可以相互轉(zhuǎn)換。

0
回復(fù)
2021-04-19 21:08

    不管是代碼區(qū)還是數(shù)據(jù)區(qū)中的數(shù)據(jù)自始至終都駐扎在內(nèi)存中,而內(nèi)存規(guī)劃的初衷是為了高效利用內(nèi)存,及時回收釋放多余的內(nèi)存,使有限的內(nèi)存有足夠的空間支撐程序的全過程運(yùn)行,顯然僅僅靠代碼區(qū)及數(shù)據(jù)區(qū)遠(yuǎn)遠(yuǎn)不夠,遂引入堆和棧的概念。
    堆區(qū)(heap),該區(qū)域可看作是一個存儲數(shù)據(jù)的大容器,其容量遠(yuǎn)遠(yuǎn)大于后面要講解的棧區(qū),該區(qū)域中的數(shù)據(jù)不需要像棧區(qū)那樣遵循先進(jìn)后出的規(guī)則。

    堆區(qū)主要用于動態(tài)內(nèi)存分配。堆區(qū)在內(nèi)存中位于數(shù)據(jù)區(qū)中的BSS區(qū)和棧區(qū)之間。該區(qū)域一般由程序員手動分配和釋放,若程序員不釋放,程序結(jié)束時由操作系統(tǒng)回收(該話題涉及到操作系統(tǒng)內(nèi)存回收的話題,此處一筆帶過,有機(jī)會分析嵌入式linux系統(tǒng)時講解)。

    C語言中堆區(qū)的大小可使用malloc函數(shù)進(jìn)行分配,堆區(qū)的釋放采用free函數(shù)實(shí)現(xiàn)。程序中malloc等內(nèi)存分配函數(shù)的使用次數(shù)一定要和free函數(shù)相等,并一一配對使用。否則隨著程序的運(yùn)行會出現(xiàn)內(nèi)存泄漏的問題。

0
回復(fù)
2021-04-19 22:12

    棧區(qū)(stack),用于存儲所有的局部變量,包括用戶定義的auto型局部變量,函數(shù)的實(shí)參,返回值,嵌套函數(shù)的調(diào)用(遞歸函數(shù))等。棧區(qū)和其他三個區(qū)域最大的不同點(diǎn)在于其采用的是先進(jìn)后出的內(nèi)存結(jié)構(gòu)。局部變量在該區(qū)域由編譯器在程序運(yùn)行過程中實(shí)時加載和釋放。所以局部變量的生存周期很短,需要時即申請,不用即銷毀釋放。

    auto型局部變量經(jīng)編譯器自動放入棧中后,其生存周期及作用域只限于定義的功能函數(shù)內(nèi)有效,當(dāng)一個auto型局部變量超出其作用域時,自動從棧中彈出,用完后再由操作系統(tǒng)自動釋放。

    auto型局部變量的生存周期及作用域的特點(diǎn)牽出一個很有意思的話題,即函數(shù)實(shí)參的調(diào)用是否影響對應(yīng)變量的數(shù)值,答案是不影響(后續(xù)C語言語法章節(jié)會詳細(xì)講解)。

    另外一個注意事項(xiàng)是不要返回局部變量的地址,因?yàn)闂^(qū)開辟的地址空間由編譯器自動釋放,當(dāng)auto型局部變量失效后,原先對應(yīng)的地址空間也隨之釋放,返回的局部變量地址是一個隨機(jī)數(shù),而不是之前對應(yīng)的局部變量的地址。


0
回復(fù)
2021-04-19 22:20

    上述堆區(qū)和棧區(qū)的概念是針對C語言而言,對于單片機(jī)我們也經(jīng)常提到堆棧的概念,但C語言的堆區(qū)棧區(qū)和單片機(jī)的堆棧還是有區(qū)別的。單片機(jī)的堆棧實(shí)質(zhì)是C語言中棧的描述。通常單片機(jī)的內(nèi)存資源相當(dāng)有限,所以一般不分配堆區(qū),而且很少用到標(biāo)準(zhǔn)庫的malloc類函數(shù),當(dāng)然上升到操作系統(tǒng)層面就是另一說了。

    單片機(jī)的堆棧也屬于內(nèi)存的一部分,所以它肯定有臨時存儲的功能,那單片機(jī)的堆棧主要用于哪些存儲場合呢?如果說代碼區(qū)和數(shù)據(jù)區(qū)中的數(shù)據(jù)是用于單片機(jī)自始至終的全程數(shù)據(jù)存儲,那堆棧就是用于單片機(jī)運(yùn)行過程中的中間數(shù)據(jù)處理。

通俗的說,代碼區(qū)和數(shù)據(jù)區(qū)中存儲的數(shù)據(jù)只要單片機(jī)不掉電,其中的數(shù)據(jù)就不會被釋放。而堆棧中的數(shù)據(jù)是根據(jù)程序需要實(shí)時產(chǎn)生,實(shí)時釋放,我們通常提到的內(nèi)存回收與釋放實(shí)質(zhì)是針對堆棧中數(shù)據(jù)的回收釋放操作。

0
回復(fù)
魯珀特
LV.4
31
2021-04-20 11:53

關(guān)于內(nèi)存占用  我有深刻的經(jīng)歷,在實(shí)際使用中,內(nèi)存會泄露,如果不能及時釋放,很容易造成程序卡頓,運(yùn)行速度變慢。

0
回復(fù)
發(fā)