久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5171|回復: 21
打印 上一主題 下一主題
收起左側(cè)

解決一個C語言程序分號“;”引起的bug

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:282850 發(fā)表于 2022-9-13 23:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
曾想也標題黨一次,寫成《一個C程序分號“;”引起的血案》,筆者原本厭惡標題黨,厭惡那些“xxxx了”、“XXXX震驚,不看后悔”、“XXXX,看這個就夠了”。也就不在此惡心各位同好。
C程序的分號,是任何寫過C程序的人都明白的,很重要,用的很多。但此文將要說明的是分號不正確的使用,導致一個隱藏的Bug。

一、發(fā)現(xiàn)錯誤
家用的太陽能熱水器控制,執(zhí)行電加熱后,本來有一個LED燈閃爍,提示電加熱是開啟的。原來用了兩年多,一直正常,前幾天發(fā)現(xiàn)是啟動電加熱后,閃一次LED就熄滅。全套控制、接線都是自己一點點搞起來的,所以要解決這個故障,有了優(yōu)勢,但更有了苦命累積。一個同事二貨在別墅頂上裝了太陽能熱水器,為了陰天有熱水,另外加了一個電熱水器,還要考慮閥門切換,考慮電熱水器防雨、考慮啟動或關(guān)閉總電源等等,反正一切由安裝的說了算,不用費腦子。想想我布的多根網(wǎng)線、多點測溫、兩組太能能占據(jù)掉的位置,自己在斜的瓦屋頂上熔水管、焊接線,那么多辛苦都過去了,借肋中秋節(jié)放假而且一直下雨在家的時間,有必要把LED不指示的問題解決。

二、查找問題
記得LED指示燈與電加熱分別各用一個IO口,也必須如此,才可以閃爍,不然加熱時變成繼電器反復通斷。LED用9012PNP管驅(qū)動,且平時一直會微閃,這個一開始就如此,胡亂微閃就閃吧,大概分析了一下,如果用NPN管不會微閃,PNP如果調(diào)偏置電阻也可以使全滅,涉及小小的三極管復雜的功能,在此不跑主題,也不細說。
未連接系統(tǒng),隨意看了一下程序,程序應該沒有動過,上月寫兩個發(fā)明專利時,為了測試幾個數(shù)據(jù),重新下載過一套改版的程序到Flash,后又恢復了。原因可能是在什么時候動過程序,導致出現(xiàn)Bug。程序看不出明顯的錯誤,必須聯(lián)機調(diào)試,監(jiān)視一下變量。
真是累不動。還好SBW下載線制作過一根專用的,直接插上就OK,不用其它排列順序的下載線換線位。搜索全部工程文件“電加熱” “電熱”,找到以下語句:
#define EHeat_off   P7OUT |=  BIT0; EHisON=0  //電加熱off
#define EHeat_on    P7OUT &=~ BIT0; EHisON=1  //電加熱on
聚焦到EHeat_off語句,再搜EHeat_off,只有3處有過:
1、              BASICTIMER_VECTOR定時器中斷250ms一次,快結(jié)束時啟動一次測溫,在測溫程序中,結(jié)果出來后,用了以下:
  /*-----------停止電加熱-----------*/
if(UperT > EleHeatTempe*10)  EHeat_off;     //達到設(shè)置溫度(45.0---450),關(guān)閉電加熱。
2、              第二處是狀態(tài)機控制的菜單程序中,當Cancel時,關(guān)閉電加熱:
if(Menu_sel==3)   EHeat_off;
另外一處就是define處的定義了。

三、解決問題
程序高手估計已經(jīng)發(fā)現(xiàn)問題了,筆者愚鈍。啟動電加熱后,中斷并監(jiān)視P7口,P70確實是0,剛好這兩周,家里主空開被我拆了調(diào)整空開位準備在家門口接充電樁,用鉗表卡16平總進戶線電流5A多,關(guān)閉電加熱時0.3A。證明加熱正常。僅僅是指示燈出故障。再搜索全部工程,除了3處定義,只在__interrupt void BT_ISR(void)中出現(xiàn)過:
if(  EHisON) P4OUT ^=  BIT2;      //電加熱指示燈閃
else  if((P4IN & BIT2) ==0 )   P4OUT |=  BIT2;
程序前強加一個EHisON=1; 指示燈會閃。說明PNP管、LED均正常。EHisON是一個標志電加熱是打開狀態(tài)的變量,原意是開關(guān)電熱時,一并切換此標志是開或關(guān)。監(jiān)視此變量總是為0。
回到if(UperT > EleHeatTempe*10)  EHeat_off;終于發(fā)現(xiàn)問題。這個語句相當于:
if(UperT > EleHeatTempe*10)  P7OUT |=  BIT0; EHisON=0;
很明顯,if執(zhí)行了“P7OUT |=  BIT0;”,而“EHisON=0;”不論if如何都會執(zhí)行,解決辦法自然是加{}。當然還有另一個解決辦法,不用加{},看大家的興趣,我在后邊回復中說明。

