當(dāng)前位置:首頁 > 公眾號精選 > 嵌入式案例Show
[導(dǎo)讀]解釋區(qū)分一下C語言和OOP 我們經(jīng)常說C語言是面向過程的,而C++是面向?qū)ο蟮?,然而何為面向?qū)ο?,什么又是面向過程呢?不管怎么樣,我們最原始的目標(biāo)只有一個(gè)就是實(shí)現(xiàn)我們所需要的功能,從這一點(diǎn)說它們是殊途同歸的。過程與對象只是側(cè)重點(diǎn)不同而已。 舉個(gè)例子



解釋區(qū)分一下C語言和OOP

我們經(jīng)常說C語言是面向過程的,而C++是面向?qū)ο蟮模欢螢槊嫦驅(qū)ο?,什么又是面向過程呢?不管怎么樣,我們最原始的目標(biāo)只有一個(gè)就是實(shí)現(xiàn)我們所需要的功能,從這一點(diǎn)說它們是殊途同歸的。過程與對象只是側(cè)重點(diǎn)不同而已。

舉個(gè)例子吧,我現(xiàn)在有個(gè)計(jì)劃,要去北京,OOP語言是直接給你一個(gè)車,然后你自己設(shè)定路線去北京就好,而C語言是需要你自己制造零件,自己組裝好車,然后再自己設(shè)定路線,最后到達(dá)北京。C語言比較費(fèi)勁,但是程序的效率很高。

過程&對象?

一個(gè)對象就是由或多或少的針對這個(gè)對象的過程構(gòu)成的,當(dāng)然其中是少不了必要的屬性。

一個(gè)過程是針對一個(gè)或者是多個(gè)對象所進(jìn)行的操作。兩者是可以互相轉(zhuǎn)換的,關(guān)鍵是哪一種方式更能適合你現(xiàn)在的需求,更能讓你的軟件開發(fā)錦上添花。

我個(gè)人認(rèn)為一般情況下,一個(gè)更容易擴(kuò)展、維護(hù)的軟件通常采用的是OOP的思想,添加一個(gè)原本不存在的相對無關(guān)單獨(dú)的個(gè)體,總比在一個(gè)已經(jīng)存在的過程內(nèi)硬塞進(jìn)去一個(gè)對象要簡單;而且面向過程更容易導(dǎo)致混亂的維護(hù)。

舉個(gè)例子,同樣是一條河與一個(gè)湖泊,哪一個(gè)更容管理維護(hù)呢?我想答案是顯而易見的。當(dāng)然不管怎么樣,軟件本身設(shè)計(jì)架構(gòu)的好壞也是非常重要的。

C語言的特性,實(shí)現(xiàn)OOP

C是一門面向過程的語言,但它依舊可以實(shí)現(xiàn)大多數(shù)面向?qū)ο笏芡瓿傻墓ぷ?。比如面向?qū)ο蟮娜筇匦裕悍庋b、繼承、多態(tài)。我們以下圖來寫代碼舉例子。

封裝

由于面象向?qū)ο笫菍?shù)據(jù)與方法封裝到一個(gè)類里。使用者無需關(guān)心類是怎么實(shí)現(xiàn)的。在 C_OOP 中貫徹了這一思想,C中有一種復(fù)雜的數(shù)據(jù)結(jié)構(gòu)叫做struct。struct是C里面的結(jié)構(gòu)體。

如上圖假如我們要對鳥bird進(jìn)行封裝,bird可能包括姓名、顏色、棲息地、重量、屬性等信息。我們就可以對它封裝如下:

struct Bird{
    char name[20];//姓名
    char color;    //顏色   
    char addr[30];    //棲息地
    int weight;        //體重
    int other;      //屬性
};

當(dāng)我們要像OOP那樣新建一個(gè)對象時(shí),我們就可以:

struct Bird p;

我們就可以直接對p進(jìn)行賦值:

p.name = "bird";
p.color = 'b';  //'b' = black; 'g' = green
p.addr = 'w';  
p.weight = 175;
p.other = 1;

繼承

在常見用C語言實(shí)現(xiàn)繼承的機(jī)制中,多半是用結(jié)構(gòu)體組合實(shí)現(xiàn)的,同樣利用struct,我們來創(chuàng)建一個(gè)Bird結(jié)構(gòu),同時(shí)繼承結(jié)構(gòu)體Bird,如下:

struct fBird{
    struct Bird p;
    char fly[20]; //飛翔
    int scream;        //鳴叫
};

對Bird進(jìn)行創(chuàng)建對象,并賦值:

struct fBird s;
s.p.name = "bird";
s.p.color = 'b';
s.p.other = 25;
s.p.weight = 65;
s.fly = "0618";
s.scream = 90;

多態(tài)

C_OOP中的一個(gè)核心就是多態(tài),C中對于多態(tài)的實(shí)現(xiàn)可以借助函數(shù)指針來實(shí)現(xiàn)。為了簡單起見,我們假設(shè)Bird這個(gè)結(jié)構(gòu)體中,只有一個(gè)函數(shù)指針。

