當(dāng)前位置:首頁 > 公眾號精選 > wenzi嵌入式軟件
[導(dǎo)讀]C 語言通常被認(rèn)為是一種面向過程的語言,因為其本身的特性更容易編寫面向過程的代碼。

引言

C 語言通常被認(rèn)為是一種面向過程的語言,因為其本身的特性更容易編寫面向過程的代碼,當(dāng)然也不排除使用 C 語言編寫面向過程的代碼,比如 Linux 的源代碼以及現(xiàn)在很火的國產(chǎn)物聯(lián)網(wǎng)操作系統(tǒng) RT-Thread,其內(nèi)核的實現(xiàn)方式都是使用 C 語言實現(xiàn)的面向?qū)ο蟮拇a。相比于 C 語言來說,C++ 更能夠?qū)崿F(xiàn)面向?qū)ο蟮某绦蛟O(shè)計,其具有的特性也要比 C 語言要多的多。下面假設(shè)有這樣一個需求。

現(xiàn)要描述兩個人的信息,姓名,職業(yè),年齡,并輸出。

我們首先先使用 C 語言的設(shè)計思路實現(xiàn)這個功能。

C語言描述

如果使用 C 語言來描述上面這個問題,大部分都會想到使用結(jié)構(gòu)體來完成這個要求,寫出的程序也就如下所示:

#include  struct person { char *name; int age; char *work;
}; int main(int argc, char**?aggv) { struct person persons[]?=?{ {"wenzi",24,"programer"},
????????{"jiao", 22,"teacher"},
????}; char i; for (i?= 0;?i?< 2;?i++)
????{ printf("name?is:%s,age?is:%d,work?is:%s\n",persons[i].name,persons[i].age,persons[i].work);
????}
}

上述這是比較初級的寫法,如果對 C 語言了解的更多一點的人在寫這段程序的時候,會使用函數(shù)指針的方式將代碼寫的更加巧妙,代碼如下所示:

#include  struct person { char *name; int age; char *work; void (*printInfo)(struct?person?*per);
}; void printInfo(struct?person?*per) { printf("The?people's?name?is:%s,age?is:%d,work?is:%s\n",per->name,per->age,per->work);
} int main(int argc, char**?argv) { struct person per[2]; per[0]?=?{"wenzi",18,"programer",printInfo};
????per[1]?=?{"jiaojiao",18,"teacher",printInfo};

????per[0].printInfo(&per[0]);
????per[1].printInfo(&per[1]);
}

使用了函數(shù)指針的方式來書寫這個程序,程序也變得更加簡介了,主函數(shù)里也少了for循環(huán)。

C++ 的引入

那除此之外,還有更好的書寫方式么,這個時候就要引入 C++ 的特性了,上述代碼中在執(zhí)行函數(shù)時都傳入了參數(shù),那要如何做才能將上述中的參數(shù)也省略去呢,且看如下的代碼:

#include  struct person { char *name; int age; char *work; void prinfInfo(void) { printf("The?people's?name?is:%s,age?is:%d,work?is:%s\n",name,age,work);???????
????}
}; int main(int argc, char**?argv) { struct person persons[]?=?{ {"wenzi", 18,"program"},
????????{"jiao", 18, "teacher"},
????};

????persons[0].prinfInfo();
????persons[1].prinfInfo(); return 0;
}

上述代碼中使用了 C++ 的特性,在結(jié)構(gòu)體中定義了函數(shù),然后也就可以直接調(diào)用函數(shù)了,上面 C 語言的代碼相比較,它沒了實參,而且代碼看起來也比 C 語言更加簡潔了。

實際在 C++ 中它具有自己獨有的一套機制來實現(xiàn)上述的代碼,也就是即將說明的class,有了 class 之后,我們就可以這樣書寫代碼:

