国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++入門(保姆級(jí)教程)

這篇具有很好參考價(jià)值的文章主要介紹了C++入門(保姆級(jí)教程)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

一、C++關(guān)鍵字

二、命名空間

2.1 C語言中的命名沖突?

2.2 C++中命名空間

2.2.1 命名空間的定義

2.2.2 命名空間的特性

2.2.3?命名空間的使用

2.2.4 補(bǔ)充知識(shí)

2.2.4 C++庫的命名空間

三、C++中的輸入&輸出

四、缺省參數(shù)

4.1? 定義

4.2 缺省參數(shù)的分類

4.2.1 全缺省參數(shù)

4.2.2?半缺省參數(shù)

4.3 示例:

五、函數(shù)重載

5.1 定義

5.2 函數(shù)重載示例

5.2.1?參數(shù)個(gè)數(shù)不同

5.2.1?參數(shù)類型不同

5.2.1 類型順序不同

5.3 為什么C++支持函數(shù)重載

六、引用

6.1 定義

6.2 引用特性

6.2.1 引用在定義時(shí)必須初始化

6.2.2 一個(gè)變量可以有多個(gè)引用

6.2.3 引用一旦引用了一個(gè)實(shí)體,再不能引用其他實(shí)體

6.3?引用做參數(shù)(輸出型參數(shù))

6.3.1 示例

6.3.2 效率比較

6.4 引用做返回值

6.4.1 引用做返回值的優(yōu)勢(shì)

6.4.2 性能比較??

6.4.3 引用缺點(diǎn)

6.5 常引用

6.6 引用和指針

七、auto關(guān)鍵字

7.1 概念

7.2 auto的使用事項(xiàng)

7.2.1 auto與指針和引用結(jié)合起來使用

7.2.2 在同一行定義多個(gè)變量

7.3 auto不能推導(dǎo)的場(chǎng)景

7.3.1 auto不能作為函數(shù)的參數(shù)

7.3.2 auto不能直接用來聲明數(shù)組

八、基于范圍的for循環(huán)

8.1 概念

8.2 使用條件

九、內(nèi)聯(lián)函數(shù)

9.1 概念

9.2 適用情況

9.3 注意問題

十、指針空值nullptr(C++)


? ?C++是在C語言的基礎(chǔ)上,容納進(jìn)去了面向?qū)ο蟮木幊趟枷?,并且增加了許多有用的庫,以及編程范式等,所以C++兼容C,也就是我們寫C語言的代碼在C++編譯環(huán)境下也依然能夠編譯通過。

注意:C++兼容C語言,本篇文章在前半部分主要還是用C語言的書寫習(xí)慣來講解C++中的命名空間,所以在前半部分使用的都還是#include<stdio.h>。

一、C++關(guān)鍵字

C++關(guān)鍵字一共有63個(gè)。

? ?在這里暫時(shí)不進(jìn)行逐一解釋,在后期博客會(huì)對(duì)此進(jìn)行分析,大家可以先去菜鳥教程中進(jìn)行了解,鏈接如下:C++ 的關(guān)鍵字(保留字)完整介紹 | 菜鳥教程 (runoob.com)。

二、命名空間

? ?在一方面來講C++是在C的基礎(chǔ)上的完善,所以C++要去解決C語言中出現(xiàn)的一些問題,首先就是命名沖突的問題。

2.1 C語言中的命名沖突?

? ?我們來觀察下面的兩個(gè)代碼:

代碼一:

#include<stdio.h>

int rand = 0;
int main()
{
	printf("%d\n", rand);
	return 0;
}

c++教程,c++,開發(fā)語言,c語言

代碼二:

#include<stdio.h>
#include<stdlib.h>
int rand = 0;
int main()
{
	printf("%d\n", rand);
	return 0;
}

c++教程,c++,開發(fā)語言,c語言

? ? ?對(duì)于上述的兩個(gè)代碼,代碼一可以正常運(yùn)行,但是代碼二無法正常運(yùn)行,這是為什么呢?

c++教程,c++,開發(fā)語言,c語言

? ? 在上述圖片中,我們知道代碼二運(yùn)行不通過的原因是由于rand重定義,我們包含了庫中的頭文件,即?#include<stdlib.h>?,上述頭文件中定義了一個(gè)函數(shù)rand,包含頭文件相當(dāng)于把頭文件中的內(nèi)容在預(yù)編譯期間拷貝一份過來,相當(dāng)于在全局域中,在代碼二中我們也定義了一個(gè)全局變量rand,也在全局域中,這時(shí)就會(huì)有命名沖突的問題

2.2 C++中命名空間

? ? 命名沖突有兩種:

  1. 和庫沖突。
  2. 和項(xiàng)目組中的其他人沖突。? ?

? ?我們知道不同的域中可以有同名的變量,C++解決了C語言中命名沖突的問題,C++使用namespace-命名空間(關(guān)鍵字)來解決命名沖突的問題,使用namespace定義一個(gè)域,用域進(jìn)行隔離。

2.2.1 命名空間的定義

? ?定義命名空間,需要使用到namespace關(guān)鍵字,后面跟命名空間的名字,然后接一對(duì){}即可,{} 中即為命名空間的成員。

? ?例如上述的代碼二,我們就可以定義一個(gè)名字是A的命名空間,rand就在A這個(gè)命名空間域了,將rand變量和stdlib.h中的rand函數(shù)進(jìn)行區(qū)分。

#include<stdio.h>
#include<stdlib.h>

namespace A
{
	int rand = 0;
}

int main()
{
	printf("%d\n", rand);
	return 0;
}