struct Bird{
    void (*print)(void *p);
};

struct fBird{
    struct Bird p;
};

而Bird和fBird這兩個(gè)結(jié)構(gòu)體的print函數(shù)實(shí)現(xiàn)如下:

void printBird(void *Bird){
    if(NULL == Bird)
        return ;
    struct Bird *p = (struct Bird *)Bird;
    printf("run in the Bird!!\n");
}
void printfBird(void *Bird){
    if(NULL == Bird)
        return ;
    struct Bird *p = (struct Bird *)Bird;
    printf("run in the fBird!!\n");
}

我們寫一個(gè)函數(shù)來調(diào)用他們:

void print(void *Bird){
    if(NULL == Bird)
        return ;
    struct Bird *p = (struct Bird *)Bird;
    p->print(Bird);
}
int main(){
    struct Bird bird;
    struct fBird fbird;
    Bird.print = printBird;
    fBird.p.print = printfBird;

    print(&bird);    //實(shí)參為Bird的對象
    print(&fbird);  //實(shí)參為fBird的對象

    return 0;
}

他們的輸出為:

run in the Bird!!
run in the fBird!!

其實(shí)這個(gè)也不難理解,無論是fBird還是Bird,他們在內(nèi)存中只有一個(gè)變量,就是那個(gè)函數(shù)指針,而void表示任何類型的指針,當(dāng)我們將它強(qiáng)制轉(zhuǎn)換成struct Bird類型時(shí),p->print指向的自然就是傳入實(shí)參的print地址。

OOP真的那么重要?

從大學(xué)到工作至今,在嵌入式領(lǐng)域中一直是使用C語言,而我在學(xué)習(xí)C++的過程中,看的代碼越多,代碼量越大,越來越覺得C++對于大型軟件架構(gòu)的良好可控性,和對以后程序員維護(hù)代碼時(shí)良好的可讀性;

個(gè)人認(rèn)為:C語言中最大的成功在于它的指針,但是也是最容易出錯(cuò)的,想要理解C,必須要掌握指針。雖然說,語言只是一門工具,但是這是基礎(chǔ).或者你可以說C太底層,現(xiàn)在都是OOP的時(shí)代了,誰還會(huì)用面向過程的,你們不要忘了操作系統(tǒng)是用什么寫的?是C;C實(shí)現(xiàn)的nginx的并發(fā)量是C++實(shí)現(xiàn)的apache的幾十倍,關(guān)鍵是要理解語言背后的思想。

當(dāng)然這不是為了OOP而OOP,實(shí)在是OOP的一些特征,例如封裝,多態(tài)其實(shí)是軟件工程思想,這些思想不分語言,遵循了這些思想可以使得程序更有彈性,更易修改和維護(hù),避免僵化,脆弱的性質(zhì)。

嵌入式C語言使用OOP的一些思考

然而就目前來說,在嵌入式領(lǐng)域廣泛的使用C++顯然是不現(xiàn)實(shí)的事情。在一個(gè)到處是OOP的年代,為何面向過程的C語言依然可以如此活躍?

我們可以用它來開發(fā)一系列的小工具,Unix/Linux就是由這些小工具組成的操作系統(tǒng);同時(shí)用C語言可以開發(fā)高性能的應(yīng)用程序。

C語言良好的可移植性,小巧靈活,而且還有一個(gè)直接與硬件打交道的指針的存在,對內(nèi)存等良好的操作性以及執(zhí)行之速度快,是嵌入式開發(fā)唯有的高級語言,均是一般嵌入式產(chǎn)品的不二首選。

LW_OOPC->C語言的面對對象

LW_OOPC是臺(tái)灣的MISOO團(tuán)隊(duì)根據(jù)多年研發(fā)經(jīng)驗(yàn),總結(jié)出來的一種輕便的面向?qū)ο蟮?a href="/tags/C語言" target="_blank">C語言。雖然不足以提供足夠的能力使我們實(shí)現(xiàn)面向?qū)ο笏械母拍?,但是我們依然可以?yīng)用它們完成我們簡單的面向?qū)ο笏枷氲臉?gòu)建。

lw_oopc僅用了2個(gè)文件,.h及.c文件就實(shí)現(xiàn)了面向?qū)ο蟮娜笠蛩?,?shí)現(xiàn)過程極為簡潔又富含技巧。lw_oopc說白了,就是定義了一堆宏,使用起來也就是調(diào)用這些宏。

