??個人主頁:@Weraphael
???作者簡介:目前學(xué)習(xí)C++和算法
??專欄:C++航路
?? 希望大家多多支持,咱一起進步!??
如果文章對你有幫助的話
歡迎 評論?? 點贊???? 收藏 ?? 加關(guān)注?
前言
本章是補充C語言語法的不足,以及C++是如何對C語言設(shè)計不合理的地方進行優(yōu)化的。
一、auto關(guān)鍵字
1.1 問題引入
隨著程序越來越復(fù)雜,程序中用到的類型也越來越復(fù)雜,經(jīng)常體現(xiàn)在:
1. 類型難于拼寫(過長)
2. 含義不明確導(dǎo)致容易出錯
來看看以下代碼:
#include <iostream>
#include <string>
#include <map>
using namespace srd;
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;
}
以上代碼剛剛對于
C++
初學(xué)者可能看不懂,而std::map<std::string, std::string>::iterator
是一個類型還是看的出來的吧,但由于該類型太長了,寫的也累。所以有些人可能想:可以通過typedef
給這么長的類型取別名
例如:
#include <iostream>
#include <string>
#include <map>
using namespace std;
//重命名長類型
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
可以創(chuàng)建新的類型名稱,但可能會使代碼難以理解和維護。如果類型名稱太過簡略或不符合命名規(guī)范,會導(dǎo)致代碼的可讀性降低。- 可能會與其他定義沖突:由于
typedef
允許用戶創(chuàng)建新的類型名稱,因此可能會與其他定義發(fā)生沖突。這可以通過遵循命名規(guī)則和避免使用與其他名稱相同的名稱來避免。- 難以進行調(diào)試:由于
typedef
創(chuàng)建了新的類型名稱,因此調(diào)試時可能會難以確定變量的類型。這可以通過良好的代碼注釋和為類型名稱選擇有意義的名稱來避免。- 可能會導(dǎo)致錯誤:
typedef
也可以用于創(chuàng)建指向其他類型的指針或引用類型。如果不小心使用了錯誤的類型名稱,可能會導(dǎo)致程序錯誤。這可以通過在代碼中進行仔細的檢查和測試來避免。
因此,C++11給auto賦予了新的含義。
1.2 auto簡介
在早期auto的含義是:使用auto修飾的變量,是具有自動存儲器的局部變量,但遺憾的是它使用的一點也不頻繁。因此,C++11中,標準委員會賦予了auto全新的含義:auto不再是一個存儲類型指示符,而是作為一個新的類型指示符來指示編譯器,它可以通過賦值操作符右邊的表達式來推導(dǎo)出其類型。
typeid
可以打印變量類型
1.3 auto的使用細則
1. auto與指針和引用結(jié)合起來使用
用auto聲明指針類型時,用auto和auto*沒有任何區(qū)別
但用auto聲明引用類型時則必須加&
2. 在同一行定義多個變量
當在同一行聲明多個變量時,這些變量必須是相同的類型,否則編譯器將會報錯
第
96
行代碼會編譯失敗,因為c和d的初始化表達式類型不同。
1.4 常見auto不能推導(dǎo)的場景
1. auto不能作為函數(shù)的參數(shù)
此處代碼編譯失敗,auto不能作為形參類型,因為編譯器無法對a的實際類型進行推導(dǎo)
2. auto不能直接用來聲明數(shù)組
1.5 基于范圍的for循環(huán)(重點)
1.5.1 遍歷數(shù)組
- 普通方法遍歷數(shù)組
對于普通的遍歷,我們需要先求出數(shù)組大小。而對于
auto
遍歷,卻缺少了這一步,讓我們繼續(xù)往下看
- auto遍歷數(shù)組
for循環(huán)后的括號由冒號“ :”分為兩部分:第一部分是范圍內(nèi)用于迭代的變量,第二部分則表示被迭代的范圍。它本質(zhì)的意思是:依次取數(shù)組
arr
中的元素賦值給e
1.5.2 用auto修改數(shù)組元素
對于auto修改數(shù)組元素,要運用到引用,相當于對
arr
取別名
1.6 范圍for的使用條件
1. for
循環(huán)迭代的范圍必須是確定的
2. 迭代的對象要實現(xiàn)++和==的操作
二、 指針空值nullptr
在良好的C/C++編程習(xí)慣中,聲明一個變量時最好給該變量一個合適的初始值,否則可能會出現(xiàn)不可預(yù)料的錯誤,比如未初始化的指針。如果一個指針沒有合法的指向,我們基本都是按照如下方式對其進行初始化:
#include <iostream>
#include <stddef.h>
using namespace std;
int main()
{
int* p = NULL;
int* pp = 0;
return 0;
}
NULL
實際是一個宏,在傳統(tǒng)的C頭文件(stddef.h)中,我們通過查詢cplusplus網(wǎng)站來查看其屬性
可以看到,
NULL
可能被定義為字面常量0,或者被定義為無類型指針(void*)的常量。不論采取何種定義,在使用空值的指針時,都不可避免的會遇到一些麻煩,比如:文章來源:http://www.zghlxwxcb.cn/news/detail-440645.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-440645.html
- 程序本意是想通過
NULL
調(diào)用指針版本的f(int*)
函數(shù),但是由于NULL
被定義成0
,因此與程序的初衷相悖。- 這是因為在C++98中,字面常量0既可以是一個整形數(shù)字,也可以是無類型的指針(void*)常量,但是編譯器默認情況下將其看成是一個整形常量,如果要將其按照指針方式來使用,必須對其進行強轉(zhuǎn)
(void*)NULL
。
但C++11
引入了nullptr
,因此可以不用強轉(zhuǎn)NULL
但需要注意的是:
- 在使用nullptr表示指針空值時,不需要包含頭文件,因為nullptr是C++11作為新關(guān)鍵字引入的。
- 在C++11中,sizeof(nullptr) 與 sizeof((void*)0)所占的字節(jié)數(shù)相同。
- 為了提高代碼的健壯性,在后續(xù)表示指針空值時建議最好使用nullptr。
到了這里,關(guān)于【C++入門】auto關(guān)鍵字(C++11) + 指針空值nullptr(C++11)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!