我一般寫define時,習慣是最后不加“;”而在執(zhí)行代碼中加,這樣看上去比較統(tǒng)一。此次定義是P7OUT |=  BIT0和EHisON=0兩個語句,故在中間順手加了一個“;”。又一個習慣是簡單的if喜歡一行寫完,不加{}。甚至長一點的if都喜歡一行寫完,以讓小小的屏幕好容納上萬行代碼。各種習慣、巧合,導至這個Bug正常運行了2年時間。今天回頭找最老版的程序查看,這個錯誤一直在,不明白為什么原來可以正常閃爍,難道編譯器根據(jù)option設(shè)置修正過此錯誤?如果有明白的大神,請不吝賜教,先謝謝了。主控是MSP430F4152,但IDE我不說了(IXX6),涉及其它不必要的麻煩。
另外,我不喜歡那些上傳整套程序的,一般也無心看,除非是自己手上有的小模塊,而又沒有玩過的,針對此模塊的驅(qū)動可以看看。也更喜歡關(guān)注思路、方法、原理。所以也不上傳整套程序,畢竟各種場合的應用不一樣、解決方案各不同,拙作也就不傷大家眼了。

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂3 踩
回復

使用道具 舉報

沙發(fā)
ID:614312 發(fā)表于 2022-9-14 12:56 | 只看該作者
學C語言的經(jīng)典 坑了。
回復

使用道具 舉報

板凳
ID:262 發(fā)表于 2022-9-15 20:53 | 只看該作者
對初學者很有用,當年好像遇到過這情況
回復

使用道具 舉報

地板
ID:1046043 發(fā)表于 2022-9-27 16:29 | 只看該作者
弄了個開發(fā)板,準備開始學單片機啦,加油
回復

使用道具 舉報

5#
ID:151348 發(fā)表于 2022-10-9 09:30 | 只看該作者
別提了,我也有你提到的編程壞習慣,語句寫成一行,又不加{},開始時死活找不出bug,以后真的要注意了
回復

使用道具 舉報

6#
ID:310441 發(fā)表于 2022-10-11 07:20 來自手機 | 只看該作者
后面你一定會養(yǎng)成if的內(nèi)容加花括號的習慣的
回復

使用道具 舉報

7#
ID:260656 發(fā)表于 2022-10-16 17:31 | 只看該作者
{}太重要了,被坑過
回復

使用道具 舉報

8#
ID:1032507 發(fā)表于 2022-10-28 10:10 | 只看該作者
受教了,給大家也提了個醒,以后會注意這個問題,養(yǎng)成良好的編程習慣。
回復

使用道具 舉報

9#
ID:1049806 發(fā)表于 2022-11-7 15:30 | 只看該作者
確實細節(jié)很重要
回復

使用道具 舉報

10#
ID:77589 發(fā)表于 2022-11-11 14:29 | 只看該作者
這個根本就不是";"號的號題。。!
在定義多條語句宏的時候,至少需要用{}把語句框起來!
#define EHeat_off   {P7OUT |=  BIT0; EHisON=0;}  //電加熱off
#define EHeat_on    {P7OUT &=~ BIT0; EHisON=1;}  //電加熱on
如果想更加保險一點應用下面格式寫更好
//電加熱off
#define EHeat_off   do {P7OUT |=  BIT0; EHisON=0;} while(0);
//電加熱on
#define EHeat_on   do {P7OUT &=~ BIT0; EHisON=1;} while(0);
為什么這樣寫,網(wǎng)上有大佬分析過。


回復

使用道具 舉報

11#
ID:142059 發(fā)表于 2022-11-11 23:58 來自手機 | 只看該作者
使用宏替換多行代碼時,在調(diào)用養(yǎng)成加大括號后再調(diào)用的習慣
回復

使用道具 舉報

12#
ID:142059 發(fā)表于 2022-11-11 23:59 來自手機 | 只看該作者
Longan.Wang 發(fā)表于 2022-11-11 14:29
這個根本就不是";"號的號題。。。
在定義多條語句宏的時候,至少需要用{}把語句框起來!
#define EHea ...

對的,用do來概括多行宏,根本不是分號問題,給你一個贊
回復

使用道具 舉報

13#
ID:282850 發(fā)表于 2022-11-12 01:19 | 只看該作者
Longan.Wang 發(fā)表于 2022-11-11 14:29
這個根本就不是";"號的號題!。!
在定義多條語句宏的時候,至少需要用{}把語句框起來!
#define EHea ...

