柚子快報(bào)激活碼778899分享:【C++】基礎(chǔ)入門(mén)(詳解)
? Hello,我是egoist2023!
? 種一棵樹(shù)最好是十年前,其次是現(xiàn)在!
目錄
輸入&輸出
缺省參數(shù)(默認(rèn)參數(shù))
函數(shù)重載
引用
概念及定義
特性及使用
const引用
與指針的關(guān)系
內(nèi)聯(lián)inline和nullptr
inline
nullptr
輸入&輸出
前文了解到本賈尼認(rèn)為C語(yǔ)言是有缺陷的,想彌補(bǔ)其缺陷,最后搞出自己的一套C++體系。其實(shí),C語(yǔ)言的scanf和printf函數(shù)是有缺陷且過(guò)于冗雜(每次都需要手動(dòng)指定格式),是否能通過(guò)一種方式使輸入輸出更簡(jiǎn)便呢?針對(duì)此問(wèn)題在C++中引入了輸入&輸出流。
#include
#include
int main()
{
int a = 1;
std::cout << a;
printf("%d", a);
return 0;
}
IO流涉及類(lèi)和對(duì)象,運(yùn)算符重載、繼承等很多面向?qū)ο蟮闹R(shí),因此在此章節(jié)只介紹IO流的用法。在vs編譯器中
#include
int main()
{
int a = 1;
std::cout << a;
printf("%d", a);
return 0;
}
缺省參數(shù)(默認(rèn)參數(shù))
缺省參數(shù)是聲明或定義函數(shù)時(shí)為函數(shù)的參數(shù)指定一個(gè)缺省值。在調(diào)用該函數(shù)時(shí),如果沒(méi)有指定實(shí)參則采用該形參的缺省值。
缺省參數(shù)分為全缺省(全部形參給缺省值)和半缺省參數(shù)(部分形參給缺省值)。C++規(guī)定半缺省參數(shù)必須從左往右依次連續(xù)缺省,不能間隔給缺省值。(同理依次給實(shí)參)函數(shù)聲明和定義分離時(shí),缺省參數(shù)不能在函數(shù)聲明和定義中同時(shí)出現(xiàn),規(guī)定必須函數(shù)聲明給缺省值。(這樣做的目的是避免沖突,因?yàn)榫幾g器在鏈接時(shí)會(huì)合成制表符,此時(shí),聲明和定義都有缺省值就會(huì)產(chǎn)生沖突)
缺省參數(shù)的意義遠(yuǎn)不止如此,在之前的棧和隊(duì)列章節(jié)中,棧的初始化中capacity默認(rèn)開(kāi)始為0。若一開(kāi)始明確插入1000個(gè)數(shù)據(jù)時(shí),初始化時(shí)直接開(kāi)好,避免多次擴(kuò)容損失效率。(沒(méi)有傳參時(shí)會(huì)采用缺省參數(shù)的值。)
函數(shù)重載
在C語(yǔ)言中若要實(shí)現(xiàn)Add函數(shù)(需要支持整形、浮點(diǎn)型相加)時(shí),需要保證Add函數(shù)名字不沖突,為了解決這一困擾。在C++中,添加了函數(shù)重載這個(gè)概念,其要求這些同名函數(shù)的形參不同,可以是參數(shù)個(gè)數(shù)不同或者類(lèi)型不同(不支持返回類(lèi)型不同),呈現(xiàn)多態(tài)行為,使用更加方便。函數(shù)支持三種類(lèi)型的重載。
函數(shù)重載是C++中實(shí)現(xiàn)多態(tài)性的一種重要方式,具有重要意義(增強(qiáng)了代碼的可讀性,函數(shù)的通用性和復(fù)用性),同時(shí)為之后的模板(函數(shù)重載的支持)、運(yùn)算符重載做了鋪墊。
參數(shù)類(lèi)型不同
int Add(int x, int y)
{
cout << "int Add(int x, int y)" << endl;
return x + y;
}
double Add(double x, double y)
{
cout << "double Add(double x, double y)" << endl;
return x + y;
}
參數(shù)個(gè)數(shù)不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
參數(shù)順序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
引用
概念及定義
引用是給已存在變量取一個(gè)別名,語(yǔ)法層面上編譯器不會(huì)為其開(kāi)辟內(nèi)存空間, 它和引用的變量共用同一塊內(nèi)存空間。(實(shí)際底層實(shí)現(xiàn)上開(kāi)辟了空間,是用一個(gè)指針指向其引用的變量)
通過(guò)調(diào)試可以知道:別名和引用的變量指向
共同占用一塊空間。
反匯編觀察
底層:a和b各自開(kāi)了一塊空間,b通過(guò)指針ptr指向了變量a
特性及使用
?
引用在定義時(shí)
必須初始化
?
支持多次引用
?
引用一個(gè)實(shí)體,其別名再不能引用其他實(shí)體
實(shí)踐中,引用傳參和引用做返回值中減少拷貝提高效率和改變引用對(duì)象時(shí)同時(shí)改變被引用對(duì)象。使用C++引用替代指針傳參,目的是簡(jiǎn)化程序,避開(kāi)復(fù)雜的指針。引用傳參和引用作返回值在實(shí)踐中經(jīng)常用到,達(dá)到了減少拷貝提高效率(指針也可以減少拷貝)和改變引用對(duì)象的目的。(針對(duì)自定義類(lèi)型更為明顯)
在指針章節(jié)中要求交換兩個(gè)變量,涉及到傳址調(diào)用(形參改變實(shí)參)。同樣,使用引用也可以達(dá)到此目的。
const引用
變量也有被const修飾的情況,此時(shí)對(duì)其進(jìn)行引用會(huì)報(bào)錯(cuò)(權(quán)限被放大了),因此需要引入 const引用。
權(quán)限要點(diǎn)? -- >? 權(quán)限可以平移或者縮小,但一定不能放大。
引用一個(gè)const對(duì)象,必須用const引用。const引用也可以引用普通對(duì)象,因?yàn)閷?duì)象的訪問(wèn)權(quán)限可以縮小,不能放大。
需要注意的是?int& rb = a*3; double d = 12.34; int& rd = d?這種場(chǎng)景下需要使用const引用
這里涉及到類(lèi)型轉(zhuǎn)換,將double轉(zhuǎn)換為int&為何需要使用const引用呢?
在類(lèi)型轉(zhuǎn)換中,會(huì)產(chǎn)生臨時(shí)對(duì)象(也稱(chēng)未命名對(duì)象),這個(gè)對(duì)象具有常性,此時(shí)rb和rd都是引用這個(gè)臨時(shí)變量,權(quán)限被放大了,因此會(huì)出現(xiàn)報(bào)錯(cuò)。
?臨時(shí)對(duì)象是編譯器需要一個(gè)空間暫存表達(dá)式的求值結(jié)果時(shí)臨時(shí)創(chuàng)建的一個(gè)未命名的對(duì)象。
與指針的關(guān)系
由上文可以發(fā)現(xiàn)引用與指針的部分功能是類(lèi)似的,那為什么本賈尼還引入了引用這個(gè)語(yǔ)法呢?
引?和指針在實(shí)踐中相輔相成,功能有重疊性,但是各有特點(diǎn),互相不可替代。如:C++引?定義后不能改變指向,相反地指針可以改變指向(鏈表章節(jié)中指針定義的結(jié)構(gòu)是不能用引用替代的)。
引用與指針的關(guān)系
引用指針語(yǔ)法上不開(kāi)空間要開(kāi)空間存儲(chǔ)變量地址必須初始化非必須初始化不能改變指向可以改變指向可以直接訪問(wèn)指向?qū)ο笮枰柚?訪問(wèn)指向?qū)ο笠媒Y(jié)果為引用類(lèi)型大小看32位/64位平臺(tái)\野指針和空指針問(wèn)題
內(nèi)聯(lián)inline和nullptr
inline
inline修飾的函數(shù)叫做內(nèi)聯(lián)函數(shù),編譯時(shí)C++編譯器會(huì)在調(diào)用的地方展開(kāi)內(nèi)聯(lián)函數(shù),這樣調(diào)用內(nèi)聯(lián)函數(shù)就需要建立棧幀了,就可以提高效率。
這個(gè)功能是和C語(yǔ)言中的define是類(lèi)似的,inline又有什么優(yōu)勢(shì)呢?
宏函數(shù)實(shí)現(xiàn)很復(fù)雜很容易出錯(cuò)的,且不方調(diào)試,C++設(shè)計(jì)了inline目的就是替代C的宏函數(shù)。
#define Add(x,y) ((x)+(y))
inline int Add(const int& x, const int& y) { ? ? return x + y; }
在實(shí)現(xiàn)Add函數(shù)中使用define宏定義時(shí)需要考慮各種因素,而使用inline則無(wú)需顧慮很多,讓編譯器決定是否展開(kāi)此函數(shù)。
inline對(duì)于編譯器是一個(gè)建議(選擇性展開(kāi)),適用于頻繁調(diào)用的短小函數(shù),對(duì)于遞歸函數(shù),代碼相對(duì)多一些的函數(shù),加上inline也會(huì)被編譯器忽略。
inline不建議聲明和定義分離到兩個(gè)文件
,分離會(huì)導(dǎo)致鏈接錯(cuò)誤。因?yàn)閕nline被展開(kāi),就沒(méi)有函數(shù)地址,鏈接時(shí)會(huì)出現(xiàn)報(bào)錯(cuò)(不能合成制表符)。
vs編譯器 debug版本下面默認(rèn)是不展開(kāi)inline的,因此需要設(shè)置下。
nullptr
引入nullptr實(shí)際是為了替代C語(yǔ)言的NULL(有缺陷)。
NULL實(shí)際是一個(gè)宏,在頭文件(stddef.h)中。
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
C++中NULL可能被定義為
常量0
,或者C中被定義為
無(wú)類(lèi)型指針(void*)
的常量。但都不可避免的會(huì)遇到一些麻煩。
nullptr(關(guān)鍵字)是?種特殊類(lèi)型的字面量,它可以轉(zhuǎn)換成任意其他類(lèi)型的指針類(lèi)型。使用
nullptr定義空指針可以避免類(lèi)型轉(zhuǎn)換
的問(wèn)題。(nullptr只能被隱式地轉(zhuǎn)換為指針類(lèi)型,而不能被轉(zhuǎn)換為整數(shù)類(lèi)型)
在此代碼中,本想通過(guò)f(NULL)調(diào)用函數(shù)f(int x),但運(yùn)行后發(fā)現(xiàn)調(diào)用的f(int x)函數(shù),與設(shè)計(jì)此程序是相違反的。
若NULL為無(wú)類(lèi)型指針(void*)呢?運(yùn)行后會(huì)報(bào)錯(cuò),這是因?yàn)?個(gè)函數(shù)重載中沒(méi)有一個(gè)能轉(zhuǎn)換所有參數(shù)類(lèi)型。
#include
using namespace std;
void f(int x)
{
cout << "f(int x)" << endl;
}
void f(int* ptr)
{
cout << "f(int* ptr)" << endl;
}
int main()
{
f(NULL);//調(diào)用f(int x)
f(nullptr);//調(diào)用f(int* ptr)
f((void*)0);//err
return 0;
}
柚子快報(bào)激活碼778899分享:【C++】基礎(chǔ)入門(mén)(詳解)
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。