国产chinesehdxxxx老太婆,办公室玩弄爆乳女秘hd,扒开腿狂躁女人爽出白浆 ,丁香婷婷激情俺也去俺来也,ww国产内射精品后入国产

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

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

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

分析如何遠(yuǎn)離漫天飛舞的全局變量

工程師 ? 來(lái)源:嵌入式大雜燴 ? 作者:嵌入式大雜燴 ? 2020-09-15 13:49 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

來(lái)源:嵌入式大雜燴

前篇 《由static來(lái)談?wù)勀K封裝》 基本實(shí)現(xiàn)了對(duì)外隱藏屬性,隱藏局部模塊函數(shù),開(kāi)放接口的功能。對(duì)于這個(gè)話題還有些點(diǎn)沒(méi)有深入探討:為什么要這樣做?以及這樣做的好處。或許很多剛剛開(kāi)始用C或者其他面向?qū)ο?a target="_blank">編程語(yǔ)言(比如C++)的小伙伴們,常常在一個(gè)項(xiàng)目里為了圖省事,整了很多全局對(duì)象、全局變量滿天飛,這樣做其實(shí)是有很多弊端,本文來(lái)聊聊這個(gè)話題。

先談?wù)勅肿兞康奶攸c(diǎn)全局變量(Global Variables):在計(jì)算機(jī)編程語(yǔ)言中,所謂全局變量是指具有全局作用域的變量,這意味著它在整個(gè)程序中是可見(jiàn)的,因此是可訪問(wèn)的。所謂可訪問(wèn),是指全局可讀、全局可寫。在編譯語(yǔ)言中,全局變量通常是靜態(tài)變量,其范圍(生命周期)是程序的整個(gè)運(yùn)行時(shí)。當(dāng)然解釋性語(yǔ)言除外,解釋性語(yǔ)言包括命令行解釋器(比如python, Java script,shell等)中,全局變量通常在聲明時(shí)由解釋器動(dòng)態(tài)分配,這是由于解釋性語(yǔ)言是讀取》解釋》執(zhí)行模式,不像編譯性語(yǔ)言,運(yùn)行前可預(yù)知變量屬性,解釋性語(yǔ)言讀取解釋前無(wú)從獲取變量屬性。

在C/C++編程語(yǔ)言中,全局變量的這種全局可見(jiàn)性特點(diǎn),濫用全局變量會(huì)讓代碼表現(xiàn)當(dāng)相當(dāng)邪惡!如果使用全局變量,就意味著下面這些場(chǎng)景的存在:

實(shí)際代碼可能有很多地方在讀、在寫全局變量

全局變量在多線程或多任務(wù)間共享

全局變量在常規(guī)代碼和中斷服務(wù)程序間共享

為啥說(shuō)全局變量很邪惡?單片機(jī)裸機(jī)編程或許你會(huì)說(shuō),我就這樣用?咋了?軟件也跑的很好???來(lái)看看這個(gè)場(chǎng)景:

一個(gè)超字寬的變量(比如16位單片機(jī),字寬即為16位),正被一個(gè)常規(guī)代碼在寫變量數(shù)據(jù)域時(shí)且還沒(méi)寫完,啪嘰,來(lái)了個(gè)中斷!中斷一來(lái),CPU趕緊把手里的活兒停下來(lái),奔過(guò)去處理中斷了,不巧在中斷函數(shù)里,該變量因業(yè)務(wù)需求有需要寫這個(gè)變量有經(jīng)驗(yàn)的不這么寫,僅為了方便說(shuō)明:

舉個(gè)栗子,還是以之前文章的傳感器為例,實(shí)際應(yīng)用中傳感器可能是下面這樣的數(shù)據(jù)結(jié)構(gòu)來(lái)描述:

#ifndef _SENSOR_H_#define _SENSOR_H_typedef struct _t_sensor{ /* 測(cè)量值與測(cè)量范圍及單位有關(guān) */ float value; /* 測(cè)量范圍,根據(jù)采樣值映射 */ float upper_range; float lower_range; /* 溫度單位 */ unsiged char unit;}T_SENSOR;/*假定是一個(gè)溫度測(cè)量產(chǎn)品*/extern T_SENSOR temperature;#endif _SENSOR_H_