#include  class person { public: char *?name; int age; char *?work; void printInfo(void) { printf("The?people's?name?is:%s,age?is:%d,work?is:%s\n",name,age,work);?
????}
} int main(int argc, char**?argv) {
????person?persons[]?=?{
????????{"wenzi", 18,"program"},
????????{"jiao", 18, "teacher"},
????};

????persons[0].prinfInfo();
????persons[1].prinfInfo(); return 0;
}

上述就是關(guān)于 C++ 的一個簡單的引入過程。

C++ 數(shù)據(jù)訪問控制

但是為了能夠改變類里數(shù)據(jù),但是又要使得這個改變不要越界,避免胡亂地改變,我們可以這樣來定義這個類:

#include  #include  class Person { private: char *name; int age; char *work; public: void PrintInfo(void) { cout << "name?is:" << name << "age?=?"<< age << "work?is:"<< work <<endl;
????}
};

這樣定義一個類之后,類里面的數(shù)據(jù)成員就變成了私有的,不能夠在外部進行訪問,比如下面這樣子就是錯誤的:

int main(int argc, char **?argv) {
????Person?per;
????per.age?= 10; //?error }

上述這樣進行數(shù)據(jù)的訪問就是錯誤的,那么要如何進行訪問呢,我們可以定義這樣一個成員函數(shù)進行數(shù)據(jù)的讀寫,比如下面的代碼所示:

#include  #include  using namespace std; class Person { private: char *name; int age; char *work; public: void PrintInfo(void) { cout << "name?is:" << name << ",age?=?"<< age << ",work?is:"<< work <<endl;
????} void setName(char *n) {
????????name?=?n;
????} int setAge(int a) { if (a?< 0 ||?a?> 150)
????????{
????????????age?= 0; return 0;
????????}
????????age?=?a;
????}
};

這樣定義了類之后,就可以訪問私有成員了,比如下面這樣進行:

int main(int argc, char **argv) {
????Person?per;
????per.setName("wenzi");
????per.setAge(24);
????per.PrintInfo(); return 0;
}

上述代碼加入了private訪問控制符,通過在類里面定義成員函數(shù)的方式,能夠?qū)λ接谐蓡T進行讀寫。

this 指針

再來看上述的代碼,我們可以看到在書寫setName和setAge這兩個函數(shù)的時候,形參寫的是char *n和int a,這樣子給人的感覺就不是那么的直觀,如果寫成char *name和char *age呢,比如成員函數(shù)是像下面這樣子編寫的。

void setName(char *name) {
????name?=?name;
} int setAge(int age) { if (age?< 0 ||?age?> 150)
????{
?????????age?= 0; return 0;
????}
????????age?=?age;
}

上述代碼也很容易看出問題,根據(jù) C 語言的就近原則,name = name沒有任何意義,這個時候就需要引入 this 指針。引入 this 指針之后的代碼如下所示:

#include  #include  using namespace std; class Person { private: char *name; int age; char *work; public: void setName(char *name) { this->name?=?name;
????} int setAge(int age) { if (age?< 0 ||?age?> 150)
????????{ this->age?= 0; return -1;
????????} this->age?=?age; return 0;
????} void printInfo(void) { cout << "name?=" << name << ",?age?=" << age << endl;
????}
}; int main(int argc, char **argv) {
????Person?per;
????per.setName("wenzi");
????per.setAge(25);
????per.printInfo();
}

在上述代碼中,引入了 this 指針,通過上述代碼也可以非常清楚它的意思,就是代表當(dāng)前實例化的對象,能夠指向當(dāng)前實例化對象的成員。

程序結(jié)構(gòu)

上述代碼中,成員函數(shù)是在類里面實現(xiàn)的,這樣使得整個類看著十分的臃腫,我們可以按照如下的方式進行書寫:

#include  class Person { private: char *name; int age; char *work; public: void SetName(char *name); int SetAge(int age;) void PrintInfo(void);
} void Person::SetName(char *name)
{ this->name?=?name;
} void Person::SetAge(int age)
{ this->age?=?age;
} void Person::PrintInfo(void)
{ cout << "name?=?" << name << "age?=?" << age << endl;
}