? ?在上述代碼中,相當(dāng)于將全局變量rand定義到了一個(gè)名字是A的域中,而#include<stdlib.h>是將stdlib.h中的內(nèi)容拷貝到當(dāng)前文件中,其中的rand函數(shù)在全局域中,兩個(gè)rand命名的函數(shù)和變量不是處于同一個(gè)域,就解決了命名沖突的問題。

2.2.2 命名空間的特性

1.命名空間中可以定義變量/函數(shù)/類型。

namespace A
{
	int rand = 0;
	int Add(int x, int y)
	{
		return x + y;
	}

	struct A
	{
		int a[5];
		char c;
	};
}

2.命名空間可以嵌套。

? ?當(dāng)一個(gè)命名空間足夠大的時(shí)候,命名空間內(nèi)部的變量或者函數(shù)也會(huì)有命名沖突的問題,這時(shí)候就需要命名空間的嵌套了。

namespace A
{
	int rand = 0;
	int Add(int x, int y)
	{
		return x + y;
	}

	struct A
	{
		int a[5];
		char c;
	};
	namespace B
	{
		int a = 0;
		char c = 'k';
	}
}

3.同一個(gè)工程中允許存在多個(gè)相同名稱的命名空間,編譯器最后會(huì)合成同一個(gè)命名空間中。

例如test.h和hll.cpp中都有A這個(gè)命名空間,在最后編譯運(yùn)行時(shí),會(huì)合成到同一個(gè)命名空間中去。

一個(gè)命名空間就定義了一個(gè)新的作用域,命名空間中的所有內(nèi)容都局限于該命名空間中。

2.2.3?命名空間的使用

#include<stdio.h>

namespace A
{
	int a = 3;
}

int main()
{
	printf("%d\n", a);
	return 0;
}

? ?對(duì)于上述的代碼,編譯會(huì)不通過,在main函數(shù)中有要去打印變量a,但在搜索時(shí)并沒有找到變量a 的定義,這是由于在對(duì)變量a進(jìn)行搜索時(shí),我們不會(huì)主動(dòng)地去命名空間域中去搜索。

? ?對(duì)于命名空間域中的成員,我們不能直接使用,什么時(shí)候才去命名空間域搜索 ?

? ?命名空間中成員該怎么使用呢?

1.指定訪問命名空間域。

? ? ?在這里我們使用 ::(域作用限定符), ::加在變量的前面,表示去::左邊的域訪問。注意:如果左邊的域是空白,就代表是全局域。

#include<stdio.h>

namespace A
{
	int a = 3;
}

int a = 5;

int main()
{
	printf("%d\n", ::a); //::左邊是空白,代表去全局域訪問
	printf("%d\n", A::a);   //::左邊的域是A,代表去A這個(gè)命名空間域訪問
	return 0;
}

2.將命名空間全部展開。(使用using namespace 命名空間名稱 引入)

#include<stdio.h>

namespace A
{
	int a = 3;
}

using namespace A;

int main()
{
	printf("%d\n", a);
	return 0;
}

? ? ?使用using namespace A;將命名空間域A展開,但是展開就相當(dāng)于將A中的內(nèi)容放在全局中,我們使用命名空間的初衷是為了防止和別人或者和庫中的內(nèi)容有沖突,將自己定義的變量等使用作用域限定起來,使用using namespace A;將其展開,可能又會(huì)造成命名沖突的問題,所以我們不推薦使用這個(gè)方式,但是在我們平時(shí)寫代碼的過程中,命名沖突可能性小,所以使用這個(gè)方式。

3.把命名空間中常用的部分展開。

? ? C++的標(biāo)準(zhǔn)庫是使用的std這個(gè)命名空間,我們想要使用cout(輸出)和endl(換行),可以單獨(dú)將他們展開。

#include<iostream>
using std::cout;
using std::endl;


int main()
{
	cout << "hello" << endl;
}

2.2.4 補(bǔ)充知識(shí)

? ?當(dāng)一個(gè)文件中有三個(gè)同名的變量,分別在局部域,全局域以及命名空間域,那么他們的訪問順序是怎樣的?

#include<stdio.h>
#include<stdlib.h>

int a = 0;  //全局域

namespace A
{
	int a = 3;
}

int main()
{
	int a = 1;  //局部域
	printf("%d\n", a);

	return 0;
}

? ? ?對(duì)于不同的域中的三個(gè)同名的變量來說,優(yōu)先去訪問局部變量,然后是全局變量,最后如果展開了命名空間域或者指定訪問才會(huì)去命名空間域。

2.2.4 C++庫的命名空間

? ?C++標(biāo)準(zhǔn)庫中的函數(shù)或者對(duì)象都是在命名空間std中定義的,所以我們要使用標(biāo)準(zhǔn)庫中的函數(shù)或者對(duì)象都要用std來限定。

? ?我們會(huì)發(fā)現(xiàn)在寫C++時(shí),我們?cè)诎^文件時(shí)不再加.h了,這是因?yàn)镃++有了命名空間這個(gè)定義之后,就把C++標(biāo)準(zhǔn)庫中的函數(shù)或者對(duì)象都用std這個(gè)命名空間包起來了,為了和舊的庫進(jìn)行區(qū)分,就定義了新的標(biāo)準(zhǔn),不再使用.h了。

三、C++中的輸入&輸出

? ?在這里由于沒有類和對(duì)象的知識(shí),所以簡(jiǎn)單的了解一下即可,之后會(huì)進(jìn)行講解。

