C++基礎(chǔ)入門教程(八):函數(shù)指針
最近事情比較多,其實并不忙,就是事情比較影響思緒,所以都沒心思寫文章了。
今天主要說說函數(shù)的一些基本情況吧,同時也解釋一下新手最容易迷糊的——什么時候要用指針參數(shù)?
一、函數(shù)原型和函數(shù)定義
大家都知道,C++定義函數(shù)之前,還需要聲明函數(shù)原型,對于習(xí)慣Java等其他高級語言的朋友來說,真心覺得這很煩人。
如下代碼:
// 聲明函數(shù)原型
void startGame(int param);
// 函數(shù)定義
void startGame(int param)
{
// 各種邏輯
}
函數(shù)原型主要是給編譯器用的,在編譯的時候會通過函數(shù)原型來檢查函數(shù)返回值、參數(shù)數(shù)量、參數(shù)類型等。
總而言之,方便編譯器,編譯器爽了,我們才能更爽。
但實際中,函數(shù)原型也方便我們快速理解某個類的功能。
這些很簡單,就不多嘮叨了。
二、const限定符與指針
之前也有簡單介紹過const,比如 const int num = 10; 那么num就是常量,不可再次進(jìn)行賦值操作了。
如果把const用在指針上呢?
int num = 10;
const int *p = #
// 編譯會報錯
*p = 100;
如上代碼,編譯的時候就會報錯,因為指針p指向一個const int類型,這是一個常量。
所以*p的值是一個常量,不能被修改。
再來理一理,不然等會會混亂的:
1.p是一個指針
2.p指向一個內(nèi)存地址,這個地址里存放的是一個const int類型的值
3.*p代表是p指向的內(nèi)存地址里存放的那個值
4.所以,*p就是一個const int類型的值
5.綜上所述,*p不能再次被賦值。
這里要區(qū)分p和*p,這是兩個概念,一個是指針,一個是指針指向的值。
p是可以被再次賦值的,但是*p是不能被賦值的。
三、函數(shù)的指針參數(shù)
先來看看下面的代碼:
void notChangeNum(int num);
void changeNum(int* num);
int _tmain(int argc, _TCHAR* argv[])
{
int num = 10;
// 這個函數(shù)不會改變num的值
notChangeNum(num);
cout << num << endl;
// 這個函數(shù)會改變num的值
int* p = #
changeNum(p);
cout << num << endl;
return 0;
}
void notChangeNum(int num)
{
// 參數(shù)不是指針
num = 999;
}
void changeNum(int* num)
{
// 參數(shù)是指針
*num = 999;
}
這里有兩個函數(shù),一個是普通參數(shù)(值傳遞),一個是指針參數(shù)(地址傳遞)。
第一個notChangeNum函數(shù)是不會改變num的值的,因為num傳遞給函數(shù)時,是拷貝了一份新的值,原來的num是不受影響的。
當(dāng)離開notChangeNum函數(shù)后,函數(shù)的num參數(shù)會被釋放。
第二個changeNum函數(shù)的參數(shù)是指針,我們都知道,指針是指向某個內(nèi)存地址的,所以,函數(shù)的參數(shù)指向的內(nèi)存地址就是num的內(nèi)存地址。
直接修改內(nèi)存地址上的值,會影響原來的num,所以,離開changeNum函數(shù)后,num的值也會被改變,最終值是999.
這就是指針參數(shù)的作用,某些情況下,我們希望函數(shù)里對參數(shù)的修改能夠真正產(chǎn)生影響。
四、為什么要使用指針參數(shù)
為什么要用指針作為參數(shù)呢?因為指針可以直接指向內(nèi)存地址,可以直接在函數(shù)里修改值,并且離開函數(shù)后仍然生效。
說是這么說,但,肯定還有人會迷糊,為什么呢?為什么要這樣呢?
比如,我們的函數(shù)參數(shù)是某個類:
void play(Sprite* sp) {
}
Sprite和Value都是Cocos2d-x常用的,這里的參數(shù)為什么是指針?
因為值引用的參數(shù)是會拷貝一份的,這樣才不會影響原本的值,拷貝一份就會有額外的開銷。
一般類的開銷都比較大(相對于int、float等基本類型而言),所以拷貝一份不太合適。
而且我們通過都需要在函數(shù)里改變Sprite的坐標(biāo)、大小等屬性,如果使用值傳遞的話,就無法修改了(修改的只是拷貝的那一份)。
當(dāng)然,這個還要看具體項目的情況,我不嘮叨了,太深入不好吹水。
五、不想拷貝,又不想值被修改,怎么辦?
拷貝開銷大,使用指針參數(shù)又很可能在函數(shù)被修改了值,怎么辦呢?
這時候就要用const限定符了,如下代碼:
void play(const Sprite* sp) {
}
這樣在函數(shù)內(nèi)部既不會修改sp指向的值,又可以避免值傳遞的額外開銷。
六、函數(shù)內(nèi)部的變量離開函數(shù)時就會被釋放
我們之前說過,只要不是new出來的變量,那么,在離開作用范圍后,就會被自動釋放。
但是,來看看這個函數(shù):
int getNum() {
int num = 10;
return num;
}
既然變量離開作用范圍后會被釋放,那么,num在離開getNum函數(shù)后,就會被釋放。
這時候return num的意義何在呢?getNum函數(shù)真的能成功獲取到數(shù)字10嗎?
答案是肯定的。
因為return 在返回num的時候,實際上是拷貝了一份的,返回的是拷貝的值,釋放的是原來的變量。
這就是return的秘密了。
但是,指針就不行了,看看下面的代碼:
// 假設(shè)有這樣一個結(jié)構(gòu)體
struct People {
int age;
};
People* getNewPeople() {
People nPeople;
nPeople.age = 20;
return &nPeople;
}
這個函數(shù)返回的是一個指向People結(jié)構(gòu)體類型的內(nèi)存地址。
按照return的規(guī)則,返回的時候?qū)嶋H上是拷貝了一份,但這個時候拷貝的只是一個指針,也就是一個內(nèi)存地址。
這個內(nèi)存地址仍然指向函數(shù)內(nèi)部的nPeople變量。
所以即使getNewPeople函數(shù)成功返回了一個指針,但這個指針指向的內(nèi)存地址上的值仍然是被釋放了。
也就是說,我們獲取的只是一個野指針。
七、結(jié)束
好了,這篇寫得有點糟糕,太多內(nèi)容了,我只是抽取部分來吹吹水~
上一篇:C++基礎(chǔ)入門教程(五):new和delete
欄 目:C語言
下一篇:VC中CWinThread類以及和createthread API的區(qū)別分析
本文標(biāo)題:C++基礎(chǔ)入門教程(八):函數(shù)指針
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3196.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實現(xiàn)與遞歸實現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點數(shù)在內(nèi)存中的存儲方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達(dá)式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10C#中split用法實例總結(jié)
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置