??????????????????????????????????????食用指南:本文在有C基礎(chǔ)的情況下食用更佳
????????????????????????????????????????這就不得不推薦此專欄了:C語言
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ????內(nèi)聯(lián)函數(shù)前置知識(shí):宏函數(shù)
????????????????????????????????????????今日夜電波:Episode 33—She Her Her Hers
? ? ? ? ? ? ? ? ??????????????????????? ? ? ? ? ? ? ? ? ? ? ? ?1:11?━━━━━━???──────── 4:17
?????????????????????????????????? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??? ? ?? ? ? ? ?? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???關(guān)注??點(diǎn)贊??收藏您的每一次鼓勵(lì)都是對(duì)我莫大的支持??
一、C++中的const
????????C語言中的const
????????1、const修飾全局變量num 變量名只讀 內(nèi)存空間在文字常量區(qū)(只讀)、不能通過num的地址修改空間內(nèi)容。
????????2、const修飾局部變量data 變量名只讀 內(nèi)存空間棧區(qū)(可讀可寫),可以通過data地址 間接的修改空間內(nèi)容。
? ? ? ? 栗子:
extern const int num;//用于外部其他文件num的聲明
const int sum = 100;//只讀的全局變量 內(nèi)存放在文字常量區(qū)(內(nèi)存空間只讀)
void text()
{
const int dat = 100;//局部只讀變量 內(nèi)存在棧區(qū)(內(nèi)存可讀可寫)
//內(nèi)存可讀可寫的例子:
int* p = (int*) & dat;
*p = 200;//此處就將dat修改為200
}
? ? ? ? C++中的const
? ? ? ? 首先,我們先理解一個(gè)符號(hào)表的概念,符號(hào)表是一個(gè)用于存儲(chǔ)程序中所有變量、函數(shù)和其他標(biāo)識(shí)符信息的數(shù)據(jù)結(jié)構(gòu)。它包含了每個(gè)標(biāo)識(shí)符的名稱、類型、作用域和存儲(chǔ)位置等信息。他在編譯和鏈接過程中起到了關(guān)鍵的作用。
? ? ? ? 而我們?cè)贑++中使用const定義變量時(shí),這個(gè)變量可以看成是一個(gè)常量,如果他是一個(gè)基礎(chǔ)的類型,系統(tǒng)不會(huì)給他開辟空間而是會(huì)把先放入到符號(hào)表當(dāng)中,在對(duì)這個(gè)數(shù)據(jù)取地址時(shí),系統(tǒng)才會(huì)給他開辟空間。是不是很繞口?請(qǐng)看下面這個(gè)圖你就明白了。
?????????對(duì)此,你對(duì)const定義的基礎(chǔ)類型存放有了一定的了解,請(qǐng)繼續(xù)看下面這個(gè)例子!
//1、c++中 對(duì)于基礎(chǔ)類型 系統(tǒng)不會(huì)給dat開辟空間 dat放到符號(hào)表中
const int dat = 10;
//dat = 100;//err 只讀
cout << "dat = " << dat << endl;
//2、c++中當(dāng) 對(duì)dat 取地址的時(shí)候 系統(tǒng)就會(huì)給dat開辟空間
int* p = (int*)&dat;
*p = 200;
cout << "*p = " << *p << endl;//空間內(nèi)容修改成功 200
cout << "dat = " << dat << endl;//data 還是10為啥?
????????很明顯的看到,正如上面所寫道的,改變*p并不會(huì)改變dat的值,改變的是所開辟的空間內(nèi)存的值!
? ? ? ? 注意:上面所述都是在const修飾為基礎(chǔ)類型的情況下的!
????????那在其他情況下又會(huì)如何呢?
? ? ? ? 在C++中,當(dāng) 以變量的形式 初始化 const修飾的變量 系統(tǒng)會(huì)為其開辟空間 或者 自定義數(shù)據(jù)類型(結(jié)構(gòu)體、對(duì)象)? 系統(tǒng)會(huì)分配空間!
? ? ? ? 栗子:
struct Person
{
int num;
char name[32];
};
void test4()
{
//3、當(dāng)以變量的形式 初始化 const修飾的變量 系統(tǒng)會(huì)為其開辟空間
int b = 200;
const int a = b;//系統(tǒng)直接為a開辟空間 而不會(huì)把a(bǔ)放入符號(hào)表中
int *p = (int*)&a;
* p = 3000;
cout << "*p = " << *p << endl;//3000
cout << "a = " << a << endl;//3000
//4、const 自定義數(shù)據(jù)類型(結(jié)構(gòu)體、對(duì)象) 系統(tǒng)會(huì)分配空間
const Person per = { 100,"lucy" };
//per.num = 1000;//err
cout << "num = " << per.num << ", name = " << per.name << endl;//100 lucy
Person * p1 = (Person*)&per;
p1-> num = 2000;
cout << "num = " << per.num << ", name = " << per.name << endl;//2000 lucy
}
二、引用?
????????什么是引用?
????????引用可以用于訪問已存在的變量或?qū)ο?。通過引用,可以通過不同的名稱訪問同一個(gè)變量,而不是創(chuàng)建副本。引用通常用于函數(shù)參數(shù)傳遞和函數(shù)返回值。說白了就是給已有變量取個(gè)別名。
? ? ? ? 引用的結(jié)構(gòu):
????????&和別名 結(jié)合 表示引用
? ? ? ? ?一個(gè)簡單的栗子:
int num = 10;
int &a = num;
????????注意:這里的&不是表示取地址,而是引用的標(biāo)志。
????????幾個(gè)需要注意的規(guī)則:
????????????????1、給某個(gè)變量取別名 就定義某個(gè)變量
????????????????2、從上往下替換
????????????????3、引用必須初始化
? ? ? ? ? ??????4、引用一旦初始化 就不能再次修改別名
? ? ? ??栗子:
void test5()
{
int a = 20;
int& b = a;
cout << "a=" << a << endl;
b = 200;
cout << "b= " << b << endl;
cout << "a地址:" << &a << endl;
cout << "b地址:" << &b << endl;
}
????????????????????????
? ? ? ? 由此可見a就是b,b就是a,b只不過是a的另外一個(gè)名字。?
引用的定義模板(如有錯(cuò)誤,請(qǐng)?zhí)咭荒_作者)
要取別名的類型( &(原來變量名的位置,直接替換別名))巴拉巴拉 = 要取別名的變量
????????引用-數(shù)組
void test6()
{
int arr[5] = {10,20,30,40,50};
//需求:給arr起個(gè)別名
int (&my_arr)[5] = arr;//my_arr就是數(shù)組arr的別名
int i=0;
for(i=0;i<5;i++)
{
cout<<my_arr[i]<<" ";
}
cout<<endl;
}
?引用在函數(shù)中的應(yīng)用
????????作為參數(shù)
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void swap2(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
void test7()
{
int n1 = 114, n2 = 514;
//swap(&n1, &n2);
swap2(n1, n2);//swap==swap2
cout << "n1=" << n1 << " n2=" << n2 << endl;//n1=514 n2=114
}
? ? ? ? 作為返回值
//引用作為函數(shù)的返回值類型
int& my_data(void)
{
int num = 100;
return num;//err 函數(shù)返回啥變量 引用就是該變量的別名
//函數(shù)的返回值是引用時(shí) 不要返回局部變量
}
int& my_data1(void)
{
static int num = 200;
return num;//ok
}
void test8()
{
//ret是別名 ret是num的別名
int &ret = my_data();
//cout<<"ret = "<<ret<<endl;//非法訪問內(nèi)存
int &ret1 = my_data1();//ret1是num的別名
cout<<"ret = "<<ret1<<endl;
}
????????注意:函數(shù)返回值作為左值 那么函數(shù)的返回值類型必須是引用
常引用
? ? ? ? ->常量的引用
void test9()
{
//給常量10取個(gè)別名 叫num
//int &針對(duì)的是int ,10是const int類型
//const int 針對(duì)的是const int, 10是const int類型
const int &num = 10;
cout<<"num = "<<num<<endl;//10
}
引用的本質(zhì)?
????????引用的本質(zhì)在 c++內(nèi)部實(shí)現(xiàn)是一個(gè)指針常量。
????????Type& ref = val; // Type* const ref =&val;
????????c++編譯器在編譯過程中使用常指針作為引用的內(nèi)部實(shí)現(xiàn), 因此引用所占用的空間
大小與指針相同, 只是這個(gè)過程是編譯器內(nèi)部實(shí)現(xiàn), 用戶不可見。
三、內(nèi)聯(lián)函數(shù)
???????????內(nèi)聯(lián)函數(shù)前置知識(shí):宏函數(shù)
????????宏函數(shù)(帶參數(shù)的宏)的缺點(diǎn):
????????第一個(gè)在c中也會(huì)出現(xiàn),宏看起來像一個(gè)函數(shù)調(diào)用,但是會(huì)有隱藏一些難以發(fā)現(xiàn)的錯(cuò)誤。
第二個(gè)問題是c++特有的,預(yù)處理器不允許訪問類的成員,也就是說預(yù)處理器宏不能用作類
的成員函數(shù)。
????????內(nèi)聯(lián)函數(shù):
????????內(nèi)聯(lián)函數(shù)為了繼承宏函數(shù)的效率,沒有函數(shù)調(diào)用時(shí)開銷,然后又可以像普通函數(shù)那樣,可以進(jìn)行參數(shù),返回值類型的安全檢查,又可以作為成員函數(shù)。內(nèi)聯(lián)函數(shù)是一個(gè)真正的函數(shù)。函數(shù)的替換 發(fā)生在編譯階段。
????????任何在類內(nèi)部定義的函數(shù)自動(dòng)成為內(nèi)聯(lián)函數(shù)。
????????注意:內(nèi)聯(lián)僅僅只是給編譯器一個(gè)建議, 編譯器不一定會(huì)接受這種建議, 如果你沒有將函
數(shù)聲明為內(nèi)聯(lián)函數(shù), 那么編譯器也可能將此函數(shù)做內(nèi)聯(lián)編譯。 一個(gè)好的編譯器將會(huì)
內(nèi)聯(lián)小的、 簡單的函數(shù)。
? ? ? ? 總的來說:內(nèi)聯(lián)函數(shù)是宏函數(shù)的優(yōu)化!
????????栗子:
#define SUB(x,y) x-y
inline int sub(int x, int y) {
return x - y;
}
void test10()
{
cout << "(define)x-y= " << SUB(5, 1) << endl;//(define)x-y= 4
cout << "(inline)x-y= " << sub(5, 1) << endl;//(inline)x-y= 4
}
? ? ? ? 這樣看起來內(nèi)聯(lián)函數(shù)是不是同宏函數(shù)一模一樣呢?請(qǐng)看下面這個(gè)例子:
#define MUT(x,y) x*y
inline int mut(int x, int y) {
return x * y;
}
void test10()
{
cout << "(define)x-y= " << MUT(5-2, 2) << endl;// 5-2*2
cout << "(inline)x-y= " << mut(5-2, 2) << endl;// 3*2
}
? ? ? ? 實(shí)際上,我們是可以將內(nèi)聯(lián)函數(shù)看作普通的函數(shù)的,但是內(nèi)聯(lián)函數(shù)有以下幾個(gè)限制條件:
?
不能是內(nèi)聯(lián)函數(shù)的情況
????????1、?函數(shù)包含靜態(tài)變量。
????????2、for、while帶有循環(huán)形式的函數(shù)。
????????3.、遞歸調(diào)用本身的函數(shù)。
????????4、包含復(fù)雜語句的函數(shù)。
? ? ? ? 5、函數(shù)體不能過于龐大 不能對(duì)函數(shù)進(jìn)行取址操作
? ? ? ? 6、不能存在過多的條件判斷語句。
?
???????????? ? ?感謝你耐心的看到這里?( ′???` )比心,如有哪里有錯(cuò)誤請(qǐng)?zhí)咭荒_作者o(╥﹏╥)o!
????????? ? ? ? ?? ? ? ? ? ??文章來源:http://www.zghlxwxcb.cn/news/detail-632073.html
?????????????????????????????????????????????????????????????? ?給個(gè)三連再走嘛~文章來源地址http://www.zghlxwxcb.cn/news/detail-632073.html
到了這里,關(guān)于【C++學(xué)習(xí)手札】-引用與內(nèi)聯(lián)函數(shù)以及C++中對(duì)const拓展詳解(超詳細(xì)?。┑奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!