? ?cout相當(dāng)于輸出函數(shù),cin相當(dāng)于輸入函數(shù),endl相當(dāng)于換行,注意cout和cin都可以連續(xù)一行插入或輸出多個(gè)變量,會(huì)自動(dòng)識(shí)別類型。

#include<iostream>  //C++中標(biāo)準(zhǔn)庫,輸入輸出是由iostream庫提供的
using std::cout;
using std::endl;
using std::cin;

int main()
{
	int a = 0;
	int x = 0;
	double d = 0;
	cout << "hello" << " " << 'd' << ' ' << 's' << a << endl;  //endl相當(dāng)于換行
	cin >> x >> d;
	cout << "hello" << " "<< x << " " << d << endl;

	return 0;
}

四、缺省參數(shù)

? ? C++前期是在解決C語言中出現(xiàn)的問題,所以我們又引出了缺省參數(shù)這一概念。

4.1? 定義

? ?缺省參數(shù),聲明函數(shù)的時(shí)候可以讓 最右邊的連續(xù)若干個(gè) 參數(shù)有缺省值,在調(diào)用函數(shù)的時(shí)候,如果不寫相應(yīng)位置的參數(shù),則調(diào)用的參數(shù)就為缺省值。

例如:

#include<iostream>  //C++中標(biāo)準(zhǔn)庫,輸入輸出是由iostream庫提供的
using std::cout;
using std::endl;
using std::cin;

void Func(int a = 0)  //在形參位置上,給一個(gè)缺省值
{
	cout << a << endl;
}

int main()
{
	Func();   //沒有傳參時(shí),使用參數(shù)的默認(rèn)值
	Func(5);    //有傳參時(shí),使用指定的實(shí)參
	return 0;
}

4.2 缺省參數(shù)的分類

4.2.1 全缺省參數(shù)

? ?全缺省參數(shù),即在聲明時(shí),給每一個(gè)形參一個(gè)缺省值。

#include<iostream>  //C++中標(biāo)準(zhǔn)庫,輸入輸出是由iostream庫提供的
using std::cout;
using std::endl;
using std::cin;

void Func(int a = 0, int b = 5,int c = 8)  
{
	cout << "a =" << " " << a << endl;
	cout << "b =" << " " << b << endl;
	cout << "c =" << " " << c << endl;
}

int main()
{
	Func();
	Func(5);//將5傳給a
	Func(5,10);  //將5傳給a,將10傳給b
	Func(5,10,6);  //將5傳給a,將10傳給b, 將6傳給c
	return 0;
}

? ?注意在這里傳參的時(shí)候,只能從左往右依次傳參,不能跳躍傳參。

//即不能如下:
Func(5, ,10);

4.2.2?半缺省參數(shù)

? ?半缺省,在聲明函數(shù)時(shí),給部分參數(shù)缺省值,但是這部分也有要求。

  1. 半缺省參數(shù)必須從右往左來給出,不能間隔著給。(如果從左往右來給出,那么在函數(shù)傳參時(shí)就無法分辨是給哪一個(gè)參數(shù)傳的值)
#include<iostream>  //C++中標(biāo)準(zhǔn)庫,輸入輸出是由iostream庫提供的
using std::cout;
using std::endl;
using std::cin;

void Func(int a, int b = 5, int c = 8)  
{
	cout << "a =" << " " << a << endl;
	cout << "b =" << " " << b << endl;
	cout << "c =" << " " << c << endl;
}

int main()
{
	Func(5);//將5傳給a
	Func(5, 10);  //將5傳給a,將10傳給b
	Func(5, 10, 6);  //將5傳給a,將10傳給b, 將6傳給c
	return 0;
}

2.缺省參數(shù)不能在函數(shù)聲明和定義中同時(shí)出現(xiàn),是在聲明中出現(xiàn)。

例如我們?cè)趖est.h文件中提供Func函數(shù)的聲明,在Test.cpp文件中提供Func函數(shù)的定義:

c++教程,c++,開發(fā)語言,c語言

c++教程,c++,開發(fā)語言,c語言

? ? 在上述兩個(gè)文件中,我們?cè)诼暶?定義中都出現(xiàn)了缺省參數(shù),此時(shí)運(yùn)行不通過。

c++教程,c++,開發(fā)語言,c語言

? ? ?為什么不允許聲明和定義中都給缺省值?為了避免如果在聲明和定義中給的缺省值不一致,那么編譯器按照哪一個(gè)來執(zhí)行的問題。

? ? ?那么是聲明給or定義給呢?
? ? ?當(dāng)然是聲明給。

如果定義給的話會(huì)出現(xiàn)以下的問題:
?

c++教程,c++,開發(fā)語言,c語言

c++教程,c++,開發(fā)語言,c語言?c++教程,c++,開發(fā)語言,c語言?

? ? ? 如果定義給,聲明不給,那么在編譯期間就會(huì)出錯(cuò)。

4.3 示例:

在這里我們使用之前寫過的棧的初始化來表示:

c++教程,c++,開發(fā)語言,c語言

c++教程,c++,開發(fā)語言,c語言

c++教程,c++,開發(fā)語言,c語言

? ?對(duì)于上述棧的初始化,如果開辟空間小的話,要進(jìn)行擴(kuò)容,但是擴(kuò)容會(huì)有一定的消耗,但是如果開辟空間大的話,就會(huì)造成空間的浪費(fèi),我們可以使用缺省參數(shù),當(dāng)已經(jīng)知道需要開辟的空間大小時(shí)指定capacity的大小,未知時(shí),就使用缺省值

五、函數(shù)重載

5.1 定義

