在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

嵌入式C語言中結構體封裝函數詳解

CHANBAEK ? 來源:南山府嵌入式 ? 作者:編外人員 ? 2023-04-14 11:50 ? 次閱讀

說明:

嵌入式系統中,結構體封裝函數可以用于對于嵌入式硬件資源進行抽象和封裝,從而提高軟件的可維護性和可移植性。 結構體封裝函數通常包含數據和行為,并提供了對數據的訪問和操作方法。

比如可以將硬件驅動函數封裝在結構體中,方便對外提供統一的API接口,同時也便于代碼的移植和擴展。 另外,結構體封裝函數還可以用于實現狀態機、任務調度等復雜的系統功能。

C語言中,結構體不僅可以封裝數據,還可以封裝函數指針。 這種方式可以用于實現回調函數、狀態機等,提高代碼的復用性和可維護性。 特別是在嵌入式當中,應用是非常多的。

結構體封裝函數的作用:

  1. 將函數指針和參數打包成一個結構體,實現了代碼的模塊化和可復用性。
  2. 在結構體中可以定義多個函數指針,實現了對函數的分類管理和調用。
  3. 結構體可以作為函數的參數或返回值,傳遞和返回函數指針和參數。

結構體封裝函數的應用:

  • 回調函數:將函數指針和參數打包成一個結構體,傳遞給API函數,在API函數內部執行該函數。
  • 狀態機:將每個狀態對應的處理函數封裝成一個結構體,根據當前狀態調用相應的處理函數。
  • 事件驅動:將事件處理函數封裝成一個結構體,通過事件觸發調用相應的處理函數。
  • 線程池:將任務處理函數封裝成一個結構體,加入任務隊列后由線程池調用執行

結構體封裝函數的好處:

  • 更好的隱藏實現細節:結構體封裝函數使得函數的實現細節被封裝在結構體內部,只有結構體暴露給外部的函數指針,實現了良好的封裝和信息隱藏。
  • 更加靈活的函數調用:函數指針可以被動態修改,從而實現動態的函數調用。 例如,在狀態機中,根據不同的狀態,可以將相應的處理函數指針賦值給一個函數指針變量,從而實現狀態的轉換和函數的調用。
  • 更加方便的擴展性:結構體封裝函數可以輕松地添加新的函數指針,從而擴展功能。 在需要添加新功能時,只需要定義一個新的函數指針,并添加到結構體中,就可以實現功能的擴展,而不需要修改原有的代碼。
  • 更加通用的代碼:結構體封裝函數可以使用于各種不同的編程范式,例如面向對象編程(OOP)和函數式編程(FP),從而實現通用的代碼。 例如,在OOP中,結構體可以被看作是一個對象,函數指針可以被看作是對象的方法,從而實現OOP編程的思想。
  • 更加易于維護:結構體封裝函數使得代碼更加清晰、易于維護和修改。 由于函數指針的定義和使用都在結構體內部,因此修改或調整代碼時,只需要修改結構體中的函數指針定義或調用方式,而不需要修改其他部分的代碼,從而使得代碼更加健壯、易于維護和修改
  • 模塊化:通過結構體封裝函數,可以將多個函數和數據結構組合成一個模塊,以便于模塊化設計和維護。 這種方法可以將代碼的復雜性分解到不同的模塊中,降低了代碼的耦合性,提高了代碼的可讀性和可維護性。
  • 代碼復用:結構體封裝的函數可以通過傳遞結構體的方式重用同一個函數。 這種方式可以大大減少代碼量,提高代碼的復用性和可維護性。
  • 可擴展性:當需要增加新的功能時,只需增加新的函數和數據結構,而不需要修改現有代碼。 這種方式可以大大減少代碼的修改和調試時間,提高代碼的可擴展性和可維護性。
  • 保護數據:通過結構體封裝函數,可以將數據和函數封裝在一個結構體中,防止外部代碼對數據的非法訪問和修改。
  • 提高安全性:將函數和數據封裝在一個結構體中,可以防止其他函數對數據的非法操作,從而提高程序的安全性。

舉例1

1/* 定義封裝函數結構體由外部調用*/
 2typedef struct {
 3    int x;
 4    int y;
 5    void (*move_up)(int steps);
 6    void (*move_down)(int steps);
 7    void (*move_left)(int steps);
 8    void (*move_right)(int steps);
 9} Point;
10
11// 定義結構體中的函數
12void move_up(int steps) {
13    // 向上移動steps個單位
14    // ...
15}
16
17void move_down(int steps) {
18    // 向下移動steps個單位
19    // ...
20}
21
22void move_left(int steps) {
23    // 向左移動steps個單位
24    // ...
25}
26
27void move_right(int steps) {
28    // 向右移動steps個單位
29    // ...
30}
31
32int main() {
33    // 初始化結構體
34    Point point = {
35        .x = 0,
36        .y = 0,
37        .move_up = move_up,
38        .move_down = move_down,
39        .move_left = move_left,
40        .move_right = move_right
41    };
42
43    // 調用結構體中的函數
44    point.move_up(10);
45    point.move_right(5);
46
47    return 0;
48}

