嵌入式C++开发详解
一、C++概述
1.嵌入式開發(fā)中為什么選擇C++語言?
(1)面向過程編程的特點
??C語言特點:C語言是在實踐的過程中逐步完善的
? ?? ?? ?? ? ·沒有深思熟慮的設(shè)計過程
? ?? ?? ?? ?? ?·使用時存在很多“灰色地帶”
? ?? ?? ?? ?? ? ……
? ?? ?? ?? ? ·殘留量過多低級語言的特征
? ?? ?? ?? ?? ?·直接利用指針進行內(nèi)存操作
? ?? ?? ?? ?? ? ……
??面向過程的編程特點:
? ?? ?? ?? ? 面向過程程序設(shè)計:數(shù)據(jù)結(jié)構(gòu)+算法
??·主要解決科學計算問題,用戶需求簡單固定
??·特點:分析解決問題所需要的步驟
? ?? ?? ? 利用函數(shù)實現(xiàn)各個步驟
? ?? ?? ? 依次調(diào)用函數(shù)解決問題
??·問題:軟件可重用性差
? ?? ?? ? 軟件可維護性差
? ?? ?? ? 構(gòu)建的軟件無法滿足用戶需求
?
(2)面向?qū)ο缶幊痰奶攸c
??面向?qū)ο蟮木幊烫攸c:
? ?? ?? ?? ?面向?qū)ο蟪绦蛟O(shè)計:由現(xiàn)實世界建立軟件模型
? ?·將現(xiàn)實世界中的事物直接映射到程序中,可直接滿足用戶需求
? ?·特點:直接分析用戶需求中涉及的各個實體
? ?? ?? ???在代碼中描述現(xiàn)實世界中的實體
? ?? ?? ???在代碼中關(guān)聯(lián)各個實體協(xié)同工作解決問題
? ?·優(yōu)勢:構(gòu)建的軟件能夠適應(yīng)用戶需求的不斷變化
? ?? ?? ???直接利用面向過程方法的優(yōu)勢而避開其劣勢
??C++語言特點:高效的面向?qū)ο笳Z言,并且能夠兼容已經(jīng)存在的代碼
?
?
2.C++為什么難學?
C++支持的編程格式:
·過程式
·數(shù)據(jù)抽象
·基于對象
·面向?qū)ο笫?/span>
·函數(shù)式
·泛型形式
·模板元形式
值語義和對象語義:
值語義可以拷貝與賦值,對象語義不可進行拷貝與賦值
3.C++相關(guān)基礎(chǔ)知識點
(1)C++之父是誰?
? ? 本賈尼·斯特勞斯特盧普
1982年,美國AT&T公司貝爾實驗室的Bjarne Stroustrup博士在c語言的基礎(chǔ)上引入并擴充 了面向?qū)ο蟮母拍?#xff0c;發(fā)明了—種新的程序語言。為了表達該語言與c語言的淵源關(guān)系,它被命名為C++。而Bjarne Stroustrup(本賈尼·斯特勞斯特盧普)博士被尊稱為C++語言之父。
(2)C++語言的標準
??C++ 98 標準
??C++標準第一版,1998年發(fā)布。正式名稱為ISO/IEC 14882:1998[17]??。
??C++ 03 標準
??C++標準第二版,2003年發(fā)布。正式名稱為ISO/IEC 14882:2003[18]??。
??C++ 11 標準
??C++標準第三版,2011年8月12日發(fā)布。正式名稱為ISO/IEC 14882:2011[19]??。
??C++11對容器類的方法做了三項主要修改。
??首先,新增的右值引用使得能夠給容器提供移動語義。其次,由于新增了模板類initilizer_list,??
??因此新增了將initilizer_list作為參數(shù)的構(gòu)造函數(shù)和賦值運算符。第三,新增的可變參數(shù)模板(variadic template)和函數(shù)參數(shù)包(parameter pack)使得可以提供就地創(chuàng)建(emplacement)方法。
??C++ 14 標準
??C++標準第四版,2014年8月18日發(fā)布。正式名稱為ISO/IEC 14882:2014[21]??。
??C++14是C++11的增量更新,主要是支持普通函數(shù)的返回類型推演,泛型 lambda,擴
??展的 lambda 捕獲,對 constexpr 函數(shù)限制的修訂,constexpr變量模板化等[22]??。
(3)C++11值得學習的新特性
·智能指針如shared_ptr、weak_ptr等
·rvalue reference
·function/bind
·lambda expression and closure
二、從C到C++的升級
1.聲明定義
C++:C++中更強調(diào)語言的實用性,所有變量都可以在需要使用時再定義
? ???如:for(int i = 0; i < 2; i++)
C語言:變量必須在作用域開始時定義
2.register關(guān)鍵字的升級
? ?經(jīng)常被訪問的變量我們就可以用register修飾為寄存器變量,請求編譯器盡可能的將變量存在CPU的內(nèi)部寄存器中,節(jié)省了CPU從內(nèi)存中抓取數(shù)據(jù)的時間,從而提高了運行效率。
C語言:register只能修飾局部變量,不能修飾全局變量和函數(shù);
? ?? ?? ?register修飾的變量不能通過取地址來獲取寄存器變量;
? ?? ?? ?register修飾的變量一定是CPU能接受的數(shù)據(jù)類型。
C++:在C++中依然支持register關(guān)鍵字
? ?? ?C++編譯器有自己的優(yōu)化方式,不使用register中也可能做優(yōu)化
? ?? ?C++中可以取register變量的地址(C++編譯器發(fā)現(xiàn)程序中需要取register
? ?? ?變量的地址時,register對變量聲明無效)
3.const關(guān)鍵字
C++:C++編譯器對const常量的處理
? ???·當碰見常量聲明時在符號表中放入常量
? ???·編譯過程中若發(fā)現(xiàn)使用常量則以符號表中的值替換
? ???·編譯過程中若發(fā)現(xiàn)對const使用了extern或者&操作符,則給對應(yīng)的常量
? ?? ? 分配存儲空間
??注意:C++編譯器雖然可能為const常量分配空間,但不會使用其存儲空間中
? ?? ???的值。
C語言:C語言中const修飾變量,空間里的值可變,但是不能通過變量名來修改這個空間的對應(yīng)值。
4.內(nèi)存分配與釋放
(1)C++中動態(tài)內(nèi)存分配
·C++中通過new關(guān)鍵字進行動態(tài)內(nèi)存申請
·C++的動態(tài)內(nèi)存申請是基于類型進行的
·delete關(guān)鍵字用于內(nèi)存釋放
變量申清:
Type *pointer = new Type;
……
delete pointer;
數(shù)組申清:
Type *pointer = new Type[];
……
delete[] pointer;
(2)new與malloc區(qū)別
·new關(guān)鍵字是C++的一部分,malloc是由C庫提供的函數(shù)
·new以具體類型為單位進行內(nèi)存分配,malloc只能以字節(jié)為單位進行內(nèi)存
??分配
·new在申請單個類型變量時可進行初始化,malloc不具備內(nèi)存初始化的特
??性
5.引用VS指針
(1)引用
? ???·引用是給一個變量起別名
? ???·定義一個引用的一般格式:
? ?? ?? ? ·類型 &引用名 = 變量名
? ?? ?? ? ·例如:int a = 1;
? ?? ?? ?? ?? ?? ?int &b = a; //b是a的別名,因此a和b是同一個單元
? ?? ?注意:定義引用時一定要初始化,指明該引用變量是誰的別名
? ???·在實際應(yīng)用中,引用一般用作參數(shù)傳遞與返回值
(2)const引用是指向const對象的引用
(3)函數(shù)傳參:按引用傳遞
引用傳遞方式是在函數(shù)定義時在形參前面加上運算符“&”
例如:void swap(int &a,int &b);
·按值傳遞方式容易理解,但形參值得改變不能對實參產(chǎn)生影響
·地址傳遞方式通過形參的改變使響應(yīng)的實參改變,但程序容易產(chǎn)生錯誤且難以閱讀
·引用作為參數(shù)對形參的任何操作都能改變相應(yīng)的實參的數(shù)據(jù),又使函數(shù)調(diào)用顯得方便、自然。
(4)函數(shù)返回值:引用作為函數(shù)返回值
·引用的另一個作用是用于返回引用的函數(shù)
·函數(shù)返回引用的一個主要目的是可以將函數(shù)放在賦值運算符的左邊
·注意:不能返回對局部變量的引用
(5)引用與指針的區(qū)別
·引用訪問一個變量是直接訪問,而指針是間接訪問
·引用是一個變量的別名,本身不單獨分配自己的內(nèi)存空間,而指針有自己的內(nèi)存空間
·引用一經(jīng)初始化不能再引用其它變量,而指針可以
·盡可能使用引用,不得已時使用指針
6.函數(shù)升級
(1)內(nèi)聯(lián)函數(shù)(inline):以空間換時間(頻繁調(diào)用且簡短)
? ?? ?內(nèi)聯(lián)函數(shù)的使用:
? ?? ?? ? inline int max(int a,int b)
? ?? ?? ? {
? ?? ?? ?? ?? ?return a>b?a:b;
? ?? ?? ? }
? ?? ?? ? #define MAX(a,b) (a)>(b)?(a):(b)
? ?? ?內(nèi)聯(lián)函數(shù)與帶參數(shù)宏的區(qū)別:
? ???·內(nèi)聯(lián)函數(shù)調(diào)用時,要求實參和形參的類型一致,另外內(nèi)聯(lián)函數(shù)會先對實
? ?? ? 參表達式進行求值,然后傳遞給形參;而宏調(diào)用只用實參簡單地替換形
? ?? ? 參。
? ???·內(nèi)聯(lián)函數(shù)是在編譯的時候、在調(diào)用的時候?qū)⒋a展開的,而宏則是在預(yù)
? ?? ? 處理時進行替換的
? ???·在C++中建議有用inline函數(shù)來替換帶參數(shù)的宏
(2)函數(shù)重載(overload)
? ? 相同的作用域,如果兩個函數(shù)名稱相同,而參數(shù)不同,我們把它們稱為重載overload
函數(shù)重載的條件:(函數(shù)的返回值不能作為條件)
??·函數(shù)重載不同形式:
? ?? ???·形參數(shù)量不同
? ?? ???·形參類型不同
? ?? ???·形參順序不同
? ?? ???·形參數(shù)量和形參類型都不同
??·調(diào)用重載函數(shù)時,編譯器通過檢查參數(shù)的個數(shù)、類型和順序來確定相應(yīng)
? ? 的被調(diào)用函數(shù)
? ???name managling與extern “C”:
? ???·name managling 這里把它翻譯為名字改編
? ???·C++為了支持重載,需要進行name managling
? ???·extern“C”實現(xiàn)了C與C++混合編程
? ?? ?? ???#ifdef__cpluscplus
? ?? ?? ???extern“C”
? ?? ?? ???{
? ?? ?? ?? ?? ? #endif
? ?? ?? ?? ?? ???……
? ?? ?? ?? ?? ? #ifdef__cpluscplus
? ?? ?? ???}
? ?? ?? ???#endif
(3)帶默認參數(shù)的函數(shù):
? ???·函數(shù)沒有聲明時,在函數(shù)定義中指定形參的默認值
? ???·函數(shù)既有定義又有聲明時,聲明時指定后,定義后就不能再指定默認值
? ???·默認值的定義必須遵守從右到左的順序,如果某個形參沒有默認值,則
? ?? ? 它左邊的參數(shù)就不能有默認值
? ?? ? void funcl(int a,double b = 4.5,int c = 3)? ?//合法
? ?? ? void funcl(int a = 1,double b ,int c = 3)? ?//不合法
? ???·函數(shù)調(diào)用時,實參與形參按從左到右的順序進行匹配
?
7.命名空間-namespace
(1)命名空間
? ? ·在C語言中只有一個全局作用域
? ???·C語言中所有的全局標識符共享一個作用域
? ?? ?? ?·標識符之間可能有沖突
·C++中提出了命名空間的概念
? ???·命名空間將全局作用域分成不同的部分
? ???·不同命名空間中的標識符可以同名而不會發(fā)生沖突
? ???·命名空間可以相互嵌套
? ???·全局作用域也叫默認命名空間
?
?
(2)如何定義命名空間
namespace First
{
? ???int i = 0;
}
namespace Second
{
int i = 1;
}
?
using namespace First;
?
int main()
{
cout<<i<<endl;
cout<<Second::i<<endl;
return 0;
}
(3)如何使用命名空間
·使用整個命名空間:using namespace name;
·使用命名空間中的變量:using name::variable;
·使用默認命名空間中的變量:??::variable
?
默認情況下可以直接使用
默認命名空間中的所有標識符
?
8.新的類型轉(zhuǎn)換運算符
(1)static_cast<T>(expr)
·用于基本類型間的轉(zhuǎn)換,但不能用于基本類型指針間的轉(zhuǎn)換
·用于有繼承關(guān)系類對象之間的轉(zhuǎn)換和類指針之間的轉(zhuǎn)換
?
int main()
{
int i = 0;
char c = ‘c’;
int *pi = &i;
char *pc = &c;
?
c = static_cast<char>(i);//success
pc = static_cast<char *>(pi);//error
? ? return 0;
}
static_cast是在編譯期進行轉(zhuǎn)換的,無法在運行時檢測類型,所以類類型之間的轉(zhuǎn)換可能存在風險
(2)const_cast<T>(expr)
const_cast強制類型轉(zhuǎn)換——用于去除變量的const屬性
int main()
{
? ? const int &j = 1;
? ? int & k = const_cast<int&>(j);
? ? const int x = 2;
? ?? ???int & y = const_cast<int&>(x);
?
? ?? ???k = 5;
?
? ?? ???cout << j << endl;
? ?? ???cout << k << endl;
?
? ?? ???y = 3;
?
? ?? ???cout <<x<<endl;
? ?? ???cout<<y<<endl;
? ?? ???cout <<&x<<endl;
? ?? ???cout<<&y<<endl;
?
? ?? ???return 0;
}
(3)reinterpret_cast<T>(expr)??
??reinterpret_cast強制類型轉(zhuǎn)換
·用于指針類型間的強制轉(zhuǎn)換
·用于整數(shù)和指針類型間的強制轉(zhuǎn)換
typedef void(pf)(int)
int main()
{
int i = 0;
char c = ‘c’;
int * pi = reinterpret_cast<int *>(&c);
char * pc = reinterpret_cast<char *>(&i);
PF * pf = reinterpret_cast<PF*>(0x12345678);
?
c = reinterpret_cast<char>(i);
?
return 0;
}
reinterpret_cast直接從二進制位進行賦值,是一種極其不安全的轉(zhuǎn)換。
(4)dynamic_cast<T>(expr)
? ?dynamic_cast強制類型轉(zhuǎn)換
·主要用于類層次間的轉(zhuǎn)換,還可以用于類之間的交叉轉(zhuǎn)移
·dynamic_cast還具有類型檢查的功能,比static_cast更安全
總結(jié)
以上是生活随笔為你收集整理的嵌入式C++开发详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LVS配合piranha安装使用
- 下一篇: spring源码构建时缺失spring-