? ?函數(shù)重載:是函數(shù)的一種特殊情況,C++允許在同一作用域中聲明幾個(gè)功能類似的同名函數(shù),這 些同名函數(shù)的形參列表(參數(shù)個(gè)數(shù) 或 類型 或 類型順序)不同,常用來處理實(shí)現(xiàn)功能類似數(shù)據(jù)類型 不同的問題。

? ?對(duì)于這樣的構(gòu)成函數(shù)重載的兩個(gè)函數(shù),在進(jìn)行函數(shù)調(diào)用時(shí),編譯器會(huì)自動(dòng)識(shí)別實(shí)參的類型來確定調(diào)用哪一個(gè)函數(shù)。

? ?注意:兩個(gè)同名函數(shù)只有返回類型不同,不構(gòu)成函數(shù)重載。

5.2 函數(shù)重載示例

5.2.1?參數(shù)個(gè)數(shù)不同

#include<iostream>  //C++中標(biāo)準(zhǔn)庫,輸入輸出是由iostream庫提供的
#include"test.h"
using std::cout;
using std::endl;
using std::cin;

void f()
{
	cout << "f()" << endl;
}

void f(int a)
{
	cout << "f(int a)" <<a<< endl;
}

int main()
{
	f();
	f(5);

	return 0;
}

? ?上述兩個(gè)函數(shù)的參數(shù)個(gè)數(shù)不同,構(gòu)成函數(shù)重載。

5.2.1?參數(shù)類型不同

#include<iostream>  //C++中標(biāo)準(zhǔn)庫,輸入輸出是由iostream庫提供的
#include"test.h"
using std::cout;
using std::endl;
using std::cin;

int add(int x, int y)
{
	cout << "int add(int x,int y)" << endl;
	return x + y;
}

double add(double x, double y)
{
	cout << "int add(double x,double y)" << endl;
	return x + y;
}

int main()
{
	cout << add(1, 2) << endl;
	cout << add(1.2, 2.3) << endl;

	return 0;
}

? ?上述的兩個(gè)函數(shù)函數(shù)名相同,他們的函數(shù)形參的類型不同,構(gòu)成函數(shù)重載。

5.2.1 類型順序不同

#include<iostream>  //C++中標(biāo)準(zhǔn)庫,輸入輸出是由iostream庫提供的
#include"test.h"
using std::cout;
using std::endl;
using std::cin;

void f(int a,char b)
{
	cout << "f(int a,char b)" << a << " " << b <<endl;
}

void f(char b,int a)
{
	cout << "f(char b,int a)" << b << " " << a << endl;
}

int main()
{

	f(5,'g');
	f('g', 5);

	return 0;
}

? ?上述兩個(gè)函數(shù)的形參參數(shù)類型順序不同,構(gòu)成函數(shù)重載。

5.3 為什么C++支持函數(shù)重載

? ?我們使用下面的例子來具體探討:

c++教程,c++,開發(fā)語言,c語言

c++教程,c++,開發(fā)語言,c語言

c++教程,c++,開發(fā)語言,c語言

? ?要探索C++為什么支持函數(shù)重載,我們要從編譯鏈接過程來看。

c++教程,c++,開發(fā)語言,c語言

c++教程,c++,開發(fā)語言,c語言

? ? ? 在c語言中,生成的符號(hào)表中記錄的只有函數(shù)的名字以及地址,即類似于下方(下方只是粗大致畫的,實(shí)際中并不是這樣):

c++教程,c++,開發(fā)語言,c語言

? ? ? 而在C++的符號(hào)表記錄中,會(huì)記錄形參的類型,所以它支持函數(shù)重載。

六、引用

? ?在c語言中,在學(xué)習(xí)指針的時(shí)候是一大難點(diǎn),C++中退推出了引用來更加方便的解決了一部分與指針相關(guān)的問題。

6.1 定義

? ?引用不是新定義一個(gè)變量,而是給已存在變量取了一個(gè)別名,編譯器不會(huì)為引用變量開辟內(nèi)存空 間,它和它引用的變量共用同一塊內(nèi)存空間。

類型& 引用變量名(對(duì)象名) = 引用實(shí)體;

注意:引用類型必須和引用實(shí)體是同一類型的。

? ?下面就是一個(gè)引用的例子:

int main()
{
	int a = 0;
	int& b = a;  //b是a的別名,b和a使用的同一塊空間
	int& c = b;  //c是b的別名,b是a的別名,即c是a的別名,c,b和a使用的同一塊空間

	cout << &a << endl;
	cout << &b << endl;
	cout << &c << endl;

	return 0;
}

c++教程,c++,開發(fā)語言,c語言

6.2 引用特性

6.2.1 引用在定義時(shí)必須初始化

int a = 0;
int& b = a;  //b是a的別名,b和a使用的同一塊空間
int& c = b;  //正確
int& d;  //是錯(cuò)誤的,必須要初始化

6.2.2 一個(gè)變量可以有多個(gè)引用

#include<iostream>
using namespace std;

int main()
{
	int a = 0;
	int& b = a;
	int& c = a;
}

6.2.3 引用一旦引用了一個(gè)實(shí)體,再不能引用其他實(shí)體

#include<iostream>
using namespace std;

int main()
{
	int a = 0;
	int& b = a;
	int& c = a;
	
	//引用一旦引用了一個(gè)實(shí)體,再不能引用其他實(shí)體
	int x = 10;
	c = x; //在這里是將x的值賦給c,c依舊是a/b的別名

	return 0;
}

引用的使用場(chǎng)景

6.3?引用做參數(shù)(輸出型參數(shù))

6.3.1 示例

#include<iostream>
using namespace std;