在上面的示例代碼中,我們定義了一個結構體Point,其中包含了兩個整型變量xy,以及四個函數指針move_upmove_downmove_leftmove_right。 每個函數指針指向一個移動函數,用于在平面坐標系中移動點的位置。 通過使用結構體封裝函數,我們可以將函數和數據封裝在一起,方便地進行操作和管理。

main()函數中,我們首先通過初始化的方式,將結構體中的成員變量和函數指針初始化。 然后,我們使用結構體中的函數指針,調用了move_up()move_right()函數,分別將點向上移動10個單位和向右移動5個單位。

值得注意的是,在實際應用中,我們需要根據實際情況修改函數的實現,以及結構體中的成員變量和函數指針的數量和類型。 同時避免濫用。

舉例2

1typedef struct {
 2    void (*init)(void);
 3    void (*write)(uint8_t data);
 4    uint8_t (*read)(void);
 5} spi_t;
 6
 7void spi_init(void) {
 8    /* SPI初始化代碼 */
 9}
10
11void spi_write(uint8_t data) {
12    /* SPI寫入數據 */
13}
14
15uint8_t spi_read(void) {
16    /* SPI讀取數據 */
17}
18
19int main(void) {
20    spi_t spi = {spi_init, spi_write, spi_read};
21
22    spi.init();
23    spi.write(0xAA);
24    uint8_t data = spi.read();
25
26    return 0;
27}

在舉例2這個例子中,我們定義了一個spi_t類型的結構體,它包含了三個成員函數指針,分別對應SPI總線的初始化、寫入和讀取操作。 在main函數中,我們定義了一個spi結構體變量,并且初始化它的函數指針成員。 接下來,我們通過spi結構體變量的函數指針成員,分別調用了SPI總線的初始化、寫入和讀取操作。

使用結構體封裝函數可以使代碼更加清晰明了,減少了代碼的冗余和重復,同時也方便代碼的擴展和維護。

舉例3

假設我們需要控制一個LED燈的亮度,可以使用PWM(脈沖寬度調制)技術來實現。 為了方便控制,我們可以使用一個結構體來封裝控制LED燈的函數和變量。

1typedef struct {
 2    uint8_t duty_cycle;     // 占空比
 3    void (*set_duty_cycle)(uint8_t duty_cycle);  // 設置占空比的函數指針
 4    void (*start)(void);    // 啟動PWM輸出的函數指針
 5    void (*stop)(void);     // 停止PWM輸出的函數指針
 6} pwm_control_t;
 7
 8// 設置占空比
 9void set_duty_cycle(uint8_t duty_cycle) {
10    // 設置占空比的代碼
11}
12
13// 啟動PWM輸出
14void start_pwm(void) {
15    // 啟動PWM輸出的代碼
16}
17
18// 停止PWM輸出
19void stop_pwm(void) {
20    // 停止PWM輸出的代碼
21}
22
23int main(void) {
24    pwm_control_t pwm;
25
26    pwm.duty_cycle = 50;   // 設置占空比為50%
27    pwm.set_duty_cycle = set_duty_cycle;
28    pwm.start = start_pwm;
29    pwm.stop = stop_pwm;
30
31    pwm.set_duty_cycle(pwm.duty_cycle);  // 設置占空比
32    pwm.start();  // 啟動PWM輸出
33
34    while (1) {
35        // 循環執行其他任務
36    }
37}

在上面的代碼中,我們定義了一個名為pwm_control_t的結構體,其中包含了一個占空比成員變量duty_cycle和三個函數指針set_duty_cyclestartstopset_duty_cycle函數用于設置占空比,start函數用于啟動PWM輸出,stop函數用于停止PWM輸出。

main函數中,我們創建了一個pwm_control_t類型的結構體變量pwm,并分別給結構體的成員變量和函數指針賦值。 接著,我們調用了set_duty_cyclestart函數來設置占空比和啟動PWM輸出。

結構體封裝函數的好處在于,我們可以通過創建不同的結構體變量來控制多個LED燈,而且不同的LED燈可以使用不同的PWM參數。 此外,如果需要修改PWM輸出的實現方式,只需要修改startstop函數即可,而不需要修改每個LED燈。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5087

    文章

    19150

    瀏覽量

    306358
  • 嵌入式系統
    +關注

    關注

    41

    文章

    3606

    瀏覽量

    129596
  • C語言
    +關注

    關注

    180

    文章

    7610

    瀏覽量

    137221
  • 函數
    +關注

    關注

    3

    文章

    4340

    瀏覽量

    62791
  • 結構體
    +關注

    關注

    1

    文章

    130

    瀏覽量

    10860
