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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2189|回復: 25
收起左側

C語言判斷某個值狀態過多時,如何優化

  [復制鏈接]
回帖獎勵 10 黑幣 回復本帖可獲得 10 黑幣獎勵! 每人限 2 次
ID:777254 發表于 2024-8-1 08:58 | 顯示全部樓層 |閱讀模式
假定有一個16位變量,代表不同狀態,狀態有幾千種,且某些功能的狀態值是不連續的。
開始使用swtch case寫,發現case太多了,放棄。
又改成if else判斷,這樣可以把某些連續的狀態使用一個判斷完成,但是寫下來還是有幾十個if else.
還能在優化嗎?
回復

使用道具 舉報

ID:777254 發表于 2024-8-1 19:41 | 顯示全部樓層
目前的解析一個協議,一開始用witch,分支有數據讀寫之類的幾個大case;然后讀功能里面需要讀的協議太多了,我看了協議文檔,幾千條。所以讀分支里面不能再用switch了,不然又有幾千個分支。目前是在讀分支里面使用if else寫著。因為查表法需要數組,RAM也要花費好多,所以暫時不用數組建立表了。還有好方法嗎?盡量不占用/少用RAM空間
回復

使用道具 舉報

ID:1109793 發表于 2024-8-1 10:21 | 顯示全部樓層
幾千種,那可是復雜了,這么復雜的系統,厲害了。要不先分開,比如>10<20,每10個分一組?
回復

使用道具 舉報

ID:277550 發表于 2024-8-1 11:15 | 顯示全部樓層
幾十個,不算多了。想優化,在if之前優化。
回復

使用道具 舉報

ID:69038 發表于 2024-8-1 11:18 | 顯示全部樓層
"假定有一個16位變量,代表不同狀態,狀態有幾千種,且某些功能的狀態值是不連續的。"
如果真有幾千種的狀態,只能說這個系統架構有問題了。才疏學淺想不出這么多復雜的狀態,只用一個16位變量來表示。。

建議參考LCM1602、LCM12864的指令集做個散轉表,或許能實現。它是一個8bit的寄存器,從bit7開始,共8個標志,除開標志位,余下的bit是參數值(如果有的話)。。

圖樣1

圖樣1



回復

使用道具 舉報

ID:276663 發表于 2024-8-1 12:41 | 顯示全部樓層
跟樓上意思類似,借鑒IPV4,使用掩碼分級判斷,歸類處理
回復

使用道具 舉報

ID:744809 發表于 2024-8-1 15:14 | 顯示全部樓層
寫一個映射表,從值映射到狀態,然后用switch
回復

使用道具 舉報

ID:220661 發表于 2024-8-1 15:44 | 顯示全部樓層
數組吧,節省空間,提升速度。
回復

使用道具 舉報

ID:1087128 發表于 2024-8-1 16:16 | 顯示全部樓層
if先判斷一個范圍
回復

使用道具 舉報

ID:451718 發表于 2024-8-1 17:35 | 顯示全部樓層
從數據結構的角度出發,你在一個分支下面查詢上千個塞選,本身就是不科學的。最好的優化方法,就是不斷的細分,采用多級查詢。
回復

使用道具 舉報

ID:624769 發表于 2024-8-1 18:43 | 顯示全部樓層
c語言如何實現 不太清楚, 匯編的話,可以根據變量值  直接跳轉若干行(比如: JMP  @A+PC),然后在  相應的位置寫下分支就可以了。
回復

使用道具 舉報

ID:777254 發表于 2024-8-1 19:33 | 顯示全部樓層
xiaobendan001 發表于 2024-8-1 10:21
幾千種,那可是復雜了,這么復雜的系統,厲害了。要不先分開,比如>10

協議功能碼太多了,不同功能發送不同數據,越寫case越多,不好搞
回復

使用道具 舉報

ID:777254 發表于 2024-8-1 19:35 | 顯示全部樓層
gongnn 發表于 2024-8-1 15:44
數組吧,節省空間,提升速度。

不行啊,一個數組包含的狀態也很多,導致RAM不夠。
回復

使用道具 舉報