void Swap(int& x, int& y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int a = 10;
	int b = 5;
	Swap(a, b);
	return 0;
}

? ?之前我們用函數(shù)實(shí)現(xiàn)交換兩個(gè)數(shù)的值,要用指針,在這里我們就可以使用引用了,x相當(dāng)于a的別名,y相當(dāng)于b的別名,改變x即改變a。

6.3.2 效率比較

? ?我們使用下面的函數(shù)來測(cè)試引用與非引用的效率。

#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;
}

c++教程,c++,開發(fā)語言,c語言

? ?我們可以看出使用引用 ,效率明顯提高。

6.4 引用做返回值

? ?下面我們會(huì)通過幾個(gè)代碼示例來具體體會(huì)引用做返回值的優(yōu)勢(shì)與弊端。

6.4.1 引用做返回值的優(yōu)勢(shì)

? ?在下面,我們會(huì)通過一段代碼的傳值返回和傳引用返回來比較用引用做返回值的優(yōu)勢(shì)。

? ?在下面的兩段代碼中我們使用傳值返回:

1. n是局部變量

int count()
{
	int n = 0;
	n++;
	return n;
}

int main()
{
	int ret = count();
	return 0;
}

c++教程,c++,開發(fā)語言,c語言

2.n是靜態(tài)變量

int count()
{
	static int n = 0;
	n++;
	return n;
}

int main()
{
	int ret = count();
	return 0;
}

c++教程,c++,開發(fā)語言,c語言

? ? ?我們會(huì)發(fā)現(xiàn)在上面的傳值返回中,不論函數(shù)中的變量是局部變量還是靜態(tài)變量,都需要有一個(gè)臨時(shí)變量協(xié)助完成返回,如果我們不想生成臨時(shí)變量怎么辦?用引用返回。

c++教程,c++,開發(fā)語言,c語言

6.4.2 性能比較??

值和引用作為函數(shù)的返回值的性能比較:

#include<iostream>
using namespace std;
#include<time.h>
struct A { int a[1000]; };

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;
}

c++教程,c++,開發(fā)語言,c語言

6.4.3 引用缺點(diǎn)

? ?在一些時(shí)候,我們無法用引用作為返回值,它會(huì)導(dǎo)致一些錯(cuò)誤。

錯(cuò)誤示例:
?

int& count()    //返回的是n的別名
{
	int n = 0;
	n++;
	return n;
}

int main()
{
	int ret = count();
	return 0;
}

? ?在上述的情況下使用引用作為函數(shù)的返回類型,就會(huì)出問題,在上述代碼中出現(xiàn)了野指針的訪問。

c++教程,c++,開發(fā)語言,c語言

? ?在上面的圖中,我們可以明顯的看到當(dāng)main函數(shù)調(diào)用count函數(shù)時(shí),n創(chuàng)建,當(dāng)調(diào)用結(jié)束,棧幀銷毀,n是在count函數(shù)中的局部變量,n的空間還給操作系統(tǒng)。

? ?在這里ret的值是不確定的,count函數(shù)返回的是n的別名,當(dāng)count函數(shù)調(diào)用結(jié)束,將n的別名對(duì)應(yīng)空間的值(即n的值)拷貝給ret,如果count函數(shù)調(diào)用結(jié)束,棧幀銷毀,沒有清理?xiàng)?,那么ret的結(jié)果僥幸是正確的,如果count函數(shù)調(diào)用結(jié)束,棧幀銷毀,清理?xiàng)敲磖et的結(jié)果是隨機(jī)值。

總結(jié):
1.基本任何場(chǎng)景都可以使用引用傳參

2.謹(jǐn)慎使用引用做返回值,出了函數(shù)作用域,變量就不在了,就不能使用引用返回,如果出了函數(shù)作用域,變量還在,就可以使用引用做返回類型

6.5 常引用

? ?常引用是指利用 const 修飾的引用類型。 由于引用本身已經(jīng)綁定不可解綁,因此所用的 const 引用都是底層 const,即引用對(duì)象不能改變 (俗稱常引用)。

在引用的過程中,權(quán)限不能放大,但是引用過程中,權(quán)限可以平移或者縮小。

下面通過幾個(gè)例子來看常引用。

    int a = 0;
	int& b = a;     //正確,b是a的別名


	const int a = 0;
	int& b = a;    //錯(cuò)誤,a是const修飾的,不能改變,而b是int類型的引用,引用不能放大權(quán)限

	const int c = 0;
	int d = c;      //正確,把c的值拷貝給d,沒有放大權(quán)限
    int x = 0;
	int& y = x;   //正確,y是x的別名
	const int& z = x;   //正確,引用能夠縮小權(quán)限

	int x = 0;
	int& y = x;
	const int& z = x;  //當(dāng)z這個(gè)別名時(shí),x的值不能改變
	++x;      //當(dāng)是x這個(gè)名字時(shí),x的值可以改變
const int& m = 10;   //m是常量10的別名,權(quán)限的平移
//當(dāng)類型不同時(shí),會(huì)發(fā)生隱式類型轉(zhuǎn)換,在轉(zhuǎn)換時(shí),中間會(huì)產(chǎn)生臨時(shí)變量,產(chǎn)生的臨時(shí)變量具有常性,

	double dd = 1.11;
	int ii = dd;       //當(dāng)類型不同時(shí),會(huì)發(fā)生隱式類型轉(zhuǎn)換
	int& isi = dd;        //錯(cuò)誤

	double dd = 1.11;
	int ii = dd;
	const int& rii = dd;  //正確

c++教程,c++,開發(fā)語言,c語言

