C++基础入门知识学习(通俗详细讲解)
目錄
- 命名空間
- 標注輸入輸出流
- 缺省參數
- 函數重載
- 引用
- 內聯函數
- C++11新特性auto關鍵字
- C++11新特性基于范圍的for循環
- 關鍵字nullptr
命名空間(關鍵字namespace)
在C++中我們會自己定義很多的變量、函數和類,這就同時要取各種變量名、函數名和類名。如果這些變量、函數和類的名稱都存在與全局作用域中,就要刻意避免重復命名造成的麻煩,要避免命名沖突或名字污染,就要對這些定義的數據類型進行嚴格管理,namespace就是用來對各種標識符名稱進行本地化管理,避免上述麻煩的關鍵字。
語法格式是 namespace 命名空間名稱 {} 。大括號里面就是用來定義變量、函數和類的,這樣的話,即使在其他作用域下有同樣的標識符名稱也不會造成沖突,要用到這些名稱時只要注明相應的命名空間即可,當然是全局作用域下的名稱,就不用注明了,這就把我們要用到的各種標識符名稱很好地管理起來了。具體看一下代碼實現。
我們平常學習C++時為了方便地使用C++標準庫中的函數或對象就常在代碼前面加上using namespace std;
標注輸入輸出流
C++中的標準輸入(鍵盤)和標準輸出(控制臺)所用的關鍵字分別是cin和cout,需要包含頭文件iostream以及標準命名空間std,與C語言的scanf和printf有很大的不同,使用cout不用增加數據格式控制如%d,%f等,它會進行自動類型推導并輸出,使用cin時同樣不用加數據格式控制符,在鍵盤上輸入當類型不同也會發生隱式類型轉換。
int main() {int a;double b;cin >> a>>b;cout << a <<" "<<b << endl;return 0; //cin與>>配合使用 cout與<<配合使用 endl相當于換行符\n }缺省參數
C++函數的參數列表中可以有缺省參數,就是默認參數的意思,在調用函數傳參時給了具體的值就用具體值,沒有傳實參拷貝值時就用默認的值。
//1.全缺省參數 void myprint1(int a = 2, int b = 5, int c = 10) {cout << a + b + c << endl; } //2.半缺省參數 void myprint2(int a, int b = 5, int c = 10) {cout << a + b + c << endl; } int main() {myprint1() ;myprint1(10);myprint2(5);myprint2(3, 4, 5);return 0; }
注意:
- 半缺省參數必須從右往左依次來給出,不能間隔著給
- 缺省參數不能在函數聲明和定義中同時出現
- 缺省值必須是常量或者全局變量
- 4. C語言不支持這樣的語法
函數重載
C++中有函數重載的概念,簡單地說就是允許定義函數名相同的函數,在調用函數時,根據函數傳入參數類型不同、參數個數不同,參數順序不同來區分是要調用同名函數中的哪一個函數。所用發生函數重載的情形相應的就有以下三種。
void func(int a, double b) {cout << "int和double" << endl; } void func(int a) //三個函數名都為func但兩兩比較有參數個數不同、參數類型不同、順序不同 {cout << "int" << endl; } void func(double a, int b) {cout << "double int" << endl; } int main() {func(1); //因此這里調用func會按照函數重載規則去調用相應的函數func(1, 1.5);func(2.5, 1);return 0; }函數重載機制
程序運行要經歷預處理、編譯、匯編和鏈接。當我們調用函數時在鏈接階段,連接器就要按照函數名到相應的符號表中去找對應函數的入口地址去執行哪里的代碼,C語言不支持函數重載就是因為符號表中的函數名就為函數定義時的函數名,而C++符號表中函數名有特殊的函數名修飾規則,在原函數名的基礎上,編譯器將函數參數類型信息添加到修改后的名字中,最后生成的符號表中的函數名是唯一對應一個函數入口地址的。這也解釋了函數返回類型不是產生重載的因素。
引用(關鍵字&)
引用可以通俗地理解給變量取別名,當我們定義一個變量時會在內存中相應地申請一塊空間,我們為使用這塊空間取了個名字,方便我們操縱這塊空間的值,使用引用就為這塊空間取了另外一個名字,使用另外的名字也可以來操縱這塊空間的值。
引用的用法:類型 & 別名=引用實體
要注意引用類型必須和引用實體是同種類型的
常引用
int main() {//int& a = 10; //類型不同 a是變量,10是常量const int& a = 10; const int b = 5;//int& c = b; //類型不同 從b到c權限放大,不允許這樣,int e = 8;const int& h = e; //從e到h變量到常量是權限的縮小,循序這樣double d = 3.14;//int& f = d; //類型不匹配const int& f = d; //這里發生隱式類型轉化d是double類型,產生臨時拷貝值是int型具有常屬性,f是臨時拷貝值的引用return 0; }引用的用法
1.作函數參數
int add(int& a,int& b) {return a+b; }2.作返回類型
int& add(int a,int b) {static int c=a+b;return c; }注意:如果函數返回時,出了函數作用域,如果返回對象還未還給系統,則可以使用引用返回,如果已經還給系統了,則必須使用傳值返回。
引用與指針的區別
引用傳參和值傳參以及引用返回和值返回效率對比
值傳參和傳值返回都是產生臨時變量返回臨時變量,中間有空間開辟和釋放等操作,相比之下引用傳參和返回就沒有這些過程,所以使用引用可以提高運行效率。
內聯函數(關鍵字 inline)
用法就是在普通函數定義的開頭加上修飾字inline,作用是編譯時C++編譯器會在調用內聯函數的地方展開,沒有函數壓棧的開銷,達到提升程序運行的效率。
inline int maxnum(int a,int b) {return (a>b)?a:b; }內聯函數特性
C++11新特性auto關鍵字
C++11開始auto是自動推導定義數據類型,用代碼解釋。
#include<vector> int main() {int a=10;auto b = a; //定義變量b就能推導它是int型,值是10double c=3.14;auto d = c; // 同樣d就是double型,值3.14cout << typeid(b).name() << endl;cout << typeid(d).name() << endl;cout << b << endl;cout << d << endl; vector<int>v1;for (int i = 1; i < 5; i++){v1.push_back(i); //上述用auto來推導int ,double等類型并沒有體現auto帶來的實質性好處} //在stl中有很多類型名非常長,就能體現auto帶來的便利了,這里v1.begin()返回的類型即變量for (auto it = v1.begin(); it != v1.end(); it++)//it的類型是vector<int>::iterator。auto it = v1.begin()和vector<int>::iterator it = v1.begin()是等價的{cout << *it << " ";}return 0; }auto使用細則
1.用auto來聲明指針類型時,auto 和auto * 沒有區別,但聲明引用類型時一定要用 auto &
2.當在同一行聲明多個變量時,這些變量必須是相同的類型,否則編譯器將會報錯,因為編譯器實際只對第一個類型進行推導,然后用推導出來的類型定義其他變量。
注意auto不能用來作形參推導類型
void func(auto a) //這是不允許的不能用來定義數組
auto arr[ ] ={3,5,7}; //不能這樣定義數組C++11新特性基于范圍的for循環
范圍for循環的用法
int main() {int arr[] = { 1,2,3,4,5 };for (auto e : arr) //必須傳入數組名,自動依據數組元素個數推導循壞次數,單趟把數組的一個元素{ //賦值給e,通過這種形式遍歷數組。cout << e << " ";}for (auto& e : arr) //加上引用符& 每趟循環生成不同的e來引用數組的元素從而操縱數組內容,這里就實現了數組各個元素+1的操作{e++;}cout << endl;for (auto e : arr) { cout << e << " ";}return 0; }注意
void myprint(int arr[]) { for (auto e : arr) //這里范圍for的效果就會失效,應為arr一定要是數組名,而這里通過傳參的方法時arr已經退化為指針了,范圍不能確定了。{ cout << e << " ";} }關鍵字nullptr
在C++中關于null定義的代碼如下
#ifndef NULL #ifdef __cplusplus #define NULL 0 //所以null在C++中是等同與整形數字0 #else #define NULL ((void *)0) #endif #endif void func(int) // {cout << "int" << endl; } void func(int*) {cout << "int*" << endl; } int main() {func(0);func(NULL); // 我們本意是希望參數是空指針NULL走第二個函數但實際是走第一個函數func((int*)NULL); //只用強制轉換和參數是nullptr時才走第二個函數func(nullptr);return 0; }
引入nullptr就是希望避免NULL是指針還是整形0的混淆引起的特定情形下的錯誤。
注意
總結
以上是生活随笔為你收集整理的C++基础入门知识学习(通俗详细讲解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工控自动化方案:和利时LE系列PLC数采
- 下一篇: C++学习召集令!