一文詳解C++關(guān)鍵詞auto的用法
一、小思考
隨著我們對(duì)于C++的不斷學(xué)習(xí),遇到的程序越來(lái)越復(fù)雜,程序中用到的類(lèi)型也越來(lái)越復(fù)雜,經(jīng)常體現(xiàn)在:
1.類(lèi)型難于拼寫(xiě)
2.含義不明確導(dǎo)致容易出錯(cuò)
舉個(gè)栗子來(lái)說(shuō):
#include <string>
#include <map>
int main()
{
std::map<std::string, std::string> m{ { "apple", "蘋(píng)果" }, { "orange", "橙子" },{"pear","梨"} };
std::map<std::string, std::string>::iterator it = m.begin();
while (it != m.end())
{
//....
}
return 0;
}std::map<std::string, std::string>::iterator 是一個(gè)類(lèi)型,但是該類(lèi)型太長(zhǎng)了,特別容易寫(xiě)錯(cuò)。 聰明的同學(xué)可能已經(jīng)想到:可以通過(guò)typedef給類(lèi)型取別名,比如:
#include <string>
#include <map>
typedef std::map<std::string, std::string> Map;
int main()
{
Map m{ { "apple", "蘋(píng)果" },{ "orange", "橙子" }, {"pear","梨"} };
Map::iterator it = m.begin();
while (it != m.end())
{
//....
}
return 0;
}使用typedef給類(lèi)型取別名確實(shí)可以簡(jiǎn)化代碼,但是typedef有會(huì)遇到新的難題:
typedef char* pstring;
int main()
{
const pstring p1; // 編譯成功還是失?。?
const pstring* p2; // 編譯成功還是失???
return 0;
}在編程時(shí),常常需要把表達(dá)式的值賦值給變量,這就要求在聲明變量的時(shí)候清楚地知道表達(dá)式的類(lèi)型。然而有時(shí)候要做到這點(diǎn)并非那么容易,因此C++11給auto賦予了新的含義。
二、auto簡(jiǎn)介
在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動(dòng)存儲(chǔ)器的局部變量,但遺憾的是一直沒(méi)有人去使用它,大家可思考下為什么?
C++11中,標(biāo)準(zhǔn)委員會(huì)賦予了auto全新的含義即:auto不再是一個(gè)存儲(chǔ)類(lèi)型指示符,而是作為一個(gè)新的類(lèi)型指示符來(lái)指示編譯器,auto聲明的變量必須由編譯器在編譯時(shí)期推導(dǎo)而得。
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; 無(wú)法通過(guò)編譯,使用auto定義變量時(shí)必須對(duì)其進(jìn)行初始化
return 0;
}
由上圖可知,auto會(huì)自動(dòng)給變量定義類(lèi)型。
注意:
使用auto定義變量時(shí)必須對(duì)其進(jìn)行初始化,在編譯階段編譯器需要根據(jù)初始化表達(dá)式來(lái)推導(dǎo)auto的實(shí)際類(lèi)型。因此auto并非是一種"類(lèi)型"的聲明,而是一個(gè)類(lèi)型聲明時(shí)的"占位符”,編譯器在編譯期會(huì)將auto替換為變量實(shí)際的類(lèi)型。
三、auto使用規(guī)則
1.auto與指針和引用結(jié)合起來(lái)使用
用auto聲明指針類(lèi)型時(shí),用auto和auto*沒(méi)有任何區(qū)別,但用auto聲明引用類(lèi)型時(shí)則必須加&
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;
*a = 20;
*b = 30;
c = 40;
return 0;
}如圖所示:

