C++——入门知识点汇总(命名空间、缺省、重载、引用等)
文章目錄
- 前言
- 一、什么是C++?
- 二、命名空間
- 2.1 命名空間的定義
- 2.2 命名空間的使用
- 三、輸入&輸出
- 四、缺省參數
- 4.1 缺省參數概念
- 4.2 缺省參數分類
- 注意:
- 五、函數重載
- 5.1 概念
- 5.2 名字修飾
- 六、引用
- 6.1 概念
- 6.2 引用特性
- 6.3 常引用
- 6.4 使用場景
- 6.4.1 做參數
- 6.4.2 做返回值
- 6.4.3 變量,指針,數組的引用
- 6.5 效率比較
- 6.5.1 傳值,傳引用效率比較
- 6.5.2 值和引用的作為返回值類型的性能比較
- 6.6 引用和指針的區別
- 引用和指針的不同點
- 七、auto關鍵字
- 7.1 auto簡介
- 7.2 auto的使用細則
- 7.2.3 auto與指針和引用結合起來使用
- 7.2.4 在同一行定義多個變量
- 7.3 auto不能推導的場景
前言
本博客意在總結初學C++的一些基礎知識,便于回顧與復習。
一、什么是C++?
C語言是結構化和模塊化的語言,適合處理較小規模的程序。對于復雜的問題,規模較大的程序,需要高度的抽象和建模時,C語言則不合適。為了解決軟件危機, 20世紀80年代, 計算機界提出了OOP(object oriented programming:面向對象)思想,支持面向對象的程序設計語言應運而生。
1982年,Bjarne Stroustrup博士在C語言的基礎上引入并擴充了面向對象的概念,發明了一種新的程序語言。為了表達該語言與C語言的淵源關系,命名為C++。因此:C++是基于C語言而產生的,它既可以進行C語言的過程化程序設計,又可以進行以抽象數據類型為特點的基于對象的程序設計,還可以進行面向對象的程序設計。
C++發展至今,已發布過許多版本,其中兩個版本需要特別注意:
1.C++98——C++標準第一個版本,絕大多數編譯器都支持,得到了國際標準化組織(ISO)和美國標準化。
協會認可,以模板方式重寫C++標準庫,引入了STL(標準模板庫)
2.C++11——增加了許多特性,使得C++更像一種新語言,比如:正則表達式、基于范圍for循環、auto關鍵字、新容器、列表初始化、標準線程庫等。
二、命名空間
在C/C++中,變量、函數和后面要學到的類都是大量存在的,這些變量、函數和類的名稱將都存在于全局作用域中,可能會導致很多沖突。使用命名空間的目的是對標識符的名稱進行本地化,以避免命名沖突或名字污染,namespace關鍵字的出現就是針對這種問題的。
2.1 命名空間的定義
定義命名空間,需要使用到namespace關鍵字,后面跟命名空間的名字,然后接一對{}即可, {} 中即為命名空間的成員。如:
namespace S1 //S1為命名空間名稱 {//命名空間中的內容,可定義變量,也可定義函數int a = 10;int Add(int x,int y){return x + y;} }需注意:
- 命名空間可以嵌套——一個命名空間的{}內可以定義別的命名空間;
- 同一工程允許存在多個名稱想同的命名空間,編譯器最終會合成同一個命名空間中。
2.2 命名空間的使用
命名空間的使用方式有三種:
- 加命名空間名稱及作用于限定符::
- 使用using將命名空間中成員引入
- 使用using namespace引入命名空間名稱
三、輸入&輸出
在C語言中,我們通常使用scanf & printf進行輸入與輸出,在C++中,我們當然也可以這么做,不過C++提出一種新的方式——cin & cout使我們的輸入輸出更加方便。
首先看一下C++的hello,world如何輸出:
#include<iostream> using namespace std;int main() {cout<<"Hello world!!!"<<endl;//<<后為需要輸出的內容,endl為換行符return 0; }注意:
觀察如上代碼,可以發現任何類型的變量,直接輸入/輸出即可,不必關注變量類型。
四、缺省參數
在C++中提出了缺省參數,思想類似于備胎…
4.1 缺省參數概念
缺省參數是聲明或定義函數時為函數的參數指定一個默認值。在調用該函數時,如果沒有指定實參則采用該默認值,否則使用指定的實參,例:
void TestFunc(int a = 0) {cout<<a<<endl; } int main() {TestFunc(); // 沒有傳參時,使用參數的默認值TestFunc(10); // 傳參時,使用指定的實參 }4.2 缺省參數分類
1. 全缺省參數
顧名思義就是全部參數都有默認值啦(都是備胎)。如:
void TestFunc(int a = 10, int b = 20, int c = 30) {cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl; }2. 半缺省參數
void TestFunc(int a, int b = 10, int c = 20) {cout<<"a = "<<a<<endl;cout<<"b = "<<b<<endl;cout<<"c = "<<c<<endl; }注意:
- 半缺省參數必須從右往左依次來給出,不能間隔著給;
- 缺省參數不能在函數聲明和定義中同時出現(防止誤導編譯器);
- 缺省值必須是常量或者全局變量;
- C語言不支持(編譯器不支持)。
五、函數重載
5.1 概念
函數重載:是函數的一種特殊情況,C++允許在同一作用域中聲明幾個功能類似的同名函數,這些同名函數的形參列表(參數個數 或 類型 或 順序)必須不同,常用來處理實現功能類似數據類型不同的問題
int Add(int left, int right) {return left+right; } double Add(double left, double right) {return left+right; }int main() {Add(10, 20);Add(10.0, 20.0);return 0; }5.2 名字修飾
為什么C++支持重載而C語言不支持呢,原因在編譯器函數名修飾規則不同。
在C/C++中,一個程序要運行起來,需要經歷以下幾個階段:預處理、編譯、匯編、鏈接。而在鏈接階段,面對一個函數,連接器會根據函數名去尋找相應的地址,然后鏈接到一起。對于C語言,函數修飾后名字是不變的,然而連接器對于相同名字的函數該去鏈接哪個是沒有辦法判斷的(同名函數無法區分),而對于C++來說,編譯完成后函數名字的修飾會根據它的參數列表發生改變,不同的參數會被修飾為不同的名稱,這樣,鏈接時連接器就會根據不同的名稱尋找相應的地址完成鏈接啦。
注意:
- 不同的系統下,名字修飾規則是不同的(如linux與windows)
- C++中函數重載底層的處理方法:C++利用命名傾軋技術改變函數名,區分參數不同的同名函數(編譯階段)。
六、引用
6.1 概念
引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會為引用變量開辟內存空間,它和它引用的變量共用同一塊內存空間。
類型& 引用變量名(對象名) = 引用實體; void TestRef() {int a = 10;int& ra = a;//<====定義引用類型printf("%p\n", &a);printf("%p\n", &ra); }注意:引用類型必須和引用實體是同種類型的。
6.2 引用特性
6.3 常引用
觀察如下代碼:,可以發現,引用的類型必須和被引用類型一樣。
void TestConstRef() {const int a = 10;//int& ra = a; // 該語句編譯時會出錯,a為常量const int& ra = a;// int& b = 10; // 該語句編譯時會出錯,b為常量const int& b = 10;double d = 12.34;//int& rd = d; // 該語句編譯時會出錯,類型不同const int& rd = d;}6.4 使用場景
6.4.1 做參數
void Swap(int& left, int& right) {int temp = left;left = right;right = temp; }6.4.2 做返回值
int& Count() {static int n = 0;n++;// ...return n; }注意::如果函數返回時,出了函數作用域,如果返回對象還未還給系統,則可以使用引用返回,如果已經還給系統了,則必須使用傳值返回。(傳值時,創建無名臨時空間來接受返回值)
6.4.3 變量,指針,數組的引用
//變量的引用int a = 1;int &b = a; //指針的引用int *ptr = &a;int *&q = ptr; //數組的引用int arr[n] = {1,2,3,4,5};int(&pa)[5] = arr;6.5 效率比較
6.5.1 傳值,傳引用效率比較
以值作為參數或者返回值類型,在傳參和返回期間,函數不會直接傳遞實參或者將變量本身直接返回,而是傳遞實參或者返回變量的一份臨時的拷貝,因此用值作為參數或者返回值類型,效率是非常低下的,尤其是
當參數或者返回值類型非常大時,效率就更低。
6.5.2 值和引用的作為返回值類型的性能比較
引用作為返回值比值作為返回值的效率好很多,但是如果返回值的生命周期受限則不能使用引用返回。
6.6 引用和指針的區別
在語法概念上引用就是一個別名,沒有獨立空間,和其引用實體共用同一塊空間。但底層實現上實際是有空間的,因為引用是按照指針方式來實現的。
引用和指針的不同點
七、auto關鍵字
7.1 auto簡介
在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動存儲器的局部變量,但遺憾的是一直沒有人去使用它。
C++11中,標準委員會賦予了auto全新的含義即:auto不再是一個存儲類型指示符,而是作為一個新的類型指示符來指示編譯器,auto聲明的變量必須由編譯器在編譯時期推導而得。
觀察一段代碼讓我們更好的了解auto:
int TestAuto() {return 10; } int main() {int a = 10;auto b = a;auto c = 'a';auto d = TestAuto();cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;cout << typeid(d).name() << endl;//auto e; 無法通過編譯,使用auto定義變量時必須對其進行初始化return 0; }上面的代碼部分,可以看到b,c,d的類型分別是int型,char型和 int型,在C語言中,初始化變量時我們必須得指明定義的變量的類型,但有了auto我們便可不再那樣麻煩,它會自動推導auto表達式的實際類型并變換為實際類型,這就是auto的作用!
注意:使用auto定義變量時必須對其進行初始化,在編譯階段編譯器需要根據初始化表達式來推導auto的實際類型。因此auto并非是一種“類型”的聲明,而是一個類型聲明時的“占位符”,編譯器在編譯期會將auto替換為變量實際的類型。
7.2 auto的使用細則
7.2.3 auto與指針和引用結合起來使用
用auto聲明指針類型時,用auto和auto*沒有任何區別,但用auto聲明引用類型時則必須加&。
int main() {int x = 10;auto a = &x;auto* b = &x;auto& c = x;cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;}7.2.4 在同一行定義多個變量
當在同一行聲明多個變量時,這些變量必須是相同的類型,否則編譯器將會報錯,因為編譯器實際只對
第一個類型進行推導,然后用推導出來的類型定義其他變量.
7.3 auto不能推導的場景
1.auto不能作為函數的參數
2. auto不能直接用來聲明數組
3. 為了避免與C++98中的auto發生混淆,C++11只保留了auto作為類型指示符的用法
4. auto在實際中最常見的優勢用法就是跟C++11提供的新式for循環,還有lambda表達式等
進行配合使用
總結
以上是生活随笔為你收集整理的C++——入门知识点汇总(命名空间、缺省、重载、引用等)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言——常见的字符串函数+内存操作函数
- 下一篇: java WebMvcConfig 全局