加入星計劃,您可以享受以下權益:

  • 創(chuàng)作內容快速變現(xiàn)
  • 行業(yè)影響力擴散
  • 作品版權保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

嵌入式 C 語言面向對象編程 --- 封裝

07/08 10:05
245
閱讀需 14 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論
我是老溫,一名熱愛學習的嵌入式工程師,關注我,一起變得更加優(yōu)秀!

大部分使用 C 語言進行開發(fā)的工程師,在接觸更高級的編程語言之前,都認為 C 語言是面向過程的。

事實也是如此,對于一些小規(guī)模的單片機應用程序,一般都是使用“面向過程”的思維進行單片機C語言編程開發(fā)。

但是,如果是需要用C語言開發(fā)一些規(guī)模比較大的軟件的時候,比如操作系統(tǒng)內核,文件系統(tǒng)底層,數(shù)據(jù)庫底層,等等,這個時候,就需要用面向對象的思想去考慮和設計整個軟件框架了。

嵌入式Linux的內核,雖然是使用 C 語言編寫的,但里面的設計大部分都使用了面向對象的編程思想。

很多單片機工程師或者嵌入式Linux驅動初學者,有時候會覺得驅動入門特別困難,很大一部分原因是,他們會用“過程式思維”去嘗試學習驅動框架和內核框架,而非從“整體對象”的思維方向出發(fā),這樣容易導致水土不服。

任何編程語言只是一種工具,而編程思想是指導我們用好這個工具的關鍵。

C 語言只是工具,而面向對象是一種編程思想,用來指導我們如何用從另一種思維模式去使用 C 語言。

值得注意的是,并不是所有使用C語言開發(fā)的項目,都必須以“面向對象”作為指導,有時候“面向過程”也不一定是壞事,需要根據(jù)實際項目情況,具體問題具體分析。

接下來,我們將嘗試使用 C 語言進行面向對象程序開發(fā),務求使用 C 語言實現(xiàn)面向對象的一些基本特性,先來說說封裝。

封裝就是把一個抽象事物的屬性和屬性的操作函數(shù)打包在一起,外界的模塊只能通過這個抽象事物對外提供的函數(shù)接口,對其屬性進行訪問。

在C++或其他高級語言中,封裝通常被稱作“類”。而 C 語言一般使用結構體對事物進行封裝。

說人話就是,封裝,即“封閉包裝起來”,俗稱“打包”。把事物里面一些相近類似的特征進行打包(打包的過程一般稱作“抽象”),這樣就是封裝了。

舉個例子:大多數(shù)動物,都有眼睛耳朵嘴巴鼻子,把“五官”提取出來進行封裝,這個封裝就成為了大多數(shù)動物共有的東西。

頭文件 coordinate.h

#ifndef __COORDINATE_H_
#define __COORDINATE_H_

//聲明一個位置類,屬性為坐標x,y
typedef struct coordinate{
    short int x;
    short int y;
}COORDINATE_T,*P_COORDINATE_T;

extern P_COORDINATE_T coordinate_create(short int x,short int y);
extern void coordinate_destroy(P_COORDINATE_T p_coordinate);
extern void coordinate_moveby(P_COORDINATE_T p_coordinate,short int dx,short int dy);
extern short int coordinate_get_x(P_COORDINATE_T p_coordinate);
extern short int coordinate_get_y(P_COORDINATE_T p_coordinate);
extern void coordinate_test_function(void);
#endif // !__COORDINATE_H_

源文件 coordinate.c

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "inc/coordinate.h"

//創(chuàng)建一個coordinate對象
P_COORDINATE_T coordinate_create(short int x,short int y)
{
    if((x < 0) || (y < 0)){
        printf("coordinate creat error! x or y can not be less than zero n");
        return NULL;
    }

    P_COORDINATE_T p_coordiante = NULL;
    p_coordiante = (P_COORDINATE_T)malloc(sizeof(COORDINATE_T));

    if(NULL != p_coordiante){
        p_coordiante->x = x;
        p_coordiante->y = y;        
    }
    else printf("coordinate malloc error! n");
         
    return p_coordiante;
}

//銷毀一個coordinate對象
void coordinate_destroy(P_COORDINATE_T p_coordiante)
{
    if(NULL != p_coordiante){
        free(p_coordiante);
        p_coordiante = NULL;
    }
}

//修改coordinate的屬性值
void coordinate_moveby(P_COORDINATE_T p_coordiante,short int dx,short int dy)
{
    if(NULL != p_coordiante){
        p_coordiante->x += dx;
        p_coordiante->y += dy;
    }
}

