基本介紹
C++的起源
1979年,當時的 Bjarne Stroustrup 正在?爾實驗室從事計算機科學和軟件?程的研究?作。?對項?中復雜的軟件開 發任務,特別是模擬和操作系統的開發?作,他感受到了現有語?(如C語?)在表達能?、可維護性 和可擴展性??的不?。

1983年,Bjarne Stroustrup 在C語?的基礎上 添加了 ?向對象編程 的特性,設計出了C++語?的雛形, 此時的C++已經有了類、封裝、繼承等核?概念,為后來的?向對象編程奠定了基礎。這?年該語?被正式命名為C++。
重點:C++祖師爺——Bjarne Stroustrup
? ? ? ? ? ?C++——在C語?的基礎上產生的
? ? ? ? ? ? ? ? ? ? ? ? ?可以進行C語言的過程化程序設計
? ? ? ? ? ? ? ? ? ? ? ? 可以進行以抽象數據類型為特點的基于對象的程序設計
? ? ? ? ? ? ? ? ? ? ? ? 可以進行面向對象的程序設計
C++的發展
時間:1998年
階段:C++98
內容:第一個版本發布,絕大多數編譯器都支持,得到了國際標準化組織(ISO)和美國標準化協會認可,以模板方式重寫?
C++
?標準庫,引入了?STL
?(標準模板庫)。
時間:2011年
階段:C++11
內容:增加了許多特性,使得?
C++
?更像一種新語言,比如:正則表達式、基于范圍for循環、auto關鍵字、新容器、列表初始化、標準線程庫等
時間:2020年
階段:C++11
內容:?引入了許多新的特性,比如:模塊(Modules)、協程(Coroutines)、范圍(Ranges)、概念(Constraints)等重大特性,還有對已有特性的更新:比如Lambda支持模板、范圍for支持初始化等
目前主要實用標準為?C++98
?和?C++11
命名空間
#include <iostream>
using namespace std;
namespace ONE {int n = 3;
}namespace TWO {int n = 4;
}int main() {cout << ONE::n << endl;cout << TWO::n << endl;return 0;
}
命名空間的定義
namespace 關鍵字{//內容——可以定義變量/函數/類型等
}
#include <iostream>
using namespace std;
namespace ONE{int n = 3;namespace TWO {int n = 4;}
}int main() {cout << ONE::n << endl;cout << ONE::TWO::n << endl;return 0;
}
命名空間的使用
一共有三種方法:
方法一:指定命名空間訪問(推薦)
// 指定命名空間訪問
#include <iostream>
using namespace std;
namespace ONE{int n = 3;
}int main() {cout << ONE::n << endl;return 0;
}
//using將命名空間中某個成員展開
#include <iostream>
using namespace std;
namespace ONE{int n = 3;
}
using ONE::n;
int main() {cout << n << endl;return 0;
}
//展開命名空間中全部成員
#include <iostream>
using namespace std;
namespace ONE{int n = 3;
}
using namespace ONE;
int main() {cout << n << endl;return 0;
}
輸入輸出
#include <iostream>
using namespace std;int n = 3;int main() {cout << n << endl;//此處endl寫成'/n'也是同樣的效果return 0;
}
缺省函數
缺省參數是聲明或定義函數時為函數的參數指定?個缺省值。在調?該函數時,如果沒有指定實參 則采?該形參的缺省值,否則使?指定的實參。
缺省參數分為全缺省和半缺省參數? 全缺省就是全部形參給缺省值
? 半缺省就是部分形參給缺省值。(不是一半哦)
?C++規定半缺省參數必須從右往左依次連續缺省,不能間隔跳躍給缺省值。
? 帶缺省參數的函數調?,C++規定必須從左到右依次給實參,不能跳躍給實參。
#include <iostream>
using namespace std;
//全缺省
void Print1(int a = 1, int b = 2) {cout<<"全缺省"<< endl;cout <<a<<endl;cout <<b<< endl;}
//半缺省
void Print2(int a , int b ,int c=3) {cout << "半缺省" << endl;cout <<a<< endl;cout <<b<< endl;cout <<c<< endl;
}int main() {//全缺省——不給參數Print1();//全缺省——給參數Print1(4, 5);//半缺省——給必要參數Print2(1,2);//半缺省——給所有參數Print2(1, 2, 4);return 0;
}
函數重載
#include <iostream>
using namespace std;void func(int a) {cout << a << endl;
}void func(int a,int b) {cout << a<<b << endl;
}void func(double a) {cout << a << endl;
}int main() {func(1);func(1, 2);func(1.1111);return 0;
}
引用
引用的概念
#include<iostream>
using namespace std;int main()
{
int a = 0;
// 引?:b和c是a的別名
int& b = a;
int& c = a;
// 也可以給別名b取別名,d相當于還是a的別名
int& d = b;
++d;
// 這?取地址我們看到是?樣的
cout << &a << endl;cout << &b << endl;
cout << &c << endl;
cout << &d << endl;
return 0;}
引用的特性
? 引?在定義時必須 初始化??? ?個變量可以有多個引?(土豆有很多個別名:洋芋、馬鈴薯)? 引??旦引??個實體,再不能引?其他實體(洋芋只能是土豆的別名,不能再成為其它蔬菜的別名)這一點注意與指針區分開!
引用的使用
#include<iostream>
using namespace std;
//引用傳參
void Swap(int& rx, int& ry){int tmp = rx;rx = ry;ry = tmp;}int main(){int x = 0, y = 1;cout << x << " " << y << endl;Swap(x, y);cout << x << " " << y << endl;return 0;}

