C++ 仍然是嵌入式開發(fā)的少數(shù)??語言,但當(dāng)項(xiàng)目變得太大而無法有效使用 C 時(shí),開發(fā)人員通常會(huì)采用 C++。這些開發(fā)人員通常從 C 過渡到 C++,語言之間的細(xì)微差異代表了他們學(xué)習(xí)曲線的重要部分。C++ 有結(jié)構(gòu),就像 C 一樣,因?yàn)樗鼈兪遣灰粯拥摹?/font>C++ 有類,它們與結(jié)構(gòu)非常相似。本文解開這些語言元素的細(xì)節(jié)。
C中的結(jié)構(gòu)
C 中的結(jié)構(gòu)是自定義的復(fù)合數(shù)據(jù)項(xiàng)(對象),可以由現(xiàn)有的內(nèi)置數(shù)據(jù)類型(int、char等)、位字段(指定位大小的整數(shù))和其他結(jié)構(gòu)構(gòu)建。這個(gè)想法是聚合一些屬于一起的數(shù)據(jù)項(xiàng)。例如,保存 3 維坐標(biāo)的結(jié)構(gòu)可能如下所示:
結(jié)構(gòu)坐標(biāo) { ?? 浮動(dòng) x; ?? 浮動(dòng)y; ?? 浮動(dòng)z; };
這段代碼告訴編譯器結(jié)構(gòu)坐標(biāo)是什么樣的。然后,您可以繼續(xù)聲明這種類型的變量:
結(jié)構(gòu)坐標(biāo)位置;
變量位置是結(jié)構(gòu)坐標(biāo)類型,它的內(nèi)部字段可以使用“點(diǎn)”運(yùn)算符來尋址:
位置.x = 1.0; 位置.y = 2.0; 位置.z = 9.99;
當(dāng)然,使用三個(gè)單獨(dú)的浮點(diǎn)變量(名稱如location_x等)可以實(shí)現(xiàn)類似的效果。但是,將位置作為可以傳遞給函數(shù)等的單個(gè)變量來處理要容易得多。
包含位字段的能力為結(jié)構(gòu)提供了 C 中其他地方不具備的能力。下面是一個(gè)例子:
結(jié)構(gòu)位寄存器 { ?? 未注冊:3; ?? 未簽名:3; ?? 無符號(hào)極性:2; };
struct bitreg類型變量中的每個(gè)字段都有特定的位大小。編譯器確保數(shù)據(jù)以合理的方式存儲(chǔ),因此我們希望這樣的變量適合一個(gè)字節(jié)。此外,所有用于訪問字節(jié)內(nèi)字段的“bit bashing”代碼都是自動(dòng)生成的。因此,程序員可以簡單地訪問它們:
結(jié)構(gòu)位寄存器控制; 控制.up = 1; control.down = 2; control.polarity = 3;
在大多數(shù)情況下,在 C 中使用結(jié)構(gòu)非常簡單,并且使代碼更易于理解,而不會(huì)影響執(zhí)行效率。但是,嵌入式開發(fā)人員應(yīng)該注意兩點(diǎn):
- 現(xiàn)代高端(通常為 32 位)處理器具有易于使用結(jié)構(gòu)的指令集。事實(shí)上,它們就是為此而設(shè)計(jì)的。然而,大多數(shù)低端 CPU 不提供這樣的效率,因此結(jié)構(gòu)的使用需要小心。
-
位域是一個(gè)很好的特性,可以產(chǎn)生高效且可讀的代碼。嵌入式開發(fā)人員可能會(huì)立即發(fā)現(xiàn)一個(gè)機(jī)會(huì):使用位域訪問設(shè)備控制寄存器。許多外圍設(shè)備具有包含各種位字段的 1 字或 1 字節(jié)寬的寄存器。這看起來像一個(gè)偉大的匹配,有時(shí)它可以工作。但是有兩個(gè)問題:
- 位域的確切布局由編譯器確定。如果一切都正確映射到設(shè)備上,則代碼可能會(huì)正常工作。但是,編譯器的更改,甚至只是編譯器的更新,都可能會(huì)破壞代碼。
- 編譯器生成的用于訪問位字段的代碼很可能會(huì)使用許多 AND/OR 操作和對寄存器的多次訪問,這可能會(huì)出現(xiàn)問題。此外,某些設(shè)備寄存器是只寫的,并且永遠(yuǎn)不會(huì)包含在編譯器生成的代碼中。
盡管 C 結(jié)構(gòu)看起來有點(diǎn)像一種新的數(shù)據(jù)類型,但實(shí)際上并非如此。一個(gè)數(shù)據(jù)類型通常會(huì)有一系列可以對其執(zhí)行的操作;這不是 C 結(jié)構(gòu)的情況。要對 C 結(jié)構(gòu)做任何事情,除了創(chuàng)建指向它的指針之外,您需要訪問內(nèi)部字段。這個(gè)問題在 C++ 中得到解決。
C++ 中的類
C++ 語言具有許多面向?qū)ο蟮墓δ堋?/font>其中之一是類的概念,它可以描述更像一種新數(shù)據(jù)類型的東西。可以從類中實(shí)例化一個(gè)變量(通常稱為對象) ;即它是這種新類型的對象。
C++ 類具有與 C 結(jié)構(gòu)幾乎完全相同的語法和一些非常相似的功能。但是,有一些重要的區(qū)別:
- 一個(gè)類也可以包含函數(shù)(稱為方法)。
- 成員變量和方法對外界是隱藏的,除非它們的聲明遵循公共:
- 可以有一對特殊的方法——構(gòu)造函數(shù)和析構(gòu)函數(shù)——分別在創(chuàng)建和銷毀類的實(shí)例(對象)時(shí)自動(dòng)運(yùn)行。
- 可以使用特殊方法(成員函數(shù))定義處理新數(shù)據(jù)類型的運(yùn)算符。
- 一個(gè)類可以用作定義另一個(gè)類的基礎(chǔ)(這稱為繼承)。
- 聲明一個(gè)新類型的變量(類的一個(gè)實(shí)例;一個(gè)對象)只需要類的名稱——關(guān)鍵字class不是必需的。
此示例中說明了大多數(shù)這些功能:
我的班級 { ?? 字符一個(gè); ?? 詮釋 b; 上市: ?? 無效的樂趣(); ?? 我的課(); ?? ?我的類(); }; 我的類我的obj; myobj.fun();
成員變量a和b只能被三個(gè)成員函數(shù)fun()、myclass()和~myclass() 訪問。后兩個(gè)函數(shù)是構(gòu)造函數(shù)和析構(gòu)函數(shù)。只有fun()可能被用戶代碼調(diào)用。所有三個(gè)函數(shù)的實(shí)際代碼將在別處定義,并使用::運(yùn)算符與類相關(guān)聯(lián),因此:
無效 myclass::fun() { ??...
C++ 中的結(jié)構(gòu)
除了類之外,C++ 還具有向后兼容 C 的結(jié)構(gòu)。但是,C++ 結(jié)構(gòu)還具有與類相同的附加功能。這只是 C++ 中結(jié)構(gòu)和類之間的一個(gè)區(qū)別。正如我們所見,類中成員變量和函數(shù)的默認(rèn)可訪問性是私有的;結(jié)構(gòu)中的默認(rèn)值是公共的。因此,早期類的功能也可以這樣表示:
結(jié)構(gòu)體 { ?? 無效的樂趣(); ?? 我的課(); ?? ?我的類(); 私人的: ?? 字符一個(gè); ?? 詮釋 b; };
在 C++ 中使用類和結(jié)構(gòu)
獲得此信息后,建議您不要過度利用它。當(dāng)您需要額外功能時(shí),僅將結(jié)構(gòu)用于它們在 C 和類中提供的功能有很多原因。首先,這是代碼可讀性的問題。另一個(gè)開發(fā)人員可能對細(xì)節(jié)不是很清楚,以“非標(biāo)準(zhǔn)”方式編寫的代碼會(huì)令人困惑。
編寫代碼時(shí)的一個(gè)關(guān)鍵優(yōu)先事項(xiàng)是確保它是可讀的(=可維護(hù)的)。有人——可能是你——可能需要在一年后查看這段代碼并了解它的作用。一些建議:假設(shè)將維護(hù)您的代碼的人是一個(gè)武裝的精神病患者,他的耐心有限,并且知道您的家庭住址。
審核編輯:湯梓紅
評論
查看更多