一文詳解C++關鍵詞auto的用法
一、小思考
隨著我們對于C++的不斷學習,遇到的程序越來越復雜,程序中用到的類型也越來越復雜,經(jīng)常體現(xiàn)在:
1.類型難于拼寫
2.含義不明確導致容易出錯
舉個栗子來說:
#include <string> #include <map> int main() { std::map<std::string, std::string> m{ { "apple", "蘋果" }, { "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 是一個類型,但是該類型太長了,特別容易寫錯。 聰明的同學可能已經(jīng)想到:可以通過typedef給類型取別名,比如:
#include <string> #include <map> typedef std::map<std::string, std::string> Map; int main() { Map m{ { "apple", "蘋果" },{ "orange", "橙子" }, {"pear","梨"} }; Map::iterator it = m.begin(); while (it != m.end()) { //.... } return 0; }
使用typedef給類型取別名確實可以簡化代碼,但是typedef有會遇到新的難題:
typedef char* pstring; int main() { const pstring p1; // 編譯成功還是失?。? const pstring* p2; // 編譯成功還是失?。? return 0; }
在編程時,常常需要把表達式的值賦值給變量,這就要求在聲明變量的時候清楚地知道表達式的類型。然而有時候要做到這點并非那么容易,因此C++11給auto賦予了新的含義。
二、auto簡介
在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動存儲器的局部變量,但遺憾的是一直沒有人去使用它,大家可思考下為什么?
C++11中,標準委員會賦予了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; }
由上圖可知,auto會自動給變量定義類型。
注意:
使用auto定義變量時必須對其進行初始化,在編譯階段編譯器需要根據(jù)初始化表達式來推導auto的實際類型。因此auto并非是一種"類型"的聲明,而是一個類型聲明時的"占位符”,編譯器在編譯期會將auto替換為變量實際的類型。
三、auto使用規(guī)則
1.auto與指針和引用結合起來使用
用auto聲明指針類型時,用auto和auto*沒有任何區(qū)別,但用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; *a = 20; *b = 30; c = 40; return 0; }
如圖所示:
不加&的情況,大家可以自行練習。如果不加&,不會引用成功。
2.在同一行定義多個變量
當在同一行聲明多個變量時,這些變量必須是相同的類型,否則編譯器將會報錯,因為編譯器實際只對第一個類型進行推導,然后用推導出來的類型定義其他變量。
void TestAuto() { auto a = 1, b = 2; auto c = 3, d = 4.0; // 該行代碼會編譯失敗,因為c和d的初始化表達式類型不同 }
四、auto不能推導的場景
1.auto不能作為函數(shù)的參數(shù)
// 此處代碼編譯失敗,auto不能作為形參類型,因為編譯器無法對a的實際類型進行推導 void TestAuto(auto a) {}
2. auto不能直接用來聲明數(shù)組
void TestAuto() { int a[] = {1,2,3}; auto b[] = {4,5,6}; }
3.為了避免與C++98中的auto發(fā)生混淆,C++11只保留了auto作為類型指示符的用法
4. auto在實際中最常見的優(yōu)勢用法就是跟以后會講到的C++11提供的新式for循環(huán),還有l(wèi)ambda表達式等進行配合使用。
五、基于范圍的for循環(huán)(附帶內(nèi)容)
1.范圍for的語法
在C++98中如果要遍歷一個數(shù)組,可以按照以下方式進行:
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; }
對于一個有范圍的集合而言,由程序員來說明循環(huán)的范圍是多余的,有時候還會容易犯錯誤。因此C++11中引入了基于范圍的for循環(huán)。for循環(huán)后的括號由冒號“ :”分為兩部分:第一部分是范圍內(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)類似,可以用continue來結束本次循環(huán),也可以用break來跳出整個循環(huán)。
2.范圍for的使用條件
1)for循環(huán)迭代的范圍必須是確定的
對于數(shù)組而言,就是數(shù)組中第一個元素和最后一個元素的范圍;對于類而言,應該提供begin和end的方法,begin和end就是for循環(huán)迭代的范圍。
注意:以下代碼就有問題,因為for的范圍不確定
void TestFor(int array[]) { for(auto& e : array) cout<< e <<endl; }
2)迭代的對象要實現(xiàn)++和==的操作
總結
到此這篇關于一文詳解C++關鍵詞auto的用法的文章就介紹到這了,更多相關C++關鍵詞auto內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言中的pause()函數(shù)和alarm()函數(shù)以及sleep()函數(shù)
這篇文章主要介紹了C語言中的pause()函數(shù)和alarm()函數(shù)以及sleep()函數(shù),是C語言入門學習中的基礎知識,需要的朋友可以參考下2015-09-09