int func1()
{
	static int x = 0;
	return x;
}

int main()
{
	//int& ret = func1();   //錯(cuò)誤,函數(shù)返回時(shí)也會(huì)產(chǎn)生一個(gè)臨時(shí)變量,臨時(shí)變量具有常性,此處是對(duì)權(quán)限的擴(kuò)大
	const int& ret = func1();  //正確,權(quán)限的平移
	return 0;
}

6.6 引用和指針

引用和指針的不同點(diǎn):
1. 引用概念上定義一個(gè)變量的別名,指針存儲(chǔ)一個(gè)變量地址。
2. 引用在定義時(shí)必須初始化,指針沒有要求
3. 引用在初始化時(shí)引用一個(gè)實(shí)體后,就不能再引用其他實(shí)體,而指針可以在任何時(shí)候指向任何
一個(gè)同類型實(shí)體
4. 沒有NULL引用,但有NULL指針
5. 在sizeof中含義不同引用結(jié)果為引用類型的大小,但指針始終是地址空間所占字節(jié)個(gè)數(shù)(32
位平臺(tái)下占4個(gè)字節(jié))
6. 引用自加即引用的實(shí)體增加1,指針自加即指針向后偏移一個(gè)類型的大小
7. 有多級(jí)指針,但是沒有多級(jí)引用
8. 訪問實(shí)體方式不同,指針需要顯式解引用,引用編譯器自己處理
9. 引用比指針使用起來相對(duì)更安全

七、auto關(guān)鍵字

? ?隨著程序越來越復(fù)雜,程序中用到的類型也越來越復(fù)雜,可能出現(xiàn)類型難于拼寫等問題,這時(shí)C++就提出了auto關(guān)鍵字。

7.1 概念

? ? C++11中,標(biāo)準(zhǔn)委員會(huì)賦予了auto全新的含義即:auto不再是一個(gè)存儲(chǔ)類型指示符,而是作為一
個(gè)新的類型指示符來指示編譯器,auto聲明的變量必須由編譯器在編譯時(shí)期推導(dǎo)而得
int main()
{
	int a = 0;
	int b = a;
	auto c = b;   //根據(jù)右邊的表達(dá)式自動(dòng)推導(dǎo)c的類型
	auto d = 1 + 1.11;   //根據(jù)右邊的表達(dá)式自動(dòng)推導(dǎo)d的類型
    
	//typeid可以打印類型
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	return 0;
}

c++教程,c++,開發(fā)語言,c語言

? ?注意:

? ?使用auto定義變量時(shí)必須對(duì)其進(jìn)行初始化,在編譯階段編譯器需要根據(jù)初始化表達(dá)式來推導(dǎo)auto 的實(shí)際類型。因此auto并非是一種“類型”的聲明,而是一個(gè)類型聲明時(shí)的“占位符”,編譯器在編 譯期會(huì)將auto替換為變量實(shí)際的類型

7.2 auto的使用事項(xiàng)

7.2.1 auto與指針和引用結(jié)合起來使用

? ?用auto聲明指針類型時(shí),用auto和auto*沒有任何區(qū)別,但用auto聲明引用類型時(shí)則必須
加&。
int main()
{
	int x = 10;
	auto a = &x;    //推導(dǎo)出來a是指針
	auto* b = a;    //指定必須是指針
	auto& c = x;    //指定是引用
	return 0;
}

7.2.2 在同一行定義多個(gè)變量

? ?當(dāng)在同一行聲明多個(gè)變量時(shí),這些變量必須是相同的類型,否則編譯器就會(huì)報(bào)錯(cuò),因?yàn)榫幾g器實(shí)際上只對(duì)第一個(gè)類型進(jìn)行推導(dǎo),然后用推導(dǎo)出來的類型定義其他變量。

auto a = 10, b = 2;
//auto ac = 0, d=1.11;//錯(cuò)誤

7.3 auto不能推導(dǎo)的場(chǎng)景

7.3.1 auto不能作為函數(shù)的參數(shù)

// 此處代碼編譯失敗,auto不能作為形參類型,因?yàn)榫幾g器無法對(duì)a的實(shí)際類型進(jìn)行推導(dǎo)
void TestAuto(auto a)
{}

7.3.2 auto不能直接用來聲明數(shù)組

void TestAuto()
{
	int a[] = { 0,1,2 };
	//auto a[] = { 4,3,5 };    //錯(cuò)誤

}

八、基于范圍的for循環(huán)

8.1 概念

