找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 3560|回復(fù): 6
打印 上一主題 下一主題
收起左側(cè)

C語(yǔ)言特性,節(jié)省空間,保留可讀性

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:392682 發(fā)表于 2022-4-20 17:31 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
我們開(kāi)發(fā)的電表,基于單片機(jī)的,電表的功能越來(lái)越多,要求我們?cè)儆布蛔兊那闆r下增加這些功能,所以就經(jīng)常會(huì)考慮程序大小問(wèn)題,有時(shí)真的會(huì)按字節(jié)去省空間,因?yàn)椋褪悄菐讉(gè)字節(jié)編譯就爆掉了。但是還要求盡量程序可維護(hù)性好(簡(jiǎn)單、直接、易讀)。這時(shí)就要去程序中尋找能省空間的地方,能用指針就考慮要不要換指針,犧牲一些可讀性,使用for&if代替switch的一些表達(dá)式。重復(fù)的語(yǔ)句使用函數(shù)代替,使用位域,尋找簡(jiǎn)便的程序處理方法等,,打開(kāi)編譯產(chǎn)生的map文件分析哪里占的存儲(chǔ)大,進(jìn)行精簡(jiǎn),真是挺有意思的。就好像捉迷藏。

這些省空間的操作有些基于C語(yǔ)言的特性,比如指針,比如位操作,比如位域操作在保留可讀性的情況下代替一堆flag。
struct file_data{
unsigned int day: 5;
unsigned int month: 4;
unsigned int year: 7;
}
struct file_data fd;
fd.day = 20;
fd.month = 4;
fd.year = 22;
這樣定義,變量day占了5個(gè)位,month占4個(gè)位,year占7位。同時(shí)也保留了可讀性。
雖然這種寫(xiě)法省空間,但是有限,而且不太好用,迫不得已還是別這么搞。但是位操作的話這么些會(huì)好看一點(diǎn)如:
struct bits{
unsigned int flag_0: 1;
unsigned int flag_1: 1;
unsigned int flag_2: 1;
unsigned int flag_3: 1;
unsigned int flag_4: 1;
unsigned int flag_5: 1;

unsigned int flag_6: 1;
unsigned int flag_7: 1;

};

struct bits flag_grop;
if(flag_grop.flag_0 == 1)
{
    flag_grop.flag_1 = 0;
}
這樣寫(xiě)一些還可以。

還有聯(lián)合體,在不增加開(kāi)銷的情況下簡(jiǎn)潔的提供了多種解析數(shù)據(jù)的方式,真是一個(gè)不錯(cuò)的工具
union bits{
u8 data;
unsigned int flag_0: 1;
unsigned int flag_1: 1;
unsigned int flag_2: 1;
unsigned int flag_3: 1;
unsigned int flag_4: 1;
unsigned int flag_5: 1;

unsigned int flag_6: 1;
unsigned int flag_7: 1;


};
union bits flag_grop;

flag_grop = 0xAA;

if(flag_grop.int flag_0 == 1)
{}
if(flag_grop.int flag_1 == 1)
{}
...
如上該聯(lián)合體只占了一個(gè)字節(jié)的空間。提供了兩種方便讀寫(xiě)操作的解析數(shù)據(jù)的方式 字節(jié)操作與位操作。
聯(lián)合體用來(lái)處理通訊挺好的。
假設(shè)串口發(fā)送數(shù)據(jù)是按字節(jié)發(fā)送,但是我們要發(fā)送的數(shù)據(jù)可能時(shí)16位的或者32位的,還會(huì)面臨先發(fā)高子節(jié)還是低字節(jié)問(wèn)題。1、我們可以使用指針
將一個(gè)整型數(shù)據(jù)分為4次發(fā)送。2、我們也可以利用聯(lián)合體的特性將整型數(shù)據(jù)分4次發(fā)出。還能增加一點(diǎn)可讀性。


今天看到一句話:no time to be brief 感覺(jué)有時(shí)用著還挺好

評(píng)分

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

查看全部評(píng)分

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

使用道具 舉報(bào)

沙發(fā)
ID:301191 發(fā)表于 2022-4-23 18:28 | 只看該作者
頂一下
回復(fù)

使用道具 舉報(bào)

板凳
ID:883242 發(fā)表于 2022-4-23 18:35 | 只看該作者
在不支持位操作的單片機(jī)上面,樓主的寫(xiě)法會(huì)嚴(yán)重增加代碼長(zhǎng)度,節(jié)約了ram卻大大浪費(fèi)了flash,得不償失。

在支持位操作的單片機(jī)上,比如51,用專門的關(guān)鍵字bdata、bit來(lái)操作也比樓主的寫(xiě)法節(jié)約了很大的空間。

所以樓主的文章,沒(méi)有什么用。
回復(fù)

使用道具 舉報(bào)

地板
ID:392682 發(fā)表于 2022-4-29 16:52 | 只看該作者
Hephaestus 發(fā)表于 2022-4-23 18:35
在不支持位操作的單片機(jī)上面,樓主的寫(xiě)法會(huì)嚴(yán)重增加代碼長(zhǎng)度,節(jié)約了ram卻大大浪費(fèi)了flash,得不償失。

...

沒(méi)太了解,在不支持位操作的單片機(jī)上,位域操作會(huì)怎加flash的開(kāi)銷嗎?
回復(fù)

使用道具 舉報(bào)

5#
ID:712493 發(fā)表于 2022-4-30 15:02 | 只看該作者
qinshuai 發(fā)表于 2022-4-29 16:52
沒(méi)太了解,在不支持位操作的單片機(jī)上,位域操作會(huì)怎加flash的開(kāi)銷嗎?

就是本來(lái)沒(méi)有位操作指令 你程序卻寫(xiě)位操作語(yǔ)法 編譯器為滿足你的程序意圖  只能按它自己的想法給你弄一堆匯編實(shí)現(xiàn)了  這樣下來(lái)FLASH開(kāi)銷就大  就如沒(méi)有硬件乘除法的單片機(jī)  你卻出現(xiàn)很多乘除法  那就不是FLASH開(kāi)銷大的問(wèn)題  也會(huì)造成程序效率不高的問(wèn)題
回復(fù)

使用道具 舉報(bào)

6#
ID:824490 發(fā)表于 2022-4-30 15:11 | 只看該作者
本帖最后由 名字不是重點(diǎn) 于 2022-4-30 19:13 編輯

我錯(cuò)了

回復(fù)

使用道具 舉報(bào)

7#
ID:392682 發(fā)表于 2022-5-4 11:50 | 只看該作者
fj51hei 發(fā)表于 2022-4-30 15:02
就是本來(lái)沒(méi)有位操作指令 你程序卻寫(xiě)位操作語(yǔ)法 編譯器為滿足你的程序意圖  只能按它自己的想法給你弄一堆 ...

這樣啊,這點(diǎn)真沒(méi)想到,當(dāng)時(shí)想當(dāng)然的認(rèn)為,位域操作會(huì)被轉(zhuǎn)化為簡(jiǎn)單常規(guī)的與或非操作了。有點(diǎn)慚愧哈,想當(dāng)然了?勺x性好點(diǎn),但是對(duì)于節(jié)約空間效果可能沒(méi)啥效果
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表