感謝回復,我的解決辦法就是這樣:
#define EHeat_off   {P7OUT |=  BIT0; EHisON=0;}  //電加熱off
#define EHeat_on    {P7OUT &=~ BIT0; EHisON=1;}  //電加熱on
用do while應該有它的好處,大佬畢竟是大佬。
基于現(xiàn)在屏幕大部分時候是橫向的,特別是對于我用筆記本來說。更喜歡把一件事寫在一行,好象看著更簡潔,好比:
unsigned char aa,bb,cc;
至于"定義多條語句宏的時候,至少需要用{}把語句框起來",這有點絕對了。
實際上:
#define EHeat_off    P7OUT |=   BIT0 ,EHisON=0     //電加熱off
#define EHeat_on    P7OUT &=~ BIT0, EHisON=1  //電加熱on
上邊語句完全可以實現(xiàn)功能,且最后是沒有分號的,以方便按習慣在調(diào)用時后邊再加分號,如:
if(...)  EHeat_off;
上邊實際上是“,”的用法,好比在寫if時為節(jié)約行數(shù),if后同時要做的事一并寫了,不用{}。
如:if(a>b) c=a,a=b,b=c;    //交換順序
畢竟是業(yè)余玩,不是按代碼行數(shù)拿薪水,我個人更喜歡上邊這種寫法,當然,壞處是出現(xiàn)了我本主題的毛病,另外也不排除在上邊if中隨手把“,”寫成分號導致隱藏的錯誤。
回復

使用道具 舉報

14#
ID:879348 發(fā)表于 2022-11-12 08:31 | 只看該作者
一般不是數(shù)值的話,我都是搞成函數(shù)的形式,而不是#define
回復

使用道具 舉報

15#
ID:507641 發(fā)表于 2022-11-15 15:56 | 只看該作者
Longan.Wang 發(fā)表于 2022-11-11 14:29
這個根本就不是";"號的號題!!。
在定義多條語句宏的時候,至少需要用{}把語句框起來!
#define EHea ...

為什么這樣寫,網(wǎng)上有大佬分析過   請給連接想學下。謝謝
回復

使用道具 舉報

16#
ID:1010910 發(fā)表于 2022-11-27 20:37 | 只看該作者
B站上有c 語言學習視頻
回復

使用道具 舉報

17#
ID:408539 發(fā)表于 2023-1-11 22:17 | 只看該作者
語句短我一般加,號不用{}
回復

使用道具 舉報

18#
ID:282850 發(fā)表于 2023-2-15 22:44 | 只看該作者
明記冷氣 發(fā)表于 2023-1-11 22:17
語句短我一般加,號不用{}

謝謝,還是找到一個知音了。
回復

使用道具 舉報

19#
ID:399179 發(fā)表于 2023-4-11 20:20 來自手機 | 只看該作者
以后學C語要細心了!
回復

使用道具 舉報

20#
ID:1073883 發(fā)表于 2023-4-24 21:00 | 只看該作者
答主講的非常仔細
回復

使用道具 舉報

21#
ID:1130105 發(fā)表于 2024-8-3 13:42 | 只看該作者
好多次了,IFELSE后跟一條語句,不加{};后來客戶提要求,加了之后出BUG,頭疼了半個多鐘頭
回復

使用道具 舉報

22#
ID:1110944 發(fā)表于 2025-4-4 01:33 | 只看該作者
哈哈,很有意思啊
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 永久看片| 91精品国产91综合久久蜜臀 | 91丨九色丨国产在线 | 国产一区二区三区不卡av | 91精品一区二区 | 国产成人av一区二区三区 | 夜夜爽99久久国产综合精品女不卡 | 中文字幕91av | 亚洲第1页| 视频一区二区三区四区五区 | 亚洲精品中文字幕av | 在线视频 亚洲 | 国产精品视频久久久 | 爱草在线| 色欧美日韩 | 日韩色图视频 | 亚洲成人动漫在线观看 | 成人免费在线观看 | 九九九久久国产免费 | 国产成人精品视频在线观看 | 日韩精品视频在线播放 | 在线欧美日韩 | 这里精品| 第一av| 国产精品久久久久久久久免费高清 | 亚洲国产成人精品在线 | 久久久久久久国产 | 一区二区三区四区在线视频 | 亚洲va中文字幕 | 久久精品在线播放 | 国产丝袜一区二区三区免费视频 | 色婷婷精品久久二区二区蜜臂av | 91影视 | 一区二区日韩 | 罗宾被扒开腿做同人网站 | www.日本精品 | 国产99精品 | 中文字幕综合 | 老妇激情毛片免费 | 午夜精品一区二区三区在线视频 | 中文字幕在线观看国产 |