? ? 對(duì)于一個(gè)有范圍的集合而言,由程序員來說明循環(huán)的范圍是多余的,有時(shí)候還會(huì)容易犯錯(cuò)誤。因
此C++11中引入了基于范圍的for循環(huán)。for循環(huán)后的括號(hào)由冒號(hào)“ :”分為兩部分:第一部分是范
圍內(nèi)用于迭代的變量,第二部分則表示被迭代的范圍。
int main()
{
	int arr[] = { 1,2,3,4,5 };
	//c語言中訪問數(shù)組
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
		arr[i] *= 2;

	for(int *p=arr; p<arr+ sizeof(arr) / sizeof(arr[0]);p++)
		cout<<*p<<endl;

	//范圍for
	//依次取數(shù)組中數(shù)據(jù)賦值給e
	//自動(dòng)迭代,自動(dòng)判斷結(jié)束
	for (auto e : arr)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

如果我們要使用范圍for來修改數(shù)組中的數(shù)據(jù):

int main()
{
	//修改數(shù)據(jù)

	//錯(cuò)誤,取arr中數(shù)據(jù)依次賦值給e,相當(dāng)于依次取arr[0]、arr[1]......拷貝給e,e的改變不會(huì)影響數(shù)組的內(nèi)容
	for (auto e : arr)
	{
		e *= 2;
	}

	//正確,e開始是arr[0]別名,然后是arr[1]別名,e的修改會(huì)影響數(shù)組
	for (auto& e : arr)
	{
		e *= 2;
	}

	return 0;
}

? ?注意上述的范圍for中,auto,e都可以改變,arr是數(shù)組。

8.2 使用條件

for循環(huán)迭代的范圍必須是確定的。

int main()
{
	int arr[] = { 0,1,2,3,4,5 };
	int* p = arr;

	//錯(cuò)誤,因?yàn)閒or的范圍不確定
	for (auto& e : p)
	{
		e *= 2;
	}
	return 0;
}

九、內(nèi)聯(lián)函數(shù)

9.1 概念

? ?以inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用內(nèi)聯(lián)函數(shù)的地方展開,沒有函數(shù)調(diào)用建立棧幀的開銷,內(nèi)聯(lián)函數(shù)提升程序運(yùn)行的效率。

9.2 適用情況

? ?內(nèi)聯(lián)函數(shù)適用于短小的頻繁調(diào)用的函數(shù),inline對(duì)于編譯器僅僅只是一個(gè)建議,最終是否成為inline,編譯器自己決定。

? ?內(nèi)聯(lián)函數(shù)不適用于:1. 比較長(zhǎng)的函數(shù)? ? ?2. 遞歸函數(shù)

inline int Add(int x, int y)
{
	return (x + y) * 10;
}
int main()
{
	for (int i = 0; i < 100; i++)
	{
		cout << Add(i, i + 1) << endl;
	}
	return 0;
}

9.3 注意問題

? ?inline不建議聲明和定義分離,分離會(huì)導(dǎo)致鏈接錯(cuò)誤。因?yàn)閕nline被展開,就沒有函數(shù)地址了,鏈接就會(huì)找不到。

十、指針空值nullptr(C++)

void Testptr()
{
	int* p1 = NULL;
}
NULL可能被定義為字面常量0,或者被定義為無類型指針(void*)的常量。
void f(int)
{
	cout << "f(int)" << endl;
}
void f(int*)
{
	cout << "f(int*)" << endl;
}
int main()
{
	f(0);
	f(NULL);
	f((int*)NULL);
	return 0;
}

? ?在上述代碼中,我們想要調(diào)用void f(int*),但是發(fā)現(xiàn)每次調(diào)用的都是void f(int),在C++98中,字面常量0既可以是一個(gè)整形數(shù)字,也可以是無類型的指針(void*)常量,但是編譯器默認(rèn)情況下將其看成是一個(gè)整形常量,如果要將其按照指針方式來使用,必須對(duì)其進(jìn)行強(qiáng)轉(zhuǎn)(void*)0。文章來源地址http://www.zghlxwxcb.cn/news/detail-731284.html

注意:
1. 在使用nullptr表示指針空值時(shí),不需要包含頭文件,因?yàn)閚ullptr是C++11作為新關(guān)鍵字引入
2. 在C++11中,sizeof(nullptr) 與 sizeof((void*)0)所占的字節(jié)數(shù)相同。
3. 為了提高代碼的健壯性,在后續(xù)表示指針空值時(shí)建議最好使用nullptr。