假定這個(gè)傳感器數(shù)據(jù)結(jié)構(gòu)有這樣一些被訪問(wèn)的可能:

上位機(jī)會(huì)改寫測(cè)量數(shù)據(jù)的范圍及單位,串口通信中斷服務(wù)程序直接寫這個(gè)全局變量中的上下限數(shù)據(jù)域

LCD操作界面可改寫溫度上下限范圍。

測(cè)量更新模塊根據(jù)當(dāng)前范圍及單位配置,將傳感器采集到的數(shù)據(jù)映射為測(cè)量值。

這些需求用例,用圖描述一下:

比如用戶操作HMI界面正改寫溫度范圍,而此時(shí)遠(yuǎn)程上位機(jī)也正改寫溫度范圍,按上面這個(gè)做法,可能出現(xiàn)哪些邪惡的后果呢?

通過(guò)LCD界面寫入上限為300.5(假定原下限為0),此時(shí)遠(yuǎn)程串口報(bào)文收到,程序直接在中斷服務(wù)程序?qū)⒎秶薷臑椋?100,200.5),此時(shí)中斷返回,用戶可能接著修改下限為-200,則最終設(shè)備內(nèi)的溫度范圍可能既不是(-100,200.5)也不是(-200,300.5),而可能是(-200,200.5)。這是一個(gè)易理解的數(shù)據(jù)混亂的場(chǎng)景。

現(xiàn)實(shí)中如果使用的單片機(jī)是8位/16位單片機(jī),一條指令無(wú)法完成操作一個(gè)32位立即數(shù),有可能才完成一個(gè)浮點(diǎn)數(shù)中某幾個(gè)字節(jié),此時(shí)就被中斷打斷寫入200,然后中斷返回后繼續(xù)寫入剩下字節(jié),數(shù)據(jù)可能會(huì)變得非常詭異!利用http://www.speedfly.cn/tools/hexconvert/ 在線工具轉(zhuǎn)換浮點(diǎn)數(shù)到16進(jìn)制:

0x43964000 /* 浮點(diǎn)數(shù)300.5的16進(jìn)制*/0x43488000 /* 浮點(diǎn)數(shù)200.5的16進(jìn)制*/

假定中斷進(jìn)入時(shí),HMI界面程序?qū)懭肓?x4396前兩個(gè)字節(jié),中斷返回時(shí),上限改寫為200.5(0x43488000),此時(shí)繼續(xù)執(zhí)行后面兩個(gè)字節(jié)寫入,則上限變成為(0x43484000),來(lái)看看這個(gè)數(shù)是多大?變成了200.25,這是不是很邪惡?

或許有的朋友會(huì)說(shuō),可以在LCD寫范圍時(shí)關(guān)中斷嘛。誠(chéng)然,可以這么做:

void hmi_operate(){ /*關(guān)中斷*/ _disable_interrupt(); /*改寫溫度范圍*/ 。。.。 /*開(kāi)中斷*/ _enable_interrupt();}

但是如果這個(gè)全局變量有很多地方在改寫,為了數(shù)據(jù)安全,勢(shì)必就到處開(kāi)/關(guān)中斷,這樣做的壞處:

經(jīng)常開(kāi)關(guān)中斷,勢(shì)必影響中斷響應(yīng),會(huì)有概率丟失異步中斷處理(比如串口按字節(jié)接收中斷,可能就會(huì)漏收字節(jié)),程序不健壯,工作不穩(wěn)定。

到處訪問(wèn)改寫,不易調(diào)試,群魔亂舞,代碼也不易維護(hù)。想加點(diǎn)東西,改點(diǎn)東西可能隨處都是坑,一不小心就掉坑里去了!

初學(xué)者甚至不會(huì)用struct將相關(guān)的數(shù)據(jù)包在一起,其結(jié)果是代碼里到處都是基本類型的全局變量。一些簡(jiǎn)單的業(yè)務(wù)邏輯實(shí)現(xiàn)變成一個(gè)復(fù)雜的代碼,數(shù)據(jù)信息流向一團(tuán)亂麻。