通過在類外面實現(xiàn)我們的成員函數(shù),看起來要更為簡潔一些,上述就是代碼的實現(xiàn)形式。

多文件

上述代碼中,我們都是將代碼寫在一個文件中,這樣當(dāng)代碼量很大的時候,如果代碼都是在一個文件里,那么會使得代碼難以閱讀,這個時候,我們就會將代碼分別放在幾個文件中來進行管理,比如實現(xiàn)上述相同的功能,我們的代碼結(jié)構(gòu)如下圖所示:

image-20210110120503456

其中main.cpp文件中的內(nèi)容如下所示:

#include  #include "person.h" int main(int argc, char **argv) {
????Person?per; //per.name?=?"zhangsan"; per.setName("zhangsan");
????per.setAge(200);
????per.printInfo(); return 0;
}

可以看到在上述main.cpp中包含了#include "person.h"頭文件,實際上是在person.h文件中定義了person類,person.h文件的內(nèi)容如下:

#ifndef __PERSON_H__ #define __PERSON_H__ class Person { private: char *name; int age; char *work; public: void setName(char *name); int setAge(int age); void printInfo(void);
}; #endif 

然后,在person.cpp中定義了成員函數(shù):

#include  #include "person.h" void Person::setName(char *name)
{ this->name?=?name;
} int Person::setAge(int age)
{ if (age?< 0 ||?age?> 150)
????{ this->age?= 0; return -1;
????} this->age?=?age; return 0;
} void Person::printInfo(void)
{ printf("name?=?%s,?age?=?%d,?work?=?%s\n",?name,?age,?work);?
}

在有了上述三個文件之后,要如何進行編譯呢,這個時候就需要寫一個Makefile文件,接下來簡單介紹一下Makefile語法。

Makefile

總的來說Makefile的規(guī)則核心就如下所示:

target?...?:prerequisites
command
...
...

target也就是一個目標(biāo)文件,可以是Object File,也可以是執(zhí)行文件。還可以是一個標(biāo)簽

prerequisites就是要生成那個target所需要的文件或者是目標(biāo)

command就是make所要執(zhí)行的命令(任意的Shell)

說了核心的東西,來看我們當(dāng)前所編寫的Makefile文件,Makefile文件如下所示:

person:?main.o?person.o g++?-o $@ $^ %.o?:?%.cpp
????g++?-c?-o $@ $< clean: rm?-f?*.o?person

在這里所要明確的一點是這樣的,就是在Makefile中,必須使用 Tab 鍵來進行縮進。然后,需要明確的一個概念是,要使得代碼能夠執(zhí)行,需要經(jīng)過 編譯 -> 鏈接 -> 執(zhí)行,這三個過程才能夠運行,編譯是把源文件編譯成中間代碼,這個中間代碼在 UNIX 是 .o 文件,然后再把大量的 .o 文件合成可執(zhí)行文件,這個過程就是 鏈接,最后,執(zhí)行我們鏈接好的可執(zhí)行文件。

我們來看上述這個Makefile文件,person是最終的可執(zhí)行文件,然后,要生成這個可執(zhí)行文件,需要main.o文件和person.o文件,然后執(zhí)行這個操作需要的是第二條命令,g++ -o $@ $^,其中$@表示的是目標(biāo)文件,$^表示的是所有依賴文件。

然后,緊接著看第三條,%.o : %.cpp,這里表示的是通配符,表示的是所有的 .o 文件和所有的 .cpp 文件,意思就是說要生成的所有的 .o 文件依賴于 .cpp 文件,然后,執(zhí)行的命令是g++ -c -o $@ $<其中表示的是第一個依賴文件。

最后,我們需要清楚,在編譯過程中,生成了一些中間文件以及可執(zhí)行文件,如果我們想要清除掉當(dāng)前生成的文件,那么只需要執(zhí)行make clean就可以清除掉生成的.o文件以及person文件。