收藏 人收藏

    評論

    相關推薦

    C語言中數組和結構的內存表示和布局

    C語言中,數組和結構都可以代表一塊內存,但為什么結構可以直接賦值,而數組不可以?這個問題涉及
    發表于 08-28 10:54 ?1690次閱讀

    C語言入門書籍《嵌入式Linux C語言程序設計基礎教程》全本下載!!

    的數據、數據的輸入和輸出、運算符和表達式、程序結構和控制語句。第6章到主要講解了嵌入式Linux C語言中的數組,包括一維數組、多維數組、字符數組和字符串等。第7章主要講解了
    發表于 03-02 17:09

    嵌入式C語言C語言的區別

    嵌入式C語言C語言的區別:最常用的系統編程語言C
    發表于 10-27 06:52

    嵌入式C語言結構設計_實驗二

    主要介紹嵌入式C語言結構設計,從基礎講起,非常合適入門
    發表于 02-22 15:45 ?2次下載

    嵌入式C實現延時程序的不同變量的區別 幾種Linux嵌入式開發環境的簡單介紹

    嵌入式C實現延時程序的不同變量的區別 幾種Linux嵌入式開發環境的簡單介紹 ARM嵌入式開發基礎 對話微軟MVP:走進嵌入式軟件開發 在
    發表于 04-14 07:24 ?1666次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b>實現延時程序的不同變量的區別 幾種Linux<b class='flag-5'>嵌入式</b>開發環境的簡單介紹

    嵌入式C語言中如何判斷數據是否損壞

    C語言中結構是非常有用的復合數據類型,正是有了結構C
    發表于 08-19 11:46 ?800次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言中</b>如何判斷數據是否損壞

    嵌入式C語言中的union語法的作用是什么

    C語言中結構語法是非常重要,也是非常有用的,相信看了最近幾節的讀者應該明白。事實上,在實際的C語言
    發表于 08-29 17:10 ?1859次閱讀

    標準c語言嵌入式,嵌入式C語言C語言的區別

    嵌入式C語言C語言的區別:最常用的系統編程語言C
    發表于 10-20 14:06 ?6次下載
    標準<b class='flag-5'>c</b><b class='flag-5'>語言</b>與<b class='flag-5'>嵌入式</b>,<b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>與<b class='flag-5'>C</b><b class='flag-5'>語言</b>的區別

    C語言嵌入式培訓 嵌入式C語言程序設計基礎

      學習嵌入式的基礎語言C語言,因此先掌握C語言對于后續
    發表于 11-03 21:06 ?32次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>嵌入式</b>培訓  <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>程序設計基礎

    嵌入式C語言知識總結

    了一些這方面的經驗和思考,就希望總結下來,系統的闡述嵌入式C語言的重要知識點,就是這篇文章的由來。本文以自己在嵌入式上的實踐為基礎,在結合相關資料, 闡述
    發表于 12-20 19:44 ?12次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>知識總結

    簡單介紹嵌入式C語言中常用的位操作

    嵌入式C語言中,使用位操作程序有很好的可讀性。以下就簡單介紹以下常用的位操作。
    的頭像 發表于 02-23 10:36 ?1037次閱讀

    嵌入式C語言中堆和棧的區別

    嵌入式C語言中,堆和棧都是用來存儲變量的內存區域,但它們在存儲和使用變量方面有很大的區別。
    的頭像 發表于 04-14 11:45 ?1429次閱讀

    嵌入式C語言結構封裝函數說明

    嵌入式系統中,結構封裝函數可以用于對于嵌入式硬件資源進行抽象和
    發表于 05-20 15:00 ?1109次閱讀

    嵌入式C語言結構特點

    過程中,不論是基于寄存器開發還是基于庫開發,深入理解和掌握嵌入式C語言函數、指針、結構是學習
    的頭像 發表于 11-24 16:16 ?719次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>C</b><b class='flag-5'>語言</b>的<b class='flag-5'>結構</b>特點

    嵌入式系統中C語言結構的基礎實現與應用

    C語言中的數組只能允許程序員定義存儲相同類型數據。但是結構C語言編程中允許您存儲不同數據類型的數據。
    發表于 03-12 14:29 ?524次閱讀
    <b class='flag-5'>嵌入式</b>系統中<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>結構</b><b class='flag-5'>體</b>的基礎實現與應用
    主站蜘蛛池模板: sihu永久在线播放地址| 久久久久久久久国产| 久久久成人影院| 欧美午夜色视频国产精品| 欧美色视频日本片免费高清| 欧美人交性视频在线香蕉| 久久久精品免费国产四虎| 成年网站在线| 午夜禁片| 国产性夜夜春夜夜爽| 在线视频观看免费| 亚洲一区二区中文字5566| 黄网站色视频大全免费观看| 亚洲婷婷综合网| 月夜免费观看完整视频| 天堂福利视频| 欧美三级免费看| 国产精品欧美一区二区三区 | 在线观看黄色x视频| 性久久久久久久久| 欧美伊久线香蕉线新在线| 四虎a456tncom| 欧美大片一区二区| 狠狠狠色丁香婷婷综合久久五月| 国产精品久久久久影院色老大| 夜夜操网站| 九九99久久精品影视| 欧美性猛交xxxx黑人喷水| 九九re热| 48pao强力打造免费基地| 爱爱视频天天干| 一区二区在线免费视频| 一级毛片 在线播放| 日韩卡1卡2卡三卡四卡二卡免| 黄色三级国产| 亚洲午夜免费| 干夜夜| 日产国产精品亚洲系列 | 天天躁日日躁狠狠躁一级毛片| 国产综合视频在线| 美欧毛片|