裸機(jī)程序策略對(duì)于上面這樣一個(gè)應(yīng)用場(chǎng)景,怎么解決這種混亂的現(xiàn)象呢。這里分享一下我的思路,這里將主要的串口以及測(cè)量模塊的設(shè)計(jì)思路用UML圖描述一下大體思路:

如此一來(lái),外部就看不到全局變量了,只需要調(diào)用對(duì)應(yīng)的set/get方法即可實(shí)現(xiàn)讀寫訪問(wèn),由于是裸機(jī)前后臺(tái)程序,數(shù)據(jù)流向就變的非常清晰了。main函數(shù)的主循環(huán)大致就可能是這樣:

void main(void){ /*模塊初始化*/ init_uart(); init_temperature(); 。。.。 while(1) { interprete_uart(); /*可能是周期性調(diào)用*/ if(timer_100ms) { timer_100ms = 0; update_temperature(); } 。。.。 } }

那么uart協(xié)議解析要怎么做呢?

void interprete_uart(void){ if(rx_msg.flag) { rx_msg.flag = false; /*報(bào)文完整性檢查*/ 。。. /*設(shè)置溫度配置*/ set_upper_range(xxx); set_lower_range(xxx); set_unit(xxx); } if(tx_msg.flag) { tx_msg.flag = false; start_send(); }}static start_send(T_UART_MSG *pMsg){ /*負(fù)責(zé)底層操作,啟動(dòng)中斷傳輸*/}/*提供應(yīng)答數(shù)據(jù)接口*/void reply_temperature_setting(T_SENSOR sensor){ /*解析傳入?yún)?shù)并封裝應(yīng)答報(bào)文*/}

如此一來(lái),數(shù)據(jù)流向?qū)⒆兊煤芮逦?,串口接收到?shù)據(jù)更新范圍配置時(shí),也無(wú)需開(kāi)關(guān)中斷了,從應(yīng)用角度幾乎見(jiàn)不到全局變量。當(dāng)然這樣做的代價(jià)就是會(huì)增加一些棧開(kāi)銷。但是這種代價(jià)還是值得的。

對(duì)于測(cè)量模塊的set函數(shù)思路稍做說(shuō)明:

int set_upper_range(float range){ T_SENSOR temp = temperature; temp.upper_range = range; /*實(shí)現(xiàn)范圍合理性檢查*/ if(check_range(temp)) { /*兩個(gè)結(jié)構(gòu)體變量可以直接賦值*/ temperature = temp; return 0; } else { return -1; }}int set_unit(E_UNIT unit){ if(unit》E_UNIT_F) return -1; adjust_range(&temperature,unit); temperature.unit = unit; }

上述代碼旨在分享個(gè)人的一些思路,其中或有不夠嚴(yán)謹(jǐn)?shù)牡胤?,但通過(guò)這樣的設(shè)計(jì)思路,應(yīng)能大幅度遠(yuǎn)離滿天飛的全局變量。

多任務(wù)/多線程環(huán)境上面描述其實(shí)本質(zhì)上描述了裸機(jī)程序里,普通模式運(yùn)行程序與中斷服務(wù)程序?qū)τ谂R界資源的競(jìng)爭(zhēng)。事實(shí)上現(xiàn)在不管是單片機(jī),還是處理器,大多都是基于一個(gè)操作系統(tǒng)進(jìn)行應(yīng)用開(kāi)發(fā)。甚至還可能是多核芯片,這里就存在并發(fā)競(jìng)爭(zhēng)訪問(wèn)資源的問(wèn)題。

臨界資源:各任務(wù)/線程采取互斥的方式,實(shí)現(xiàn)共享的資源稱作臨界資源。屬于臨界資源的硬件串口打印、顯示等,軟件有消息緩沖隊(duì)列、變量、數(shù)組、緩沖區(qū)等。多任務(wù)/線程間應(yīng)采取互斥方式,從而實(shí)現(xiàn)對(duì)這種資源的共享。

多任務(wù)/多線程情況下在寫模塊時(shí),只需要封裝進(jìn)保護(hù)機(jī)制即可。常見(jiàn)的保護(hù)機(jī)制有關(guān)中斷、信號(hào)量、互斥鎖等。在Linux內(nèi)核中為應(yīng)對(duì)多核并發(fā)訪問(wèn)還有自旋鎖機(jī)制。由于篇幅所限,本文就不做展開(kāi)了,先挖個(gè)坑,以后有機(jī)會(huì)再分享吧。

