色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

嵌入式開發中的C語言編程思想

STM32嵌入式開發 ? 來源:STM32嵌入式開發 ? 作者:STM32嵌入式開發 ? 2022-04-08 11:03 ? 次閱讀

摘要

本文首先分析了C語言的陷阱和缺陷,對容易犯錯的地方進行歸納整理;分析了編譯器語義檢查的不足之處并給出防范措施,以Keil MDK編譯器為例,介紹了該編譯器的特性、對未定義行為的處理以及一些高級應用;在此基礎上,介紹了防御性編程的概念,提出了編程過程中就應該防范于未然的多種措施;提出了測試對編寫優質嵌入式程序的重要作用以及常用測試方法;最后,本文試圖以更高的層次看待編程,討論一些通用的編程思想。

1 編程風格

《計算機程序的構造和解釋》一書在開篇寫到:程序寫出來是給人看的,附帶能在機器上運行。

1.1 整潔的樣式

使用什么樣的編碼樣式一直都頗具爭議性的,比如縮進和大括號的位置。因為編碼的樣式也會影響程序的可讀性,面對一個亂放括號、對齊都不一致的源碼,我們很難提起閱讀它的興趣。我們總要看別人的程序,如果彼此編碼樣式相近,讀起源碼來會覺得比較舒適。但是編碼風格的問題是主觀的,永遠不可能在編碼風格上達成統一意見。因此只要你的編碼樣式整潔、結構清晰就足夠了。除此之外,對編碼樣式再沒有其它要求。

提出匈牙利命名法的程序員、前微軟首席架構師Charles Simonyi說:我覺得代碼清單帶給人的愉快同整潔的家差不多。你一眼就能分辨出家里是雜亂無章還是整潔如新。這也許意義不大。因為光是房子整潔說明不了什么,它仍可能藏污納垢!但是第一印象很重要,它至少反映了程序的某些方面。我敢打賭,我在3米開外就能看出程序拙劣與否。我也許沒法保證它很不錯,但如果從3米外看起來就很糟,我敢保證這程序寫得不用心。如果寫得不用心,那它在邏輯上也許就不會優美。

1.2 清晰的命名

變量、函數、宏等等都需要命名,清晰的命名是優秀代碼的特點之一。命名的要點之一是名稱應能清晰的描述這個對象,以至于一個初級程序員也能不費力的讀懂你的代碼邏輯。我們寫的代碼主要給誰看是需要思考的:給自己、給編譯器還是給別人看?我覺得代碼最主要的是給別人看,其次是給自己看。如果沒有一個清晰的命名,別人在維護你的程序時很難在整個全貌上看清代碼,因為要記住十多個以上的糟糕命名的變量是件非常困難的事;而且一段時間之后你回過頭來看自己的代碼,很有可能不記得那些糟糕命名的變量是什么意思。

為對象起一個清晰的名字并不是簡單的事情。首先能認識到名稱的重要性需要有一個過程,這也許跟譚式C程序教材被大學廣泛使用有關:滿書的a、b、c、x、y、z變量名是很難在關鍵的初學階段給人傳達優秀編程思想的;其次如何恰當的為對象命名也很有挑戰性,要準確、無歧義、不羅嗦,要對英文有一定水平,所有這些都要滿足時,就會變得很困難;此外,命名還需要考慮整體一致性,在同一個項目中要有統一的風格,堅持這種風格也并不容易。

關于如何命名,Charles Simonyi說:面對一個具備某些屬性的結構,不要隨隨便便地取個名字,然后讓所有人去琢磨名字和屬性之間有什么關聯,你應該把屬性本身,用作結構的名字。

1.3 恰當的注釋

注釋向來也是爭議之一,不加注釋和過多的注釋我都是反對的。不加注釋的代碼顯然是很糟糕的,但過多的注釋也會妨礙程序的可讀性,由于注釋可能存在的歧義,有可能會誤解程序真實意圖,此外,過多的注釋會增加程序員不必要的時間。如果你的編碼樣式整潔、命名又很清晰,那么,你的代碼可讀性不會差到哪去,而注釋的本意就是為了便于理解程序。

這里建議使用良好的編碼樣式和清晰的命名來減少注釋,對模塊、函數、變量、數據結構、算法和關鍵代碼做注釋,應重視注釋的質量而不是數量。如果你需要一大段注釋才能說清楚程序做什么,那么你應該注意了:是否是因為程序變量命名不夠清晰,或者代碼邏輯過于混亂,這個時候你應該考慮的可能就不是注釋,而是如何精簡這個程序了。

