鄉(xiāng)鎮(zhèn)政府網(wǎng)站建設(shè)自查報(bào)告培訓(xùn)心得體會(huì)范文大全1000字
目錄
- 🥇命名空間
- 🏅存在原因
- 🏵命名空間定義
- 🎧命名空間的3種使用方式
- 🏆C++輸入和輸出
- 🌝缺省參數(shù)
- 🌜缺省參數(shù)概念
- ??缺省參數(shù)分類
- ??函數(shù)重載
- 🔥引用
- 🌚引用概念
- 🌓引用語法
- 🧩引用特性
- 🚧常引用
- 🚏使用場(chǎng)景
- ??傳值、傳引用效率比較
- 💧值和引用的作為返回值類型的性能比較
- ??引用和指針的區(qū)別
- ??總結(jié)
🥇命名空間
🏅存在原因
在C/C++中,變量、函數(shù)和后面要學(xué)到的類都是大量存在的,這些變量、函數(shù)和類的名稱將都存在于全局作用域中,可能會(huì)導(dǎo)致很多沖突。使用命名空間的目的是對(duì)標(biāo)識(shí)符的名稱進(jìn)行本地化, 以避免命名沖突或名字污染,namespace
關(guān)鍵字的出現(xiàn)就是針對(duì)這種問題的。
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
// C語言沒辦法解決類似這樣的命名沖突問題,所以C++提出了namespace來解決
int main()
{printf("%d\n", rand);
return 0;
}
// 編譯后后報(bào)錯(cuò):error C2365: “rand”: 重定義;以前的定義是“函數(shù)”
🏵命名空間定義
定義命名空間,需要使用到namespace
關(guān)鍵字,后面跟命名空間的名字,然后接一對(duì){}即可,{}中即為命名空間的成員。
// 1. 正常的命名空間定義
namespace Q
{// 命名空間中可以定義變量/函數(shù)/類型int rand = 10;int Add(int left, int right){return left + right;}struct Node{struct Node* next;int val;};
}
//2. 命名空間可以嵌套
// test.cpp
namespace N1
{int a;int b;int Add(int left, int right){return left + right;}namespace N2{int c;int d;int Sub(int left, int right){return left - right;}}
}
//3. 同一個(gè)工程中允許存在多個(gè)相同名稱的命名空間,編譯器最后會(huì)合成同一個(gè)命名空間中。
// ps:一個(gè)工程中的test.h和上面test.cpp中兩個(gè)N1會(huì)被合并成一個(gè)(因此兩個(gè)命名空間也不能定義相同的變量)
// test.h
namespace N1
{int Mul(int left, int right){return left * right;}
}
🎧命名空間的3種使用方式
- 加命名空間名稱及作用域限定符
namespace N
{int a = 1;
}
int main()
{printf("%d\n", N::a);return 0;
}
- 使用using將命名空間中某個(gè)成員引入
namespace N
{int a = 1;int b = 2;
}
using N::b;
int main()
{printf("%d\n", N::a);printf("%d\n", b);return 0;
}
- 使用using
namespace
命名空間名稱引入
namespace N
{int a = 1;int b = 2;void Add(int a, int b){printf("%d\n", a + b);}
}
using namespace N;
int main()
{printf("%d\n", N::a);printf("%d\n", b);Add(10, 20);return 0;
}
🏆C++輸入和輸出
std是C++標(biāo)準(zhǔn)庫(kù)的命名空間名,C++將標(biāo)準(zhǔn)庫(kù)的定義實(shí)現(xiàn)都放到這個(gè)命名空間中。如下代碼:
#include<iostream>
using namespace std;
int main()
{cout<<"Hello world!!!"<<endl;return 0;
}
說明:
- 使用
cout
標(biāo)準(zhǔn)輸出對(duì)象(控制臺(tái))和cin
標(biāo)準(zhǔn)輸入對(duì)象(鍵盤)時(shí),必須包含<iostream>
頭文件以及按命名空間使用方法使用std。cout
和cin
是全局的流對(duì)象,endl
是特殊的C++符號(hào),表示換行輸出,他們都包含在包含<iostream>
頭文件中。<<
是流插入運(yùn)算符,>>
是流提取運(yùn)算符。- 使用C++輸入輸出更方便,不需要像
printf/scanf
輸入輸出時(shí)那樣,需要手動(dòng)控制格式。 C++的輸入輸出可以自動(dòng)識(shí)別變量類型
#include <iostream>
using namespace std;
int main()
{int a;double b;char c;// 可以自動(dòng)識(shí)別變量的類型cin>>a;cin>>b>>c;cout<<a<<endl;cout<<b<<" "<<c<<endl;return 0;
}
std命名空間的使用慣例:
std是C++標(biāo)準(zhǔn)庫(kù)的命名空間,如何展開std使用更合理呢?
- 在日常練習(xí)中,直接
using namespace std
即可,這樣就很方便。using namespace std
展開,標(biāo)準(zhǔn)庫(kù)就全部暴露出來了,如果我們定義跟庫(kù)重名的類型/對(duì)象/函數(shù),就存在沖突問題。該問題在日常練習(xí)中很少出現(xiàn),但是項(xiàng)目開發(fā)中代碼較多、規(guī)模大,就很容易出現(xiàn)。- 所以建議在項(xiàng)目開發(fā)中使用像
std::cout
這樣使用時(shí)指定命名空間和using std::cout
展開常用的庫(kù)對(duì)象/類型等方式。
🌝缺省參數(shù)
🌜缺省參數(shù)概念
缺省參數(shù)是聲明或定義函數(shù)時(shí)為函數(shù)的參數(shù)指定一個(gè)缺省值。在調(diào)用該函數(shù)時(shí),如果沒有指定實(shí)參則采用該形參的缺省值,否則使用指定的實(shí)參。
ps:之前聽到一位老師說過一個(gè)非常貼切的比喻,就說這個(gè)缺省參數(shù)就像是一只舔狗,當(dāng)我需要你的時(shí)候,你就趕緊過來,當(dāng)我不需要你的時(shí)候,你就一邊去吧你。(所以說咱們不要當(dāng)舔狗啊兄弟們!!!)
using namespace std;
void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func(); // 沒有傳參時(shí),使用參數(shù)的默認(rèn)值Func(10); // 傳參時(shí),使用指定的實(shí)參return 0;
}
??缺省參數(shù)分類
- 全缺省參數(shù)
using namespace std;
void Func(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}
int main()
{Func(); return 0;
}
- 半缺省參數(shù)
using namespace std;
void Func(int a, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;
}
int main()
{Func(10); return 0;
}
注意:
- 缺省參數(shù)必須從右往左依次來給出,不能間隔著給
- 缺省參數(shù)不能在函數(shù)聲明和定義中同時(shí)出現(xiàn)
- 缺省值必須是常量或者全局變量
- C語言不支持(編譯器不支持)
//a.hvoid Func(int a = 10);// a.cppvoid Func(int a = 20){}// 注意:如果聲明與定義位置同時(shí)出現(xiàn),恰巧兩個(gè)位置提供的值不同,那編譯器就無法確定到底該用那個(gè)缺省值。
??函數(shù)重載
函數(shù)重載:是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個(gè)功能類似的同名函數(shù),這些同名函數(shù)的形參列表(參數(shù)個(gè)數(shù)或類型或類型順序)不同,常用來處理實(shí)現(xiàn)功能類似數(shù)據(jù)類型不同的問題。
#include<iostream>
using namespace std;
// 1、參數(shù)類型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、參數(shù)個(gè)數(shù)不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
// 3、參數(shù)類型順序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}
🔥引用
🌚引用概念
引用不是新定義一個(gè)變量,而是給已存在變量取了一個(gè)別名,編譯器不會(huì)為引用變量開辟內(nèi)存空 間,它和它引用的變量共用同一塊內(nèi)存空間。
🌓引用語法
類型& 引用變量名(對(duì)象名) = 引用實(shí)體;
注意:引用類型必須和引用實(shí)體是同種類型的
#include <iostream>
using namespace std;
void TestRef()
{int a = 10;int& ra = a;//<====定義引用類型printf("%p\n", &a);printf("%p\n", &ra);
}
int main()
{TestRef();return 0;
}
🧩引用特性
- 引用在定義時(shí)必須初始化
- 一個(gè)變量可以有多個(gè)引用
- 引用一旦引用一個(gè)實(shí)體,再不能引用其他實(shí)體
#include <iostream>
void TestRef()
{int a = 10;// int& ra; // 該條語句編譯時(shí)會(huì)出錯(cuò)int& ra = a;int& rra = a;printf("%p %p %p\n", &a, &ra, &rra);
}
int main()
{TestRef();return 0;
}
🚧常引用
權(quán)限可以縮小和平移,但是不能擴(kuò)大。
using namespace std;
void TestConstRef()
{//權(quán)限擴(kuò)大錯(cuò)誤const int a = 10;//int& ra = a; // 該語句編譯時(shí)會(huì)出錯(cuò),a為const修飾的常變量const int& ra = a;// int& b = 10; // 該語句編譯時(shí)會(huì)出錯(cuò),b為常量const int& b = 10;double d = 12.34;//int& rd = d; // 該語句編譯時(shí)會(huì)出錯(cuò),類型不同const int& rd = d;cout << "a = "<< a << endl << "ra = " << ra << endl;cout << "d = " << d << endl << "rd = " << rd << endl;
}int main()
{TestConstRef();return 0;
}
🚏使用場(chǎng)景
- 做參數(shù)
做參數(shù)可以省去傳地址
using namespace std;
void Swap(int& left, int& right)
{int temp = left;left = right;right = temp;
}
int main()
{int a = 10;int b = 20;Swap(a, b);//Swap(&a, &b);cout << "a = " << a << endl;cout << "b = " << b << endl;return 0;
}
- 做返回值
int& Count()
{static int n = 0;n++;return n;
}
int main()
{int ret = Count();cout << ret;return 0;
}
如果函數(shù)返回時(shí),出了函數(shù)作用域,如果返回對(duì)象還在(還沒還給系統(tǒng)),則可以使用引用返回,如果已經(jīng)還給系統(tǒng)了,則必須使用傳值返回。
錯(cuò)誤示范:
int& Add(int a, int b)
{int c = a + b;return c;
}
int main()
{int& ret = Add(1, 2);Add(3, 4);cout << "Add(1, 2) is :"<< ret <<endl;return 0;
}
??傳值、傳引用效率比較
以值作為參數(shù)或者返回值類型,在傳參和返回期間,函數(shù)不會(huì)直接傳遞實(shí)參或者將變量本身直接返回,而是傳遞實(shí)參或者返回變量的一份臨時(shí)的拷貝,因此用值作為參數(shù)或者返回值類型,效 率是非常低下的,尤其是當(dāng)參數(shù)或者返回值類型非常大時(shí),效率就更低。
#include <iostream>
using namespace std;
#include <time.h>
struct A
{ int a[10000];
};
void TestFunc1(A a)
{
}
void TestFunc2(A& a)
{
}
void TestRefAndValue()
{A a;// 以值作為函數(shù)參數(shù)size_t begin1 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc1(a);size_t end1 = clock();// 以引用作為函數(shù)參數(shù)size_t begin2 = clock();for (size_t i = 0; i < 10000; ++i)TestFunc2(a);size_t end2 = clock();// 分別計(jì)算兩個(gè)函數(shù)運(yùn)行結(jié)束后的時(shí)間cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{TestRefAndValue();return 0;
}
💧值和引用的作為返回值類型的性能比較
#include <iostream>
using namespace std;
#include <time.h>
struct A
{ int a[10000];
};
A a;
// 值返回
A TestFunc1()
{ return a;
}
// 引用返回
A& TestFunc2()
{ return a;
}
void TestReturnByRefOrValue()
{// 以值作為函數(shù)的返回值類型size_t begin1 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc1();size_t end1 = clock();// 以引用作為函數(shù)的返回值類型size_t begin2 = clock();for (size_t i = 0; i < 100000; ++i)TestFunc2();size_t end2 = clock();// 計(jì)算兩個(gè)函數(shù)運(yùn)算完成之后的時(shí)間cout << "TestFunc1 time:" << end1 - begin1 << endl;cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
int main()
{TestReturnByRefOrValue();return 0;
}
通過上述代碼的比較,可以發(fā)現(xiàn)傳值和指針在作為傳參以及返回值類型上效率相差很大。
??引用和指針的區(qū)別
在語法概念上引用就是一個(gè)別名,沒有獨(dú)立空間,和其引用實(shí)體共用同一塊空間。
在底層實(shí)現(xiàn)上實(shí)際是有空間的,因?yàn)橐檬前凑罩羔樂绞絹韺?shí)現(xiàn)的。
int main()
{int a = 10;int& ra = a;ra = 20;int* pa = &a;*pa = 20;return 0;
}
運(yùn)行上面的代碼,對(duì)比引用和指針的匯編代碼
引用和指針的不同點(diǎn):
- 引用概念上定義一個(gè)變量的別名,指針存儲(chǔ)一個(gè)變量地址。
- 引用在定義時(shí)必須初始化,指針沒有要求
- 引用在初始化時(shí)引用一個(gè)實(shí)體后,就不能再引用其他實(shí)體,而指針可以在任何時(shí)候指向任何一個(gè)同類型實(shí)體
- 沒有NULL引用,但有NULL指針
- 在
sizeof
中含義不同:引用結(jié)果為引用類型的大小,但指針始終是地址空間所占字節(jié)個(gè)數(shù)(32 位平臺(tái)下占4個(gè)字節(jié),64位平臺(tái)占8個(gè)字節(jié))- 引用自加即引用的實(shí)體增加1,指針自加即指針向后偏移一個(gè)類型的大小
- 有多級(jí)指針,但是沒有多級(jí)引用
- 訪問實(shí)體方式不同,指針需要顯式解引用,引用編譯器自己處理
- 引用比指針使用起來相對(duì)更安全
??總結(jié)
本篇博客主要對(duì)C++的一些入門必備知識(shí)點(diǎn)進(jìn)行歸納總結(jié)介紹,希望可以幫助到準(zhǔn)備學(xué)習(xí)C++的同學(xué),由于作者水平有限,寫作途中難免會(huì)有一些紕漏,還望大家多多包涵指正。