總結(jié)一下在前文介紹static文章的基礎(chǔ)上,相對(duì)更深入的介紹了為何需要隱藏屬性以及開(kāi)放接口的做法。以及如何遠(yuǎn)離邪惡的全局變量漫天飛舞的不良設(shè)計(jì)風(fēng)格。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2119

    瀏覽量

    75264
  • 全局變量
    +關(guān)注

    關(guān)注

    1

    文章

    28

    瀏覽量

    9141
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    請(qǐng)問(wèn)Modus Toolbox下針對(duì)CYW20719B2編程,能否指定全局變量地址?

    請(qǐng)問(wèn)Modus Toolbox 下針對(duì)CYW20719B2編程,能否指定全局變量地址?
    發(fā)表于 07-08 07:20

    Cubeide1.18.1在線調(diào)試改變\"現(xiàn)場(chǎng)表達(dá)式\"中的值提示找不到地址,為什么?

    Cubeide1.18.1在線調(diào)試時(shí),在\"現(xiàn)場(chǎng)表達(dá)式\"中添加全局變量,然后改變其數(shù)值,Console窗口提示: Failed to read all registers
    發(fā)表于 06-12 06:50

    Cubeide1.18.1在線調(diào)試改變\"現(xiàn)場(chǎng)表達(dá)式\"中的值提示找不到地址是怎么回事?

    Cubeide1.18.1在線調(diào)試時(shí),在\"現(xiàn)場(chǎng)表達(dá)式\"中添加全局變量,然后改變其數(shù)值,Console窗口提示: Failed to read all registers
    發(fā)表于 06-10 08:26

    開(kāi)疆智能Ethernet/IP轉(zhuǎn)Modbus網(wǎng)關(guān)連接MAG8000電池流量計(jì)配置案例

    /IP連接設(shè)置,在彈出的選個(gè)框內(nèi)選擇顯示EDS庫(kù)添加網(wǎng)關(guān)eds文件 開(kāi)始安裝網(wǎng)關(guān)EDS文件,并在完成后選擇對(duì)應(yīng)模塊。EIP2COM 設(shè)置網(wǎng)關(guān)IP地址(注意不要與其他設(shè)備IP沖突) 添加全局變量并關(guān)聯(lián)
    的頭像 發(fā)表于 06-07 11:19 ?202次閱讀
    開(kāi)疆智能Ethernet/IP轉(zhuǎn)Modbus網(wǎng)關(guān)連接MAG8000電池流量計(jì)配置案例

    Cubeide1.18.1在線調(diào)試改變\"現(xiàn)場(chǎng)表達(dá)式\"中的值提示找不到地址,怎么解決?

    Cubeide1.18.1在線調(diào)試時(shí),在\"現(xiàn)場(chǎng)表達(dá)式\"中添加全局變量,然后改變其數(shù)值,Console窗口提示: Failed to read all registers
    發(fā)表于 06-06 08:27

    開(kāi)疆智能Etherenet轉(zhuǎn)Modbus網(wǎng)關(guān)連接歐姆龍PLC配置案例

    模塊。 添加全局變量并關(guān)聯(lián) 在PLC組態(tài)軟件的Ethernet/IP端口設(shè)置中將全局變量關(guān)聯(lián)至網(wǎng)關(guān)組態(tài)。 配置完成后將組態(tài)下
    的頭像 發(fā)表于 06-05 16:43 ?196次閱讀
    開(kāi)疆智能Etherenet轉(zhuǎn)Modbus網(wǎng)關(guān)連接歐姆龍PLC配置案例

    飛凌嵌入式ElfBoard ELF 1板卡-uboot編譯鏈接文件uboot.lds

    :.text代碼段通常是指用來(lái)存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域;.data數(shù)據(jù)段.通常是指用來(lái)存放程序中已初始化的全局變量的一塊內(nèi)存區(qū)域;.bss段通常是指用來(lái)存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域;當(dāng)然有的.o文件中不僅僅只有這三個(gè)基本數(shù)據(jù)段,還有其他的段和自定義的段
    發(fā)表于 05-22 11:20

    Cubeide1.18.1在線調(diào)試改變\"現(xiàn)場(chǎng)表達(dá)式\"中的值提示找不到地址怎么解決?

    Cubeide1.18.1在線調(diào)試時(shí),在\"現(xiàn)場(chǎng)表達(dá)式\"中添加全局變量,然后改變其數(shù)值,Console窗口提示: Failed to read all registers
    發(fā)表于 04-27 06:18

    static在單片機(jī)中的妙用

    了呢?一起來(lái)看下吧一、修飾變量第一個(gè)作用修飾變量,變量又分為局部變量全局變量,但它們都存在內(nèi)存的靜態(tài)區(qū)。 對(duì)于靜態(tài)區(qū),堆棧等等這些區(qū)域的概
    發(fā)表于 04-02 13:50 ?1次下載

    VirtualLab Fusion應(yīng)用:參數(shù)耦合

    。 源代碼標(biāo)簽包含以下三部分: 源代碼(中心區(qū)域) 全局變量/參數(shù)(右側(cè)上端) 選擇系統(tǒng)參數(shù)(右側(cè)底端) 6.參數(shù)耦合的一般示例 ?通常,利用代碼字典讀取所選參數(shù)并將其保存到變量(第4行)。 ?之后
    發(fā)表于 03-17 11:11

    求助,關(guān)于STM32G070封裝HAL_GetTick的疑問(wèn)求解

    HAL_GetTick函數(shù),默認(rèn)使用了滴答定時(shí)器中斷,并使用了全局變量uwTick,這個(gè)變量是32位的,那變量溢出了就會(huì)從0開(kāi)始,許多外設(shè)超時(shí)判斷的語(yǔ)句是HAL_GetTick() - Tickstart>TimeOut,
    發(fā)表于 03-14 07:20

    FRED案例:天文光干涉儀

    。干涉儀的小孔半徑為1mm,反射鏡距離為50mm。右:增加反射鏡間距到100mm的干涉圖樣,此干涉圖的能見(jiàn)度降低了。 全局變量的腳本 條紋可見(jiàn)度是光源角度范圍、光譜含量、小孔半徑和兩個(gè)外反射鏡(M1
    發(fā)表于 01-21 09:58

    天文光干涉儀

    的小孔半徑為1mm,反射鏡距離為50mm。右:增加反射鏡間距到100mm的干涉圖樣,此干涉圖的能見(jiàn)度降低了。全局變量的腳本 條紋可見(jiàn)度是光源角度范圍、光譜含量、小孔半徑和兩個(gè)外反射鏡(M1和M2)之間
    發(fā)表于 12-25 15:26

    為什么同一個(gè)隊(duì)列引用的全局變量,運(yùn)行在兩個(gè)子vi中發(fā)現(xiàn)隊(duì)列數(shù)據(jù)丟失了

    我創(chuàng)建了一個(gè)隊(duì)列,然后將隊(duì)列引用做了個(gè)全局變量,運(yùn)行在兩個(gè)子vi中,一個(gè)是只入隊(duì)列,另一個(gè)是只出隊(duì)列。但我發(fā)現(xiàn),一個(gè)字vi數(shù)據(jù)入隊(duì)列成功,檢查隊(duì)列元素?cái)?shù)量也已經(jīng)是1了,這時(shí)我運(yùn)行另一個(gè)子vi,出隊(duì)列前檢查隊(duì)列數(shù)量發(fā)現(xiàn)為0了。隊(duì)列里的數(shù)據(jù)沒(méi)了。而且這個(gè)情況不是一直有,是偶爾發(fā)生。
    發(fā)表于 11-14 11:47

    labview主程序運(yùn)行時(shí)如何引起子VI里的事件結(jié)構(gòu)響應(yīng)

    設(shè)計(jì)了一個(gè)程序需要通過(guò)主VI的按鍵控制子VI事件發(fā)生,設(shè)置了個(gè)全局變量作為媒介,但是值會(huì)變事件并不會(huì)發(fā)生
    發(fā)表于 11-10 13:04