2 數據結構

數據結構是程序設計的基礎。在設計程序之前,應該先考慮好所需要的數據結構。

前微軟首席架構師Charles Simonyi:編程的第一步是想象。就是要在腦海中對來龍去脈有極為清晰的把握。在這個初始階段,我會使用紙和鉛筆。我只是信手涂鴉,并不寫代碼。我也許會畫些方框或箭頭,但基本上只是涂鴉,因為真正的想法在我腦海里。我喜歡想象那些有待維護的結構,那些結構代表著我想編碼的真實世界。一旦這個結構考慮得相當嚴謹和明確,我便開始寫代碼。我會坐到終端前,或者換在以前的話,就會拿張白紙,開始寫代碼。這相當容易。我只要把頭腦中的想法變換成代碼寫下來,我知道結果應該是什么樣的。大部分代碼會水到渠成,不過我維護的那些數據結構才是關鍵。我會先想好數據結構,并在整個編碼過程中將它們牢記于心。

開發過以太網操作系統SDS 940的Butler Lampson:(程序員)最重要的素質是能夠把問題的解決方案組織成容易操控的結構。

開發CP/M操作系統的Gary.A:如果不能確認數據結構是正確的,我是決不會開始編碼的。我會先畫數據結構,然后花很長時間思考數據結構。在確定數據結構之后我就開始寫一些小段的代碼,并不斷地改善和監測。在編碼過程中進行測試可以確保所做的修改是局部的,并且如果有什么問題的話,能夠馬上發現。

微軟創始人比爾**·**蓋茨:編寫程序最重要的部分是設計數據結構。接下來重要的部分是分解各種代碼塊。

編寫世界上第一個電子表格軟件的Dan Bricklin:在我看來,寫程序最重要的部分是設計數據結構,此外,你還必須知道人機界面會是什么樣的。

我們舉個例子來說明。在介紹防御性編程的時候,提到公司使用的LCD顯示屏抗干擾能力一般,為了提高LCD的穩定性,需要定期讀出LCD內部的關鍵寄存器值,然后跟存在Flash中的初始值相比較。需要讀出的LCD寄存器有十多個,從每個寄存器讀出的值也不盡相同,從1個到8個字節都有可能。如果不考慮數據結構,編寫出的程序將會很冗長。

void lcd_redu(void)

{ 。

讀第一個寄存器值;

if(第一個寄存器值==Flash存儲值)

{

讀第二個寄存器值;

if(第二個寄存器值==Flash存儲值)

{

。..

讀第十個寄存器值;

if(第十個寄存器值==Flash存儲值)

{

返回;

}

else

{

重新初始化LCD;

}

}

else

{

重新初始化LCD;

}

}

else

{

重新初始化LCD;

}

}

我們分析這個過程,發現能提取出很多相同的元素,比如每次讀LCD寄存器都需要該寄存器的命令號,都會經過讀寄存器、判斷值是否相同、處理異常情況這一過程。所以我們可以提取一些相同的元素,組織成數據結構,用統一的方法去處理這些數據,將數據與處理過程分開來。

我們可以先提取相同的元素,將之組織成數據結構:

c2ecb04c-b659-11ec-aa7f-dac502259ad0.png

這里lcd_command表示的是LCD寄存器命令號;lcd_get_value是一個數組,表示寄存器要初始化的值,這是因為對于一個LCD寄存器,可能要初始化多個字節,這是硬件特性決定的;lcd_value_num是指一個寄存器要多少個字節的初值,這是因為每一個寄存器的初值數目是不同的,我們用同一個方法處理數據時,是需要這個信息的。

就本例而言,我們將要處理的數據都是事先固定的,所以定義好數據結構后,我們可以將這些數據組織成表格:

/*LCD部分寄存器設置值列表*/

