網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
一. auto關(guān)鍵字
1. auto介紹
在早期C/C++中auto的含義是:使用auto修飾的變量,是具有自動(dòng)存儲(chǔ)器的局部變量。
但是在C++11開始,賦予了auto全新的含義即:auto不再是一個(gè)存儲(chǔ)類型指示符,而是作為一個(gè)新的類型指示符來(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;
return 0;
}
注意:
使用auto定義變量時(shí)必須對(duì)其進(jìn)行初始化,在編譯階段編譯器需要根據(jù)初始化表達(dá)式來(lái)推導(dǎo)auto的實(shí)際類型。因此auto并非是一種“類型”的聲明,而是一個(gè)類型聲明時(shí)的“占位符”,編譯器在編譯期會(huì)將auto替換為變量實(shí)際的類型(自定義類型也可以)。
auto a; 無(wú)法通過(guò)編譯,使用auto定義變量時(shí)必須對(duì)其進(jìn)行初始化
2. 使用規(guī)則
(1)auto與指針和引用結(jié)合起來(lái)使用
用auto聲明指針類型時(shí),用auto和auto*沒(méi)有任何區(qū)別,但用auto聲明引用類型時(shí)則必須加&
int main()
{
int x = 10;
const int y = 20;
//推斷沒(méi)有帶解引用操作符的整形指針
auto a = &x;
auto a2 = &y;
//推斷帶解引用操作符的整形指針
auto* b = &x;
//auto* b = x;//注意別寫成這樣,左邊推導(dǎo)一定是指針,x是整形,這樣是會(huì)報(bào)錯(cuò)的
auto* b2 = &y;
//推斷引用類型
auto& c = x;
auto& c2 = y;
//打印類型
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << typeid(a2).name() << endl;
cout << typeid(b2).name() << endl;
cout << typeid(c2).name() << endl;
return 0;
}
這里發(fā)現(xiàn)了一個(gè)問(wèn)題,我們用const修飾了y,但是推導(dǎo)出來(lái)的引用類型居然沒(méi)有被const修飾,但是我們?cè)趯懘a的時(shí)候不加const編譯器一定會(huì)報(bào)錯(cuò),要注意這里的這個(gè)問(wèn)題
(2)在同一行定義多個(gè)變量
當(dāng)在同一行聲明多個(gè)變量時(shí),這些變量必須是相同的類型,否則編譯器將會(huì)報(bào)錯(cuò),因?yàn)榫幾g器實(shí)際只對(duì)第一個(gè)類型進(jìn)行推導(dǎo),然后用推導(dǎo)出來(lái)的類型定義其他變量。
void TestAuto()
{
auto a = 1, b = 2;
auto c = 3, d = 4.0; // 該行代碼會(huì)編譯失敗,因?yàn)閏和d的初始化表達(dá)式類型不同
}
3. auto不能推導(dǎo)的場(chǎng)景
auto不能作為函數(shù)的參數(shù)和返回值
// 此處代碼編譯失敗,auto不能作為形參類型,因?yàn)榫幾g器無(wú)法對(duì)a的實(shí)際類型進(jìn)行推導(dǎo)
void TestAuto(auto a)
{}
//不然接收和傳參不知道怎么傳參和接收
auto TestAuto(int a)
{}
auto不能直接用來(lái)聲明數(shù)組
void TestAuto()
{
int a[] = {1,2,3};
auto b[] = {4,5,6};
}
為了避免與C++98中的auto發(fā)生混淆,C++11只保留了auto作為類型指示符的用法
auto在實(shí)際中最常見(jiàn)的優(yōu)勢(shì)用法就是跟以后會(huì)講到的C++11提供的新式for循環(huán),還有l(wèi)ambda表達(dá)式等進(jìn)行配合使用。
二. 基于范圍的for循環(huán)(C++11)
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()
{
//依次自動(dòng)取array中的數(shù)據(jù)賦值給e,自動(dòng)判斷結(jié)束
int array[] = { 1, 2, 3, 4, 5 };
for(auto& e : array)
e *= 2;
for(auto e : array)
cout << e << " ";
}
注意:與普通循環(huán)類似,可以用continue來(lái)結(jié)束本次循環(huán),也可以用break來(lái)跳出整個(gè)循環(huán)。
2. 范圍for的使用條件
(1)for循環(huán)迭代的范圍必須是確定的
對(duì)于數(shù)組而言,就是數(shù)組中第一個(gè)元素和最后一個(gè)元素的范圍;對(duì)于類而言,應(yīng)該提供begin和end的方法,begin和end就是for循環(huán)迭代的范圍。
以下代碼就有問(wèn)題,因?yàn)閒or的范圍不確定:
(數(shù)組傳參,數(shù)組會(huì)退化成指針,所以這里接受的是指針,就導(dǎo)致了范圍是不確定的)
void TestFor(int array[])
{
for(auto& e : array)
cout<< e <<endl;
}
(2)迭代的對(duì)象要實(shí)現(xiàn)++和==的操作
三. 指針空值nullptr(C++11)
C++98中的指針空值,在C/C++中,聲明一個(gè)變量時(shí)最好給該變量一個(gè)合適的初始值,否則可能會(huì)出現(xiàn)不可預(yù)料的錯(cuò)誤,比如未初始化的指針。如果一個(gè)指針沒(méi)有合法的指向,我們基本都是按照如下方式對(duì)其進(jìn)行初始化:
void TestPtr()
{
int* p1 = NULL;
int* p2 = 0;
}
但是,這里的NULL實(shí)際是一個(gè)宏,在傳統(tǒng)的C頭文件(stddef.h)中,可以看到如下代碼:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
可以看到,NULL可能被定義為字面常量0,或者被定義為無(wú)類型指針(void*)的常量。但是不論采取何種定義,在使用空值的指針時(shí),都不可避免的會(huì)遇到一些麻煩,比如:
void fun(int)
{
cout<<"fun(int)"<<endl;
}
void fun(int*)
{
cout<<"fun(int*)"<<endl;
}
int main()
{
fun(0);
fun(NULL);
fun((int*)NULL);
return 0;
}
程序本意是想通過(guò)fun(NULL)調(diào)用指針版本的fun(int*)函數(shù),但是由于NULL被定義成0,因此與程序的初衷相悖。 在C++98中,字面常量0既可以是一個(gè)整形數(shù)字,也可以是無(wú)類型的指針(void*)常量,但是編譯器默認(rèn)情況下將其看成是一個(gè)整形常量,如果要將其按照指針?lè)绞絹?lái)使用,必須對(duì)其進(jìn)行強(qiáng)轉(zhuǎn)(void *)0。
注意:
- 在使用nullptr表示指針空值時(shí),不需要包含頭文件,因?yàn)閚ullptr是C++11作為新關(guān)鍵字引入的。
- 在C++11中,sizeof(nullptr) 與 sizeof((void*)0)所占的字節(jié)數(shù)相同。
- 為了提高代碼的健壯性,在后續(xù)表示指針空值時(shí)建議最好使用nullptr。
原文鏈接:https://blog.csdn.net/Britney_dark/article/details/124781144
相關(guān)推薦
- 2023-07-16 uniapp 小程序訂閱消息報(bào)錯(cuò)( wx.requestSubscribeMessage is no
- 2022-02-01 通過(guò)url路徑下載服務(wù)器文件
- 2022-12-27 pytorch?K折交叉驗(yàn)證過(guò)程說(shuō)明及實(shí)現(xiàn)方式_python
- 2022-09-03 ASP.NET中Response.BufferOutput屬性的使用技巧_實(shí)用技巧
- 2022-12-26 python使用Pyinstaller如何打包整個(gè)項(xiàng)目_python
- 2022-11-15 python列表中常見(jiàn)的一些排序方法_python
- 2022-09-03 ASP.NET實(shí)現(xiàn)Repeater控件的數(shù)據(jù)綁定_基礎(chǔ)知識(shí)
- 2024-03-06 SpringAOP基于注解方式實(shí)現(xiàn)和細(xì)節(jié)
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支