到了這里,關(guān)于C++入門(保姆級(jí)教程)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Shopify開發(fā)入門-前端保姆級(jí)教程

    Shopify開發(fā)入門-前端保姆級(jí)教程

    本文旨在介紹Shopify開發(fā)入門、環(huán)境、配置等,幫助開發(fā)者配置環(huán)境、了解各個(gè)開發(fā)模式的區(qū)別及用途;已有Shopify開發(fā)經(jīng)驗(yàn)者可退出,以免浪費(fèi)你的寶貴時(shí)間。 本文5k字+,圖片、鏈接、代碼塊較多,請(qǐng)耐心閱讀~ 最近在調(diào)研Shopify開發(fā),對(duì)其也有了一定的認(rèn)識(shí)、了解;即將這些

    2024年02月16日
    瀏覽(47)
  • 保姆級(jí)教程——VSCode如何在Mac上配置C++的運(yùn)行環(huán)境

    保姆級(jí)教程——VSCode如何在Mac上配置C++的運(yùn)行環(huán)境

    點(diǎn)擊官網(wǎng)鏈接,下載對(duì)應(yīng)的pkg,安裝打開; 點(diǎn)擊箭頭所指插件商店按鈕,yyds; 下載C/C++ 插件; ![外鏈圖片轉(zhuǎn)存 ! 如果安裝失敗,可手動(dòng)安裝; 打開Github:https://github.com/vadimcn/vscode-lldb/releases; 如果是基于Intel的Mac選擇codelldb-×86_64-darwin.vsix, 如果是基于Apple Silicon的Mac選擇

    2024年02月09日
    瀏覽(27)
  • Spring注解開發(fā) -- Spring快速入門保姆級(jí)教程(二)

    Spring注解開發(fā) -- Spring快速入門保姆級(jí)教程(二)

    為了鞏固所學(xué)的知識(shí),作者嘗試著開始發(fā)布一些學(xué)習(xí)筆記類的博客,方便日后回顧。當(dāng)然,如果能幫到一些萌新進(jìn)行新技術(shù)的學(xué)習(xí)那也是極好的。作者菜菜一枚,文章中如果有記錄錯(cuò)誤,歡迎讀者朋友們批評(píng)指正。 (博客的參考源碼可以在我主頁的資源里找到,如果在學(xué)習(xí)的

    2024年02月09日
    瀏覽(30)
  • 萬字長(zhǎng)文 | 保姆級(jí)的后臺(tái)服務(wù)器開發(fā)C++學(xué)習(xí)路線

    ??這一篇的主題是「Linux C/C++ 服務(wù)器/后臺(tái)開發(fā)學(xué)習(xí)路線」。 ? ??這樣的文章相信大家都見得不少了,寫之前也非常忐忑,能不能和其它人寫得不一樣, 也定下了一個(gè)目標(biāo),這篇文章,不能是簡(jiǎn)單的堆砌學(xué)習(xí)資源和書單推薦,更要細(xì)化如何有效的去執(zhí)行落地。 ? ??爭(zhēng)取

    2024年02月06日
    瀏覽(23)
  • C語言基礎(chǔ)入門——配置C/C++環(huán)境及多種運(yùn)行方式(保姆級(jí)教程)

    C語言基礎(chǔ)入門——配置C/C++環(huán)境及多種運(yùn)行方式(保姆級(jí)教程)

    本文章主要講解新手在運(yùn)行C 程序的源文件.c中的一些簡(jiǎn)單操作。 其主要的編輯器有:VSCode、CodeBlocks、VC++ 6.0、CodeLite、Notepad、eclipse、 dev-C++、 C-Free,vim/vi(Linux/UNIX 操作系統(tǒng))等。 其主要的編譯器有:Gcc、Clang(蘋果公司開發(fā)的C語言編譯器前端)、MSVC、Turbo C等。 文章中所

    2024年04月15日
    瀏覽(166)
  • 【Go語言】Golang保姆級(jí)入門教程 Go初學(xué)者chapter3

    【Go語言】Golang保姆級(jí)入門教程 Go初學(xué)者chapter3

    下劃線“_”本身在Go中一個(gè)特殊的標(biāo)識(shí)符,成為空標(biāo)識(shí)符??梢源砣魏纹渌臉?biāo)識(shí)符,但是他對(duì)應(yīng)的值就會(huì)被忽略 僅僅被作為站維度使用, 不能作為標(biāo)識(shí)符使用 因?yàn)镚o語言中沒有private public 所以標(biāo)記變量首字母大寫代表其他包可以使用 小寫就是不可使用的 注意:Go語言中

    2024年02月13日
    瀏覽(92)
  • 【Go語言】Golang保姆級(jí)入門教程 Go初學(xué)者chapter2

    【Go語言】Golang保姆級(jí)入門教程 Go初學(xué)者chapter2

    setting的首選項(xiàng) 一個(gè)程序就是一個(gè)世界 變量是程序的基本組成單位 變量的使用步驟 [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-zuxG8imp-1691479164956)(https://cdn.staticaly.com/gh/hudiework/img@main/image-20230726152905139.png)] 變量表示內(nèi)存中的一個(gè)存儲(chǔ)區(qū) 注意:

    2024年02月14日
    瀏覽(577)
  • yolov8實(shí)戰(zhàn)第六天——yolov8 TensorRT C++ 部署——(踩坑,平坑,保姆教程)

    yolov8實(shí)戰(zhàn)第六天——yolov8 TensorRT C++ 部署——(踩坑,平坑,保姆教程)

    C++ 結(jié)合 TensorRT 部署深度學(xué)習(xí)模型有幾個(gè)關(guān)鍵優(yōu)勢(shì),這些優(yōu)勢(shì)在各種工業(yè)和商業(yè)應(yīng)用中極其重要: 高效的性能 :TensorRT 通過優(yōu)化深度學(xué)習(xí)模型來提高推理速度,減少延遲。這對(duì)于實(shí)時(shí)處理應(yīng)用(如視頻分析、機(jī)器人導(dǎo)航等)至關(guān)重要。 降低資源消耗 :TensorRT 優(yōu)化了模型以在

    2024年04月13日
    瀏覽(52)
  • 【Go語言】Golang保姆級(jí)入門教程 Go初學(xué)者介紹chapter1

    【Go語言】Golang保姆級(jí)入門教程 Go初學(xué)者介紹chapter1

    Golang的學(xué)習(xí)方向 區(qū)塊鏈研發(fā)工程師: 去中心化 虛擬貨幣 金融 Go服務(wù)器端、游戲軟件工程師 : C C++ 處理日志 數(shù)據(jù)打包 文件系統(tǒng) 數(shù)據(jù)處理 很厲害 處理大并發(fā) Golang分布式、云計(jì)算軟件工程師:盛大云 cdn 京東 消息推送 分布式文件系統(tǒng) 2、Golang的應(yīng)用領(lǐng)域 區(qū)塊鏈應(yīng)用:區(qū)塊鏈

    2024年02月15日
    瀏覽(128)
  • 從C語言到C++:C++入門知識(shí)(2)

    從C語言到C++:C++入門知識(shí)(2)

    朋友們、伙計(jì)們,我們又見面了,本期來給大家解讀一下有關(guān)C++的基礎(chǔ)知識(shí)點(diǎn),如果看完之后對(duì)你有一定的啟發(fā),那么請(qǐng)留下你的三連,祝大家心想事成! C 語 言 專 欄: C語言:從入門到精通 數(shù)據(jù)結(jié)構(gòu)專欄: 數(shù)據(jù)結(jié)構(gòu) 個(gè)? 人? 主? 頁?: stackY、 目錄 前言: 1. 函數(shù)重載

    2024年02月08日
    瀏覽(57)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包