lcd_redu_list_struct const lcd_redu_list_str[]= {

{SSD1963_Get_Address_Mode,{0x20}

,1}, /*1*/

{SSD1963_Get_Pll_Mn

,{0x3b,0x02,0x04}

,3}, /*2*/

{SSD1963_Get_Pll_Status

,{0x04}

,1}, /*3*

{SSD1963_Get_Lcd_Mode

,{0x24,0x20,0x01,0xdf,0x01,0x0f,0x00}

,7}, /*4*/

{SSD1963_Get_Hori_Period ,{0x02,0x0c,0x00,0x2a,0x07,0x00,0x00,0x00},8}, /*5*/

{SSD1963_Get_Vert_Period ,{0x01,0x1d,0x00,0x0b,0x09,0x00,0x00}

,7}, /*6*/ {SSD1963_Get_Power_Mode ,{0x1c}

,1}, /*7*/ {SSD1963_Get_Display_Mode,{0x03}

,1}, /*8*/ {SSD1963_Get_Gpio_Conf ,{0x0F,0x01}

,2}, /*9*/ {SSD1963_Get_Lshift_Freq ,{0x00,0xb8}

,2}, /*10* };

至此,我們就可以用一個處理過程來完成數十個LCD寄存器的讀取、判斷和異常處理了:

/** * lcd 顯示冗余

* 每隔一段時間調用該程序一次 */ void lcd_redu(void) {

uint8_t tmp[8];

uint32_t i,j;

uint32_t lcd_init_flag;

lcd_init_flag =0;

for(i=0;i《sizeof(lcd_redu_list_str)/sizeof(lcd_redu_list_str[0]);i++)

{

LCD_SendCommand(lcd_redu_list_str[i].lcd_command);

uyDelay(10);

for(j=0;j《lcd_redu_list_str[i].lcd_value_num;j++)

{

tmp[j]=LCD_ReadData();

if(tmp[j]!=lcd_redu_list_str[i].lcd_get_value[j])

{

lcd_init_flag=0x55;

//一些調試語句,打印出錯的具體信息

goto handle_lcd_init;

}

}

}

handle_lcd_init:

if(lcd_init_flag==0x55)

{

//重新初始化LCD

//一些必要的恢復措施

}

}

通過合理的數據結構,我們可以將數據和處理過程分開,LCD冗余判斷過程可以用很簡潔的代碼來實現。更重要的是,將數據和處理過程分開更有利于代碼的維護。比如,通過實驗發現,我們還需要增加一個LCD寄存器的值進行判斷,這時候只需要將新增加的寄存器信息按照數據結構格式,放到LCD寄存器設置值列表中的任意位置即可,不用增加任何處理代碼即可實現!這僅僅是數據結構的優勢之一,使用數據結構還能簡化編程,使復雜過程變的簡單,這個只有實際編程后才會有更深的理解。

審核編輯 :李倩

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7604

    瀏覽量

    136701
  • 嵌入式開發
    +關注

    關注

    18

    文章

    1028

    瀏覽量

    47564

原文標題:嵌入式開發中的C語言編程思想

文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    新手怎么學嵌入式?

    的運行機制。例如,了解數據結構的鏈表、棧和隊列,對于在嵌入式編程管理數據非常有幫助。 2. 選擇合適的編程
    發表于 12-12 10:51

    如何使用 RISC-V 進行嵌入式開發

    RISC-V是一種開源的指令集架構(ISA),它允許任何人設計、制造和銷售基于RISC-V的處理器,這為嵌入式開發提供了極大的靈活性和創新空間。以下是使用RISC-V進行嵌入式開發的基本步驟: 一
    的頭像 發表于 12-11 17:32 ?471次閱讀

    MCU編程語言開發環境介紹

    微控制器單元(Microcontroller Unit,簡稱MCU)是嵌入式系統的核心,廣泛應用于各種電子產品。隨著技術的發展,MCU編程語言
    的頭像 發表于 11-01 11:51 ?672次閱讀

    零基礎嵌入式開發學習路線

    嵌入式開發”沒有接觸過的同學可能會不明覺厲,但是只要你了解了,感興趣并且有一個正確的學習路線的話,零基礎也能入門。給大家介紹一個簡單易懂的學習路線,讓你能夠從零開始學習嵌入式開發。 第一步:掌握
    發表于 10-25 15:55

    嵌入式開發常見問題排查

    嵌入式開發問題排查很多人認為嵌入式開發很難,主要是因為在這個過程中常常會遇到各式各樣的問題。這些問題的復雜性和多樣性使得許多人感到困惑和無所適從。然而,如果將這些問題逐一拆解,實際上大部分都可以
    的頭像 發表于 09-22 08:04 ?322次閱讀
    <b class='flag-5'>嵌入式開發</b>常見問題排查

    AWFlow:內置豐富的功能節點,簡化嵌入式開發流程

    AWFlow突破傳統C語言限制的嵌入式開發框架,通過封裝硬件驅動和系統平臺,集成通用軟件功能與通信協議,助力開發者專注于核心業務,提升效率,縮短周期,迅速適應市場變化。在傳統的
    的頭像 發表于 08-09 08:25 ?290次閱讀
    AWFlow:內置豐富的功能節點,簡化<b class='flag-5'>嵌入式開發</b>流程

    聚焦嵌入式開發的合規性工具、項目管理工具、版本迭代工具應用

    ,就嵌入式開發與管理領域的最新趨勢、工具選擇以及DevSecOps實踐應用等方面展開了深入探討。 本期對話龍智資深DevSecOps顧問徐晨暉, 分享嵌入式開發的合規性工具、項目管理和版本管理的工具選擇,以及DevSecOps
    的頭像 發表于 07-29 15:15 ?528次閱讀

    嵌入式開發前景怎么樣?

    嵌入式開發前景非常廣闊,這主要得益于物聯網、人工智能、大數據等技術的快速發展,以及嵌入式系統在各個領域的廣泛應用。以下是對嵌入式開發前景的詳細分析
    的頭像 發表于 07-10 09:00 ?2683次閱讀
    <b class='flag-5'>嵌入式開發</b>前景怎么樣?

    嵌入式開發就業前景怎么樣?

    一定的電路設計和編程能力。 2)醫療設備 醫療設備是指用于診斷、治療和輔助治療的各種設備。隨著醫療技術的不斷發展,醫療設備市場也在不斷擴大,嵌入式開發在醫療設備領域的應用前景也十分廣闊。在醫療設備領域
    發表于 06-07 14:51

    C語言嵌入式開發的關鍵編譯器角色

    嵌入式程序開發跟硬件密切相關,需要使用C語言來讀寫底層寄存器、存取數據、控制硬件等,C語言和硬件
    發表于 04-26 14:53 ?610次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>:<b class='flag-5'>嵌入式開發</b><b class='flag-5'>中</b>的關鍵編譯器角色

    如何成為一名嵌入式C語言高手?

    如何成為一名嵌入式C語言高手? 嵌入式系統是當今科技領域的核心,而C語言則是
    發表于 04-07 16:03

    如何成為一名嵌入式C語言高手?

    如何成為一名嵌入式C語言高手? 嵌入式系統是當今科技領域的核心,而C語言則是
    發表于 03-25 14:12

    fpga是嵌入式開發

    FPGA(現場可編程門陣列)與嵌入式開發之間確實存在一定的關聯,但它們在本質上是兩個不同的領域。
    的頭像 發表于 03-15 14:18 ?1033次閱讀

    聊一聊嵌入式C語言

    作為一名嵌入式軟件開發者,熟練掌握嵌入式C語言對我的日常工作至關重要。
    的頭像 發表于 01-22 09:28 ?544次閱讀

    嵌入式開發常見的C語言技巧與方法分享

    嵌入式開發,常常要操作寄存器,對寄存器進行寫入,讀出等等操作。每個寄存器都有自己固有的地址,通過C語言訪問這些地址就變得尤為重要。
    的頭像 發表于 12-26 09:55 ?1095次閱讀
    主站蜘蛛池模板: 国产色婷婷精品人妻蜜桃成熟| 开心色99xxxx开心色| 国产欧美日韩视频怡春院 | 中国jjzz| 97成人在线| 吃奶摸下的羞羞漫画| 国产精品久久久久影院嫩草| 国产又粗又猛又爽黄老大爷 | 国产精品成人网| 经典WC女厕所里TV| 久久有码中文字幕| 人曽交Z00Z0OA片| 小鸟酱喷水| 在线免费公开视频| YELLOW在线观看高清视频免费 | 高H黄暴NP辣H一女多男| 国产三级在线免费观看| 久久橹| 人妻互换免费中文字幕| 午夜一级毛片看看| 月夜直播免费观看全集| 草莓国产视频免费观看| 国产亚洲日韩另类在线播放| 乱码中字在线观看一二区| 日久精品不卡一区二区| 亚洲免费观看| 把手戳进美女尿口里动态图| 国产亚洲精品久久久久久线投注| 久久精品亚洲精品国产欧美| 日本红怡院亚洲红怡院最新| 亚洲香蕉网久久综合影院| GAY东北澡堂激情2022| 国内精品视频一区二区在线观看| 嗯啊好爽视频| 亚洲黄色官网| jealousvue成熟40岁| 狠狠射首页| 人妻中文字幕乱人伦在线| 一个人的视频在线观看免费观看 | 午夜视频在线观看国产| 99久久综合精品免费|