ID:777254 發表于 2024-8-1 19:41 | 顯示全部樓層
zhuls 發表于 2024-8-1 11:18
"假定有一個16位變量,代表不同狀態,狀態有幾千種,且某些功能的狀態值是不連續的。"
如果真有幾千種的狀 ...

好的,謝謝,我參考一下
回復

使用道具 舉報

ID:57657 發表于 2024-8-1 21:42 | 顯示全部樓層
li1069136863 發表于 2024-8-1 19:35
不行啊,一個數組包含的狀態也很多,導致RAM不夠。

你要搞清楚 C語言是單片機還是操作系統運行的 寫法不一樣
回復

使用道具 舉報

ID:57657 發表于 2024-8-1 21:51 | 顯示全部樓層
用二分查找,找到的取出索引 然后用該索引地址定位到函數指針數組執行相應的函數,找不到的執行default。
回復

使用道具 舉報

ID:401564 發表于 2024-8-2 13:07 | 顯示全部樓層
不知道你這個是什么協議,幾千個狀態,那不得幾千個函數來處理?在單片機領域,搞這種東西出來的,十有八九是新手
還不如果直接說,你要干嘛,說不定網還能幫到你
如果說從一開始,方向就是錯的,那就太浪費時間了
回復

使用道具 舉報

ID:1129414 發表于 2024-8-2 17:00 | 顯示全部樓層
你寫的是啥,判斷幾千個狀態,單片機估計夠嗆
回復

使用道具 舉報

ID:777254 發表于 2024-8-2 20:20 | 顯示全部樓層
Y_G_G 發表于 2024-8-2 13:07
不知道你這個是什么協議,幾千個狀態,那不得幾千個函數來處理?在單片機領域,搞這種東西出來的,十有八九是新 ...

電表的DLT645協議,里面的協議太多,需要讀取的參數太多了,不知道怎么優化。
回復

使用道具 舉報

ID:777254 發表于 2024-8-2 20:28 | 顯示全部樓層
li1069136863 發表于 2024-8-1 19:41
目前的解析一個協議,一開始用witch,分支有數據讀寫之類的幾個大case;然后讀功能里面需要讀的協議太多了 ...

是DLT645-2007電表協議,有做過的大佬嗎?
回復

使用道具 舉報

ID:57657 發表于 2024-8-2 22:24 | 顯示全部樓層
狀態表數組使用二分查找 可以不連續但必須從小到大排序,找到的返回索引,找不到的返回指定數字。
然后用索引訪問指針表數組,取出函數指針并傳遞參數執行,最后取回返回值,如果參數還傳遞其他數據類型或數組可能涉及多級指針。
回復

使用道具 舉報

ID:982617 發表于 2024-8-7 16:04 | 顯示全部樓層
面對大量狀態處理的場景,確實單靠 `switch-case` 或 `if-else` 結構可能會顯得冗長且難以維護。你可以考慮以下幾種優化策略:

1. **枚舉類型(Enum)**:將狀態值定義為枚舉類型,這樣不僅代碼更清晰,還可以利用編譯器的靜態檢查避免狀態值的誤用。枚舉類型能提供更好的可讀性,并且可以更方便地添加或修改狀態。

   ```c
   enum State {
       STATE_1, STATE_2, STATE_3, ... // 具體狀態
   }
   ```

2. **狀態機(State Machine)**:如果狀態之間有明確的轉換邏輯,可以設計一個狀態機來管理狀態的轉換。狀態機通過一系列狀態轉換函數或狀態對象來實現,這樣可以清晰地表示狀態之間的依賴關系和轉換條件。

   ```c
   void process_state(State current_state) {
       switch (current_state) {
           case STATE_1:
               // 處理STATE_1邏輯
               break;
           case STATE_2:
               // 處理STATE_2邏輯
               break;
           // ...
           default:
               // 處理未知狀態
               break;
       }
   }
   ```

3. **宏定義**:對于某些頻繁使用的邏輯,可以考慮使用宏來定義,簡化代碼并提高可讀性。

   ```c
   #define PROCESS_STATE(state) do {\
       if (state == STATE_1) {\
           // 處理STATE_1邏輯\
       } else if (state == STATE_2) {\
           // 處理STATE_2邏輯\
       } else if (state == STATE_3) {\
           // 處理STATE_3邏輯\
       } // 更多狀態\
   } while(0)
   ```