int arr[5] = { 0 };//全局變量int& func(int n) {return arr[n];
}int main() {cout << arr[4] << endl;func(4)=1;//改變了arr[4]的值為1cout << arr[4] << endl;return 0;
}
const引用
可以引??個const對象,但是必須?const引?。const引?也可以引?普通對象原因:因為對象的訪問權限在引?過程中 可以縮? ,但是 不能放? 。
注意 :類似 int& rb = a*3; double d = 12.34; int& rd = d; 這樣?些場景下a*3的和結果保存在?個臨時對象中, int& rd = d 也是類似,在類型轉換中會產?臨時對象存儲中間值,也就是時,rb和rd引?的都是臨時對象,?C++規定臨時對象具有常性,所以這? 就觸發了權限放?,必須要?const引?才可以。?(臨時對象:編譯器需要?個空間暫存表達式的求值結果時臨時創建的?個未命名的對象)
指針和引用的關系
引用 | 指針 | |
開不開空間? | 不開 | 開 |
初始化? | 必須初始化 | 建議初始化,但不必須 |
改變對象? | 引??個對象后,不能再引?其他對象 | 可以改變指向對象 |
訪問對象? | 可以直接訪問 | 需要解引? |
sizeof中含義 | 引?類型的?? | 地址空間所占字節個數(32位平臺下 占4個字節,64位下是8byte) |
安全性 | 更安全 | 空指針和野指針的問題 |
內聯函數
nline int Add(int x, int y)
{return x + y;
}
? inline對于編譯器??只是?個建議。也就是說,你加了inline編譯器也可以選擇在調?的地?不展開,不同編譯器關于inline什么情況展開各不相同,因為C++標準沒有規定這個。inline適?于頻繁調用的短小函數,對于遞歸函數,代碼相對多?些的函數,加上inline也會被編譯器忽略。



? C++設計了inline?的就是替代C的宏函數C語?實現宏函數也會在預處理時替換展開,但是宏函數實現很復雜很容易出錯的,且不?便調試
#define ADD(x, y) ((x) + (y)) //通過宏函數實現ADD,復雜易錯
? inline不建議聲明和定義分離到兩個?件,分離會導致鏈接錯誤。因為inline被展開,就沒有函數地址,鏈接時會出現報錯。
內聯函數特點:
- 在?
Debug
?模式下,函數不會進行替換,可以進行調試- 在?
Realse
?模式下,函數會像宏函數一樣展開,提高程序運行速度- 內聯函數彌補了宏函數的不足,同時吸收了宏函數速度快的優點
補充:
nullptr
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif#endif
nullptr是?個特殊的關鍵字,nullptr是?種特殊類型的字?量,它可以轉換 成任意其他類型的指針類型。使?nullptr定義空指針可以避免類型轉換的問題,因為nullptr只能被 隱式地轉換為指針類型,?不能被轉換為整數類型。