【C++】 C++入门和基础
? ? ? ? ????????????????????????????????????????????????什么是C++?
????????1982年,Bjarne Stroustrup博士在C語言的基礎上引入并擴充了面向對象的概念,發明了一種新的程序語言。為了表達該語言與C語言的淵源關系,命名為C++。因此:C++是基于C語言而產生的,它既可以進行C語言的過程化程序設計,又可以進行以抽象數據類型為特點的基于對象的程序設計,還可以進行面向對象的程序設計。
登高莫問頂,途中耳目新!
文章目錄
- 一、C++的發展歷史和應用領域
- 二、C++的關鍵字
- 三、命名空間
- 四、C++的輸入輸出
- 五、缺省參數
- 六、函數重載
- 七、C++的引用
- 八、內聯函數
- 總結
提示:以下是本篇文章正文內容,下面案例可供參考
一、C++的發展歷史和應用領域
1.1、C++的起源
????????C語言是結構化和模塊化的語言,適合處理較小規模的程序。對于復雜的問題,規模較大的程序,需要高度 的抽象和建模時,C語言則不合適。為了解決軟件危機, 20世紀80年代, 計算機界提出了OOP(object oriented programming:面向對象)思想,支持面向對象的程序設計語言應運而生。之后便有了本賈尼博士等人設計出了C++這門語言。
1.2、C++發展史及歷代版本
? ? ? ??1979年,貝爾實驗室的本賈尼等人試圖分析unix內核的時候,試圖將內核模塊化,于是在C語言的基礎上進行擴展,增加了類的機制,完成了一個可以運行的預處理程序,稱之為C with classes。
1.3、C++的歷史版本
| ????????階段 | ????????????????????????????????????????????????????????????????內容 |
| C with classes | 類及派生類、公有和私有成員、類的構造和析構、友元、內聯函數、賦值運算符重載等 |
| C++1.0 | 添加虛函數概念,函數和運算符重載,引用、常量等 |
| C++2.0 | 更加完善支持面向對象,新增保護成員、多重繼承、對象的初始化、抽象類、靜態成員以 及const成員函數 |
| C++3.0 | 進一步完善,引入模板,解決多重繼承產生的二義性問題和相應構造和析構的處理 |
| C++98 | C++標準第一個版本,絕大多數編譯器都支持,得到了國際標準化組織(ISO)和美國標準化 協會認可,以模板方式重寫C++標準庫,引入了STL(標準模板庫) |
| ··· | ···之后介紹重要版本 |
| C++11 | 增加了許多特性,使得C++更像一種新語言,比如:正則表達式、基于范圍for循環、auto 關鍵字、新容器、列表初始化、標準線程庫等 |
| C++14 | 對C++11的擴展,主要是修復C++11中漏洞以及改進,比如:泛型的lambda表達式, auto的返回值類型推導,二進制字面常量等 |
? ? ? ? 現階段我們常用的還是C++98和C++11;
1.4、C++的應用領域
?1. 操作系統以及大型系統軟件開發
2. 服務器端開發
3. 人工智能
4. 網絡工具
5. 游戲開發
6. 嵌入式領域
7. 數字圖像處理
8. 分布式應用
9. 移動設備
二、C++的關鍵字
1.1、C++關鍵字
????????(C++98) C++總計63個關鍵字,C語言32個關鍵字
三、?命名空間
3.1、命名空間的概念
????????在C/C++中,變量、函數和后面要學到的類都是大量存在的,這些變量、函數和類的名稱將都存在于全局作 用域中,可能會導致很多沖突。使用命名空間的目的是對標識符的名稱進行本地化,以避免命名沖突或名字污染,namespace關鍵字的出現就是針對這種問題的。
示例:如下,我們自己定義的rand和庫里的rand函數產生命名沖突
?3.2、命名空間的定義
????????定義命名空間,需要使用到namespace關鍵字,后面跟命名空間的名字,然后接一對{}即可,{}中即為命名空間的成員。
? ? ? ? 注意點:
? ? ? ?1、命名空間中的內容,既可以定義變量,也可以定義函數
? ? ? ?2、命名空間還可以嵌套,同名的命名空間會被編譯器合并到一起。
3.3、命名空間嵌套的示例
#include<stdio.h> #include<stdlib.h> namespace jjx {namespace xiang{struct ListNode{int val;struct ListNode* next;};} }加域訪問限定符訪問使用示例:
#include<iostream>//放出來,方便使用了,但是存在沖突風險 //using namespace std; //std封C++庫的命名空間//放部分常用的 using std::cout; using std::endl; using std::cin; int main() { cout << "hello world" << endl;return 0; }注意:一個命名空間就定義了一個新的作用域,命名空間中的所有內容都局限于該命名空間中
3.4命名空間的使用
1、加命名空間名稱及作用域限定符????????::
2、使用using將命名空間中成員引入? ? ? ? using N::b;
3、使用using namespace 命名空間名稱引入????????using namespce N;
四、C++的輸入輸出
4.1、C++是如何實現輸入輸出的例子:
#include<iostream>using namespace std; int main() {int a = 0;scanf("%d", &a);printf("%d\n", a);// >> 流提取運算符,cin 是對象, >> 是運算符重載,并且自動識別輸入類型cin >> a;// << 流插入運算符cout << a;return 0; }說明:
1. 使用cout標準輸出(控制臺)和cin標準輸入(鍵盤)時,必須包含< iostream >頭文件以及std標準命名空間。
注意:早期標準庫將所有功能在全局域中實現,聲明在.h后綴的頭文件中,使用時只需包含對應頭文件即可,后來將其實現在std命名空間下,為了和C頭文件區分,也為了正確使用命名空間,規定C++頭文件不帶.h;舊編譯器(vc 6.0)中還支持<iostream.h>格式,后續編譯器已不支持,因此推薦使用
<iostream>+std的方式。
2. 使用C++輸入輸出更方便,不需增加數據格式控制,比如:整形--%d,字符--%c
cin中的>>是通過重載>>和模板實現自動識別類型。
五、缺省參數
5.1、?缺省參數概念
????????缺省參數是聲明或定義函數時為函數的參數指定一個默認值。在調用該函數時,如果沒有指定實參則采用該 默認值,否則使用指定的實參。
類似于備胎的概念:
缺省參數/默認參數 void Fun(int a = 0) {cout << a << endl; } int main() {Fun();//沒有傳參數的時候,使用參數的默認值Fun(1);//傳參時,使用指定的實參return 0; }?5.2、 缺省參數分類
? ·全缺省參數:
void Fun(int a = 10, int b = 20, int c = 30) {cout << "a =" << a << endl;cout << "b =" << b << endl;cout << "c =" << c << endl << endl; } int main() {Fun();Fun(1);Fun(1, 2);Fun(1, 2, 3);return 0; }?·半缺省參數:
?注:
1. 半缺省參數必須從右往左依次來給出,不能間隔著給
2. 缺省參數不能在函數聲明和定義中同時出現
3. 缺省值必須是常量或者全局變量
4. C語言不支持(編譯器不支持)
void Fun(int a , int b = 20, int c = 30) {cout << "a =" << a << endl;cout << "b =" << b << endl;cout << "c =" << c << endl << endl; } int main() { // Fun();半缺省至少傳一個參數Fun(1);Fun(1, 2);Fun(1, 2, 3);return 0; }?缺省值必須是常量或者全局變量
void QueueInit(int n = 10);//申明給值 #include"Queue.h" void QueueInit(int n)//定義給值不可以,必須在申明給值 {cout << n << endl; } #include"Queue.h" int main() {QueueInit();//不給值默認是10,如果是定義給值,則頭文件在這展開時//編譯器找不到其默認值,鏈接時找定義QueueInit(20);return 0; }六、函數重載
C語言不支持重載,C++支持重載!
C++是如何支持的?為什么C語言不能支持?
這里我們一起探索一下問題的答案!
6.1、函數重載概念 :
函數重載:是函數的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數,這些同名函數的 形參列表(參數個數 或 類型 或 順序)必須不同,常用來處理實現功能類似數據類型不同的問題
//C語言不支持同名函數 //CPP支持同名函數 //要求:參數名相同———— //參數不同:參數個數/類型/順序 int Add(int left, int right) {return left + right; } double Add(double left, double right) {return left + right; } void f(int i, double d) {cout << "void f(int i, double d)" << endl; } void f(double i, int d) {cout << "void f(double i, int d)" << endl; } //示例二 void swap(int* p1, int* p2) {int x = *p1;*p1 = *p2;*p2 = x; } void swap(double* p1, double* p2) {double x = *p1;*p1 = *p2;*p2 = x; } int main() {cout << Add(1, 2) << endl;cout << Add(1.1, 2.2) << endl;f(1, 22.2);f(22.2, 1);int a = 0, b = 1;double c = 1.1, d = 2.2;swap(&a, &b);swap(&c, &d);return 0;}為什么C++支持函數重載,而C語言不支持函數重載呢?為此我們不得不提到一個新的概念名字修飾(name Mangling)。
6.2、 名字修飾(name Mangling)
在C/C++中,一個程序要運行起來,需要經歷以下幾個階段:預處理、編譯、匯編、鏈接。
?????????1. 實際我們的項目通常是由多個頭文件和多個源文件構成,而通過我們C語言階段學習的編譯鏈接,我們 可以知道,【當前a.cpp中調用了b.cpp中定義的Add函數時】,編譯后鏈接前,a.o的目標文件中沒有 Add的函數地址,因為Add是在b.cpp中定義的,所以Add的地址在b.o中。那么怎么辦呢?
????????2. 所以鏈接階段就是專門處理這種問題,鏈接器看到a.o調用Add,但是沒有Add的地址,就會到b.o的符 號表中找Add的地址,然后鏈接到一起。(如果同學們忘記了上面過程,咋們老師要帶同學們回顧一下)
????????3. 那么鏈接時,面對Add函數,連接器會使用哪個名字去找呢?這里每個編譯器都有自己的函數名修飾規則。
示例:由于Windows下vs的修飾規則過于復雜,而Linux下gcc的修飾規則簡單易懂
?g++(C++)的函數名修飾
gcc
?
6.3 、extern “C”
?在函數前加extern "C",意思是告訴編譯器, 將該函數按照C語言規則來編譯.
?
C++可以調用C的庫,利用extern 是c++的語法
C也可以調用C++的庫,但是很麻煩,需要條件編譯
下面就是條件編譯
小結:為啥C++支持函數重載
????????了C語言沒辦法支持重載,因為同名函數沒辦法區分。而C++是通過函數修飾規則來區 分,只要參數不同,修飾出來的名字就不一樣,就支持了重載。
七、C++的引用
?7.1 、引用概念
?????????引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會為引用變量開辟內存空間,它和它引用的變量共用同一塊內存空間。
? ? ? ? 就是類似于有些和正品耐克鞋質量一樣好的莆田鞋,他們之間的價格可能差了好幾倍,但是他們的本質是一樣的。
代碼+監視示例:
?7.2、 引用特性
1. 引用在定義時必須初始化
2. 一個變量可以有多個引用?
3. 引用一旦引用一個實體,再不能引用其他實體
賦值操作執行時,比如說是上面的e賦值給b,編譯器會給e產生一個臨時變量,再把臨時變量賦值給b,臨時變量具有常性權限縮小,所以+const?
比如:
示例1:
int main() {int a = 10;int& b = a;//不變//取別名原則:對原引用變量,權限只能縮小,不能放大const int x = 20;//const是可讀但不可改寫(讀寫權限)//int& y = x; //權限放大了const int& y = x;int c = 30;const int& d = c;//權限的縮小return 0; }示例2:
int main() {int a = 10;int& b = a;const int& c = 20;//在傳參過程取別名,才是它更多的作用//C++允許相似類型隱式轉換,會發生截斷或者是整形提升double d = 2.2;const int& e = d;//e是臨時變量的地址,不是d的地址retuen 0; }7.3、?使用場景
1、做參數
void Swap(int& left, int& right) {int temp = left;left = right;right = temp; }?2. 做返回值
int& Count() {static int n = 0;n++;// ...return n; }?注意:
????????如果函數返回時,出了函數作用域,如果返回對象還未還給系統,則可以使用引用返回,如果已經還給系統了,則必須使用傳值返回。
7.4、傳值、傳引用效率比較
????????以值作為參數或者返回值類型,在傳參和返回期間,函數不會直接傳遞實參或者將變量本身直接返回,而是 傳遞實參或者返回變量的一份臨時的拷貝,因此用值作為參數或者返回值類型,效率是非常低下的,尤其是當參數或者返回值類型非常大時,效率就更低。
測試引用傳參的效率、傳值、指針傳參效率的區別的函數
#include <time.h> struct A{ int a[10000]; }; void TestFunc1(A aa){} void TestFunc2(A& aa){} void TestFunc3(A* paa){} void TestRefAndValue() {A a;// 以值作為函數參數size_t begin1 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作為函數參數size_t begin2 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc2(a);size_t end2 = clock();size_t begin3 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc3(&a);size_t end3 = clock();// 分別計算兩個函數運行結束后的時間cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;cout << "TestFunc3(A*)-time:" << end3 - begin3 << endl; }在我的電腦下測試結果
順帶提一下引用和指針的區別:底層的角度,指針和引用是一樣的,因為引用底層就是指針
?為啥傳值會更慢?
傳值調用會產生一個臨時變量,也就是圖中的方塊,所以效率更低
?7.5、引用和指針的不同點:
1. 引用在定義時必須初始化,指針沒有要求
2. 引用在初始化時引用一個實體后,就不能再引用其他實體,而指針可以在任何時候指向任何一個同類型 實體
3. 沒有NULL引用,但有NULL指針
4. 在sizeof中含義不同:引用結果為引用類型的大小,但指針始終是地址空間所占字節個數(32位平臺下占 4個字節)
5. 引用自加即引用的實體增加1,指針自加即指針向后偏移一個類型的大小
6. 有多級指針,但是沒有多級引用
7. 訪問實體方式不同,指針需要顯式解引用,引用編譯器自己處理
8. 引用比指針使用起來相對更安全
八、內聯函數
8.1、內聯函數的概念
????????以inline修飾的函數叫做內聯函數,編譯時C++編譯器會在調用內聯函數的地方展開,沒有函數壓棧的開銷, 內聯函數提升程序運行的效率。
8.2、內聯函數的特性
????????1. inline是一種以空間換時間的做法,省去調用函數額開銷。所以代碼很長或者有循環/遞歸的函數不適宜 使用作為內聯函數。
????????2. inline對于編譯器而言只是一個建議,編譯器會自動優化,如果定義為inline的函數體內有循環/遞歸等 等,編譯器優化時會忽略掉內聯。
????????3. inline不建議聲明和定義分離,分離會導致鏈接錯誤。因為inline被展開,就沒有函數地址了,鏈接就會 找不到。
探究:為什么C++要寫出內聯函數?
用C語言實現一個加法的宏
#define ADD(x, y)((x) + (y))?宏的優缺點:
優點: 1.增強代碼的復用性。 2.提高性能。 缺點: 1.不方便調試宏。(因為預編譯階段進行了替換) 2.導致代碼可讀性差,可維護性差,容易誤用。 3.沒有類型安全的檢查 。
使用內聯寫一個加法函數
inline int Add(int x, int y) {int z = x + y;return z; }?內聯函數的優點:
????????inline: 1、debug版本下支持調試 2、不容易寫錯,就是普通函數的寫法
所以內聯函數是替換宏的一個好辦法。
總結
? ? ? ? 本文寫了約7000字,比較詳細地向大家介紹了什么是C++以及C++發展歷史,?還向大家講述了C++關鍵字、命名空間等知識,希望大家在看完后能夠有所收獲,感謝大家的支持!
總結
以上是生活随笔為你收集整理的【C++】 C++入门和基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最新emoji表情代码大全_8张最新创意
- 下一篇: 腾讯微博android版本,腾讯微博An