4. **使用函數指針或宏來封裝狀態邏輯**:如果每個狀態的處理邏輯不同且較為復雜,可以考慮使用函數指針或宏來封裝邏輯,這樣可以使得每個狀態的邏輯獨立且易于維護。

   ```c
   typedef void (*StateHandler)(void);
   StateHandler state_handlers[] = {
       &process_state_1,
       &process_state_2,
       // 更多狀態函數\
   };

   void process_state(State state) {
       state_handlers[state]();
   }
   ```

5. **使用類或結構體**:對于復雜的狀態,可以考慮使用類或結構體來封裝狀態的屬性和處理邏輯。這樣可以更好地組織代碼,提高可讀性和可維護性。

   ```c
   struct State {
       void (*handle)(void);
   };

   void process_state(State state) {
       state.handle();
   }
   ```

6. **性能考慮**:在選擇優化策略時,也需要考慮性能影響。宏和函數調用在某些情況下可能會帶來額外的開銷。在進行優化時,可以先進行性能測試,確保優化后代碼的執行效率滿足需求。

通過上述方法,你可以更有效地管理和處理大量狀態,提高代碼的可讀性和可維護性。根據具體需求和場景,選擇最適合的優化策略。
回復

使用道具 舉報

ID:688692 發表于 2024-8-8 14:05 | 顯示全部樓層
li1069136863 發表于 2024-8-2 20:28
是DLT645-2007電表協議,有做過的大佬嗎?

你是要實現協議還是做這個協議的上位機?我寫過一個簡單的上位機,不復雜。要實現這個協議,幾十個if是合理范圍。
回復

使用道具 舉報

ID:777254 發表于 2024-8-8 20:20 | 顯示全部樓層
cnos 發表于 2024-8-8 14:05
你是要實現協議還是做這個協議的上位機?我寫過一個簡單的上位機,不復雜。要實現這個協議,幾十個if是合 ...

我是接收上位機發來的DLT645協議,實現對應功能。太多參數要讀寫了,目前用if else,能把連續的協議簡化,看起來沒那么臃腫
回復

使用道具 舉報

ID:57657 發表于 2024-8-9 05:30 | 顯示全部樓層
hezezeze 發表于 2024-8-7 16:04
面對大量狀態處理的場景,確實單靠 `switch-case` 或 `if-else` 結構可能會顯得冗長且難以維護。你可以考慮 ...

類是操作系統的運行環境才有的,單片機內存小幾乎不可能。
回復

使用道具 舉報

ID:844772 發表于 2024-8-9 08:46 | 顯示全部樓層
其實就是個簡單的數據庫搜索功能,但用單片機實現就很麻煩。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人久久视频 | 日皮视频免费 | 欧美一区二区三区 | 国产伦一区二区三区四区 | 69热视频在线观看 | 国产精品久久久久久吹潮 | 看片91| 在线视频一区二区三区 | 一区二区三区四区在线视频 | 日韩一区二区在线观看视频 | 久久亚洲国产精品日日av夜夜 | 久久99精品久久久久蜜桃tv | 青青久视频| 久久国产成人 | 国产十日韩十欧美 | 国产成人av电影 | 欧美一级久久久猛烈a大片 日韩av免费在线观看 | 视频1区2区 | 日韩午夜在线播放 | 日韩中文字幕在线观看视频 | 精品欧美色视频网站在线观看 | 久久一区二区三区电影 | 自拍 亚洲 欧美 老师 丝袜 | 久久久xxx| 日韩福利在线观看 | 亚洲超碰在线观看 | 99成人在线视频 | 高清欧美性猛交xxxx黑人猛交 | 在线观看av网站永久 | 国产福利久久 | 成人性生交大片免费看r链接 | 365夜爽爽欧美性午夜免费视频 | a级毛片基地 | 国产精久久久久久久 | 欧美高清性xxxxhdvideosex | 欧美日韩亚洲二区 | 在线观看欧美日韩视频 | 亚洲欧美日韩一区二区 | 巨大黑人极品videos精品 | 亚洲精品久久久久久国产精华液 | 国产精品中文字幕在线观看 |