//| INTERFACE                 | 接口
//----------------------------------------------------------------------
//| CLASS                     | 類
//----------------------------------------------------------------------
//| CTOR                      | 構(gòu)造器開始
//---------------------------------------------------------------------- 
//| END_CTOR                  | 構(gòu)造器截止
//----------------------------------------------------------------------
//| FUNCTION_SETTING          | 關(guān)聯(lián)成員函數(shù)指針
//----------------------------------------------------------------------
//| IMPLEMENTS                | 繼承
//----------------------------------------------------------------------
//| DTOR                      | 為了支持析構(gòu)函數(shù)的概念 
//| END_DTOR                  |                                                    
//----------------------------------------------------------------------
//| ABS_CLASS                 | 為了支持抽象類的概念   
//----------------------------------------------------------------------
//| ABS_CTOR                  | 為了支持可繼承的抽象類的構(gòu)造函數(shù) 
//| END_ABS_CTOR              |                         
//----------------------------------------------------------------------
//| EXTENDS                   | 為了讓熟悉Java的人容易理解(與IMPLEMENTS宏等同)  
//----------------------------------------------------------------------
//| SUPER_CTOR                | 為了支持子類調(diào)用父類的構(gòu)造函數(shù)

//----------------------------------------------------------------------
//| SUPER_PTR                 | 為了支持向上轉(zhuǎn)型     
//| SUPER_PTR_2               |     
//| SUPER_PTR_3               | 
//----------------------------------------------------------------------
//| SUB_PTR                   | 為了支持向下轉(zhuǎn)型   
//| SUB_PTR_2                 |                       
//| SUB_PTR_3                 |                                           
//----------------------------------------------------------------------
//| INHERIT_FROM              | 為了支持訪問直接父類的數(shù)據(jù)成員
//----------------------------------------------------------------------

下面是對LW_OOPC的簡單的分析。

LW_OOPC概述

簡單來說它主要是一個(gè)頭文件,我們通過對這個(gè)頭文件的使用來實(shí)現(xiàn)面向?qū)ο蟆?/p>

//lw_oopc.h : MISOO團(tuán)隊(duì)設(shè)計(jì)的C宏
#include

#ifndef LW_OOPC
#define LW_OOPC

#define CLASS(type)       /
typedef struct type type; /
struct type

#define CTOR(type)        /
void* type##New()         /
{                         /
  struct type *t;        /
  t = (struct type*)malloc(sizeof(struct type));

#define CTOR2(type, type2)     /
void* type2##New()             /
{                              /
  struct type *t;             /
  t = (struct type*)malloc(sizeof(struct type));  

#define END_CTOR return (void*)t; }
#define FUNCTION_SETTING(f1, f2) t->f1 = f2;
#define IMPLEMENTS(type) struct type type
#define INTERFACE(type) struct type

#endif
/*          lw_oopc.h               */

下面一段代碼是簡單的OOPC的應(yīng)用:

// Circle.c   
#include
#include "lw_oop.h"

#define PI 3.1415926

CLASS(Circle)
{
  double (*cal_area)(double);
}

double circle_cal_area(double radius)
{
  return PI*r*r;
}

CTOR(Circle)
 FUNCTION_SETTING(cal_area, circle_cal_area)
END_CTOR

int main()
{
     double area = 0.0;
     Circle *pc;
    
     pc = (Circle*)CircleNew();
     area = pc->cal_area(10);

     printf("area = %f/n", area);

     return 0;
}

接口的實(shí)現(xiàn)

在OOP程序中,通常是通過類定義和接口定義來實(shí)現(xiàn)的。

//IA.h  
#include "lw_oopc.h"

INTERFACE(IA)
{
   void   (*init)(void*, double);
   double (*cal_area)(void*);
   double (*cal_permimeter)(void*);
}
//circle.c 
#include "IA.h"

#define PI 3.1415926

CLASS(Circle)
{
  IMPLEMENTS(IA);
  double radius;
}

static void circle_init(void* circle, double radius)
{
  Circle *_this = (Circle*)circle;

  _this->radius = radius;
}

static double circle_cal_area(void* circle)
{
  Circle *_this = (Circle*)circle;

  return PI*_this->radius*_this->radius;
}

static double circle_cal_permimeter(void* circle)
{
  Circle *_this = (Circle*)circle;

  return 2*PI*_this->radius;
}

CTOR(Circle)
  FUNCTION_SETTING(IA.init, circle_init)
  FUNCTION_SETTING(IA.cal_area, circle_cal_area)
  FUNCTION_SETTING(IA.cal_permimeter, circle_cal_permimeter)
END_CTOR
//main.c
#include
#include “IA.h”

void print_area(IA* pi)
{
    printf("area = %f/n", pi->cal_area(pi));
}

int main()
{
  IA *pc = NULL;

  pc = (IA*)CircleNew();
  pc->init(pc, 10.0);

  print_area();
  return 0;
}

總結(jié)

語言只是一種工具,任何語言之間都是相通的,一通則百通,關(guān)鍵是要理解語言背后的思想,理解其思想,任何語言,拿來用就行了。語言沒有好壞之分,任何語言既然存在自然有它存在的價(jià)值。

掃碼關(guān)注我們

看更多嵌入式案例



點(diǎn)贊、再看、轉(zhuǎn)發(fā)三連是最大支持

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