//獲取coordinate的屬性值x
short int coordinate_get_x(P_COORDINATE_T p_coordiante)
{  
    return (NULL != p_coordiante) ? p_coordiante->x : -1;
}

//獲取coordinate的屬性值y
short int coordinate_get_y(P_COORDINATE_T p_coordiante)
{
    return (NULL != p_coordiante) ? p_coordiante->y : -1;
}

代碼比較簡單,在頭文件 coordinate.h里面,通過結構體封裝了一個coordinate類,里面有兩個坐標屬性 x 和 y 。

coordinate_create 函數(shù)主要用于創(chuàng)建一個 P_COORDINATE_T 類型的對象,并為其分配內存空間,內存分配成功后,設置兩個坐標屬性的初始值,最后返回申請成功的對象指針。

coordinate_destroy 主要是釋放對象之前申請的內存空間,然后把對象指針重置為NULL。

其他的操作函數(shù),主要是對類對象的屬性進行操作,比如獲取 x 和 y 的屬性值,重置坐標的屬性值。

以下是測試函數(shù),在主函數(shù)中調用,即可測試類coordinate對外提供的接口。

void coordinate_test_function(void)
{
    P_COORDINATE_T p_coordiante_1 = NULL;
    P_COORDINATE_T p_coordiante_2 = NULL;

    p_coordiante_1 = (P_COORDINATE_T)coordinate_create(100,200);
    p_coordiante_2 = (P_COORDINATE_T)coordinate_create(10,20);

    if((NULL == p_coordiante_1) || (NULL == p_coordiante_2)){
        printf("p_coordiante_1 or p_coordiante_2 create error! n");
        return;
    }

    printf("p_coordiante_1 x = %d, y = %d n",coordinate_get_x(p_coordiante_1), coordinate_get_y(p_coordiante_1));
    printf("p_coordiante_2 x = %d, y = %d n",coordinate_get_x(p_coordiante_2), coordinate_get_y(p_coordiante_2));

    coordinate_moveby(p_coordiante_1,50,50);
    coordinate_moveby(p_coordiante_2,50,50);

    printf("after moveby p_coordiante_1 x = %d, y = %d n",coordinate_get_x(p_coordiante_1), coordinate_get_y(p_coordiante_1));
    printf("after moveby p_coordiante_2 x = %d, y = %d n",coordinate_get_x(p_coordiante_2), coordinate_get_y(p_coordiante_2));

    coordinate_destroy(p_coordiante_1);
    coordinate_destroy(p_coordiante_2);
}

測試代碼比較簡單,主要是創(chuàng)建了兩個 P_COORDINATE_T 類型的對象,然后打印其坐標初始值,再通過對外提供的函數(shù)修改其坐標值,然后再打印出來,最后銷毀之前創(chuàng)建的對象。測試函數(shù)運行后,結果如下所示:

p_coordiante_1 x = 100, y = 200 
p_coordiante_2 x = 10, y = 20 
after moveby p_coordiante_1 x = 150, y = 250 
after moveby p_coordiante_2 x = 60, y = 70

從上述代碼可以看出,使用結構體可以很好地對數(shù)據(jù)進行封裝,并且需要通過指定的操作函數(shù)對結構體內的數(shù)據(jù)進行訪問。

每個操作函數(shù)的第一個參數(shù)是對象本身的指針,通過這個指針去訪問具體對象里面的屬性。這是因為在 C 語言中不存在像 C++ 語言那樣的 this 指針,所以我們只能顯式地通過函數(shù)傳參的方式,讓函數(shù)內部可以訪問對象實例的其他成員。

對于對象屬性的各種操作函數(shù),還可以使用函數(shù)指針的方式,放入結構體內進行封裝。但為了便于理解,本文并沒有采用這種方法。

源碼下載地址:https://github.com/embediot/my_program_test

感謝閱讀!

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風險等級 參考價格 更多信息
CB3LV-3I-18M4320 1 CTS Corporation OSC 18.4320 MHZ 3.3V SMD

ECAD模型

下載ECAD模型
$1.43 查看
HFBR-1414Z 1 Broadcom Limited Transmitter, 792nm Min, 865nm Max, 160Mbps, ST Connector, DIP, Panel Mount, Through Hole Mount, ROHS COMPLIANT PACKAGE
$27.48 查看
SN65HVD230DR 1 Texas Instruments 3.3 V CAN Transceiver with Standby Mode 8-SOIC -40 to 85

ECAD模型

下載ECAD模型
$2.94 查看

相關推薦

電子產(chǎn)業(yè)圖譜