不加&的情況,大家可以自行練習(xí)。如果不加&,不會(huì)引用成功。
2.在同一行定義多個(gè)變量
當(dāng)在同一行聲明多個(gè)變量時(shí),這些變量必須是相同的類(lèi)型,否則編譯器將會(huì)報(bào)錯(cuò),因?yàn)榫幾g器實(shí)際只對(duì)第一個(gè)類(lèi)型進(jìn)行推導(dǎo),然后用推導(dǎo)出來(lái)的類(lèi)型定義其他變量。
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0; // 該行代碼會(huì)編譯失敗,因?yàn)閏和d的初始化表達(dá)式類(lèi)型不同
}四、auto不能推導(dǎo)的場(chǎng)景
1.auto不能作為函數(shù)的參數(shù)
// 此處代碼編譯失敗,auto不能作為形參類(lèi)型,因?yàn)榫幾g器無(wú)法對(duì)a的實(shí)際類(lèi)型進(jìn)行推導(dǎo)
void TestAuto(auto a)
{}2. auto不能直接用來(lái)聲明數(shù)組
void TestAuto()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};
}3.為了避免與C++98中的auto發(fā)生混淆,C++11只保留了auto作為類(lèi)型指示符的用法
4. auto在實(shí)際中最常見(jiàn)的優(yōu)勢(shì)用法就是跟以后會(huì)講到的C++11提供的新式for循環(huán),還有l(wèi)ambda表達(dá)式等進(jìn)行配合使用。
五、基于范圍的for循環(huán)(附帶內(nèi)容)
1.范圍for的語(yǔ)法
在C++98中如果要遍歷一個(gè)數(shù)組,可以按照以下方式進(jìn)行:
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
array[i] *= 2;
for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)
cout << *p << endl;
}對(duì)于一個(gè)有范圍的集合而言,由程序員來(lái)說(shuō)明循環(huán)的范圍是多余的,有時(shí)候還會(huì)容易犯錯(cuò)誤。因此C++11中引入了基于范圍的for循環(huán)。for循環(huán)后的括號(hào)由冒號(hào)“ :”分為兩部分:第一部分是范圍內(nèi)用于迭代的變量,第二部分則表示被迭代的范圍。
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
for(auto& e : array)
e *= 2;
for(auto e : array)
cout << e << " ";
return 0;
}注意:與普通循環(huán)類(lèi)似,可以用continue來(lái)結(jié)束本次循環(huán),也可以用break來(lái)跳出整個(gè)循環(huán)。
2.范圍for的使用條件
1)for循環(huán)迭代的范圍必須是確定的
對(duì)于數(shù)組而言,就是數(shù)組中第一個(gè)元素和最后一個(gè)元素的范圍;對(duì)于類(lèi)而言,應(yīng)該提供begin和end的方法,begin和end就是for循環(huán)迭代的范圍。
注意:以下代碼就有問(wèn)題,因?yàn)閒or的范圍不確定
void TestFor(int array[])
{
for(auto& e : array)
cout<< e <<endl;
}2)迭代的對(duì)象要實(shí)現(xiàn)++和==的操作
總結(jié)
到此這篇關(guān)于一文詳解C++關(guān)鍵詞auto的用法的文章就介紹到這了,更多相關(guān)C++關(guān)鍵詞auto內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++中vector<vector<int>?>的基本使用方法
vector<vector<int>?>其實(shí)就是容器嵌套容器,外層容器的元素類(lèi)型是vector<int>,下面這篇文章主要給大家介紹了關(guān)于C++中vector<vector<int>?>的基本使用方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
C++ 線(xiàn)程互斥鎖 lock_guard的基本用法
std::lock_guard是C++11提供的RAII風(fēng)格互斥鎖封裝類(lèi),自動(dòng)管理互斥鎖的加鎖/解鎖,避免忘記解鎖和異常導(dǎo)致的鎖無(wú)法釋放等問(wèn)題,它通過(guò)構(gòu)造時(shí)加鎖、析構(gòu)時(shí)解鎖的機(jī)制,簡(jiǎn)化了多線(xiàn)程編程中的鎖管理,本文介紹C++線(xiàn)程互斥鎖lock_guard的基本用法,感興趣的朋友一起看看吧2026-01-01
C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)字符串分割的實(shí)例
這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)字符串分割的實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10
C++中putchar與getchar函數(shù)的細(xì)節(jié)及運(yùn)用
C語(yǔ)言提供putchar函數(shù),用于給終端輸出一個(gè)字符;getchar函數(shù),可以從終端接收用戶(hù)輸入的一個(gè)字符,本文給大家分享C++中putchar與getchar函數(shù)的細(xì)節(jié)及運(yùn)用,感興趣的朋友跟隨小編一起看看吧2021-07-07
C++中priority_queue模擬實(shí)現(xiàn)
本文主要介紹了C++中priority_queue模擬實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2026-04-04
Qt重復(fù)添加控件問(wèn)題的現(xiàn)象、原理與解決方案
本文分析了Qt開(kāi)發(fā)中重復(fù)添加控件導(dǎo)致的常見(jiàn)問(wèn)題,包括界面重疊、內(nèi)存泄漏和信號(hào)混亂,通過(guò)剖析Q時(shí)象樹(shù)管理機(jī)制,揭示了問(wèn)題根源在于父子關(guān)系管理失效,并提出了三種解決方案,需要的朋友可以參考下2026-01-01
C++類(lèi)重載函數(shù)的function和bind使用示例
這篇文章主要介紹了C++類(lèi)重載函數(shù)的function和bind使用示例,幫助大家更好的理解和使用c++,感興趣的朋友可以了解下2021-01-01
C語(yǔ)言循環(huán)隊(duì)列與用隊(duì)列實(shí)現(xiàn)棧問(wèn)題解析
循環(huán)隊(duì)列又叫環(huán)形隊(duì)列,是一種特殊的隊(duì)列。循環(huán)隊(duì)列解決了隊(duì)列出隊(duì)時(shí)需要將所有數(shù)據(jù)前移一位的問(wèn)題,本篇帶你一起看看循環(huán)隊(duì)列的問(wèn)題和怎樣用隊(duì)列實(shí)現(xiàn)棧2022-04-04