函數(shù)重載

C++ 不允許變量重名,但是對于函數(shù)來說,可以允許重載,只要函數(shù)的參數(shù)不同即可,這樣就完成了函數(shù)的重載,直接來看一段關(guān)于函數(shù)重載的代碼:

#include  using namespace std; int add(int a, int b) { cout<<"add?int+int"<<endl; return a+b;
} int add(int a, int b, int c) { cout<<"add?int+int+int"<<endl; return a+b+c;
} double add(double a, double b) { cout<<"add?double+double"<<endl; return a+b;
} double add(int a, double b) { cout<<"add?int+double"<<endl; return (double)a+b;
} double add(double b, int a) { cout<<"add?double+int"<<endl; return (double)a+b;
} int main(int argc, char **argv) {
????add(1, 2);
????add(1, 2, 3);
????add(1.0, 2.0);
????add(1, 2.0);
????add(1.0, 2); return 0;
}

代碼很簡單,就是兩數(shù)相加的一個運算,但是兩數(shù)相加的形參不一樣,有的形參是兩個整型的相加,還有是一個整型和浮點數(shù)的相加,因為 C++ 重載的功能,因此,得以定義多個函數(shù)名相同但是形參和返回值都不同的函數(shù),從而在主函數(shù)實現(xiàn)了不同類型數(shù)的相加。

引用和指針

在 C語言中是沒有引用的,在 C++ 中引用的提出也使得之前在 C 語言中必須使用指針的操作,現(xiàn)在可以使用引用完成了,但是引用又不是指針,簡單來說,引用是一個變量的別名,也就是“綽號”,對于這個別名的操作也就完全等同于被引用變量的操作。為了看是否真的是別名,我們來實驗這樣一段代碼:

#include  using namespace std; int main(int argc,char **argv) { int m;
????m?= 10; int &n?=?m; int *p?=?&m; int *p1?=?&n; cout << "n?=" << n << endl; cout << "p?=" << p << endl; cout << "p1?=" << p1 << endl; return 0;?

}

上述這段代碼中輸出的就是 n 的值,和 m 以及 n 變量的地址,我們來看輸出的內(nèi)容:

image-20210112235421638

可以看到代碼中雖然是對 m 進行了賦值,但是在輸出 n 的時候,輸出的是 m 的值,也就是說在這里對于 n 的操作是完全等同于 m 的,緊接著,我們來證實 n 是否是 m 的別名,那么我們就來看 n 和 m 的地址,可以看到我們輸出的兩個變量的地址也是完全一致的,這也就證實了我們的說法。

接下來,看一段指針,引用,常規(guī)形參的一段代碼,代碼如下所示:

#include  using namespace std; int add_one(int a) {
????a?=?a+1; return a;
} int add_one(int *a) {
????*a?=?*a?+ 1; return *a;
} int add_one_ref(int &b) {
????b?=?b+1; return b;
} int main(int argc, char **argv) { int a?= 99; int &c?=?a; cout<endl; cout<<"a?=?"<endl; cout<endl; cout<<"a?=?"<endl; cout<endl; cout<<"a?=?"<endl;

????????c++; cout<<"a?=?"<endl; cout<<"c?=?"<endl; return 0;
}

根據(jù)上述對于引用的闡述,我們直接給出運行結(jié)果,運行結(jié)果如下所示:

image-20210113000240223

具體的計算過程就不再這里贅述了。

小結(jié)

OK,上述就是關(guān)于 C++ 的一個簡單的引入的過程以及其涉及到的一部分有別于C語言的語法,本教程將持續(xù)連載,歡迎各位朋友關(guān)注~

本小節(jié)所涉及的代碼可以通過百度云鏈接的方式獲取:鏈接:https://pan.baidu.com/s/1RWPXiqiFCVApcfTdaHyDgw
提取碼:j9hd


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

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

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(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ā)耗時1.5...

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

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

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

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

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

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

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

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

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

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

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

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(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)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

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