欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++基礎(chǔ)入門教程(八):函數(shù)指針

 更新時(shí)間:2014年11月17日 10:15:22   投稿:junjie  
這篇文章主要介紹了C++基礎(chǔ)入門教程(八):函數(shù)指針,本文講解了函數(shù)原型和函數(shù)定義、const限定符與指針、函數(shù)的指針參數(shù)、為什么要使用指針參數(shù)等內(nèi)容,需要的朋友可以參考下

最近事情比較多,其實(shí)并不忙,就是事情比較影響思緒,所以都沒心思寫文章了。
今天主要說說函數(shù)的一些基本情況吧,同時(shí)也解釋一下新手最容易迷糊的——什么時(shí)候要用指針參數(shù)?

一、函數(shù)原型和函數(shù)定義

大家都知道,C++定義函數(shù)之前,還需要聲明函數(shù)原型,對(duì)于習(xí)慣Java等其他高級(jí)語言的朋友來說,真心覺得這很煩人。
如下代碼:

復(fù)制代碼 代碼如下:

// 聲明函數(shù)原型
void startGame(int param);
// 函數(shù)定義
void startGame(int param)
{
    // 各種邏輯
}

函數(shù)原型主要是給編譯器用的,在編譯的時(shí)候會(huì)通過函數(shù)原型來檢查函數(shù)返回值、參數(shù)數(shù)量、參數(shù)類型等。
總而言之,方便編譯器,編譯器爽了,我們才能更爽。

但實(shí)際中,函數(shù)原型也方便我們快速理解某個(gè)類的功能。

這些很簡單,就不多嘮叨了。

二、const限定符與指針

之前也有簡單介紹過const,比如 const int num = 10; 那么num就是常量,不可再次進(jìn)行賦值操作了。
如果把const用在指針上呢?

復(fù)制代碼 代碼如下:

    int num = 10;
    const int *p = #
 
    // 編譯會(huì)報(bào)錯(cuò)
    *p = 100;

如上代碼,編譯的時(shí)候就會(huì)報(bào)錯(cuò),因?yàn)橹羔榩指向一個(gè)const int類型,這是一個(gè)常量。
所以*p的值是一個(gè)常量,不能被修改。

再來理一理,不然等會(huì)會(huì)混亂的:
1.p是一個(gè)指針
2.p指向一個(gè)內(nèi)存地址,這個(gè)地址里存放的是一個(gè)const int類型的值
3.*p代表是p指向的內(nèi)存地址里存放的那個(gè)值
4.所以,*p就是一個(gè)const int類型的值
5.綜上所述,*p不能再次被賦值。

這里要區(qū)分p和*p,這是兩個(gè)概念,一個(gè)是指針,一個(gè)是指針指向的值。
p是可以被再次賦值的,但是*p是不能被賦值的。

三、函數(shù)的指針參數(shù)

先來看看下面的代碼:

復(fù)制代碼 代碼如下:

void notChangeNum(int num);
void changeNum(int* num);
int _tmain(int argc, _TCHAR* argv[])
{
    int num = 10;
  
    // 這個(gè)函數(shù)不會(huì)改變num的值
    notChangeNum(num);
    cout << num << endl;
    // 這個(gè)函數(shù)會(huì)改變num的值
    int* p = &num;
    changeNum(p);
    cout << num << endl;
    return 0;
}
void notChangeNum(int num)
{
    // 參數(shù)不是指針
    num = 999;
}
void changeNum(int* num)
{
    // 參數(shù)是指針
    *num = 999;
}

這里有兩個(gè)函數(shù),一個(gè)是普通參數(shù)(值傳遞),一個(gè)是指針參數(shù)(地址傳遞)。

第一個(gè)notChangeNum函數(shù)是不會(huì)改變num的值的,因?yàn)閚um傳遞給函數(shù)時(shí),是拷貝了一份新的值,原來的num是不受影響的。

當(dāng)離開notChangeNum函數(shù)后,函數(shù)的num參數(shù)會(huì)被釋放。

第二個(gè)changeNum函數(shù)的參數(shù)是指針,我們都知道,指針是指向某個(gè)內(nèi)存地址的,所以,函數(shù)的參數(shù)指向的內(nèi)存地址就是num的內(nèi)存地址。

直接修改內(nèi)存地址上的值,會(huì)影響原來的num,所以,離開changeNum函數(shù)后,num的值也會(huì)被改變,最終值是999.

這就是指針參數(shù)的作用,某些情況下,我們希望函數(shù)里對(duì)參數(shù)的修改能夠真正產(chǎn)生影響。

四、為什么要使用指針參數(shù)

為什么要用指針作為參數(shù)呢?因?yàn)橹羔樋梢灾苯又赶騼?nèi)存地址,可以直接在函數(shù)里修改值,并且離開函數(shù)后仍然生效。
說是這么說,但,肯定還有人會(huì)迷糊,為什么呢?為什么要這樣呢?

比如,我們的函數(shù)參數(shù)是某個(gè)類:

復(fù)制代碼 代碼如下:

void play(Sprite* sp) {
}

Sprite和Value都是Cocos2d-x常用的,這里的參數(shù)為什么是指針?
因?yàn)橹狄玫膮?shù)是會(huì)拷貝一份的,這樣才不會(huì)影響原本的值,拷貝一份就會(huì)有額外的開銷。
一般類的開銷都比較大(相對(duì)于int、float等基本類型而言),所以拷貝一份不太合適。
而且我們通過都需要在函數(shù)里改變Sprite的坐標(biāo)、大小等屬性,如果使用值傳遞的話,就無法修改了(修改的只是拷貝的那一份)。

當(dāng)然,這個(gè)還要看具體項(xiàng)目的情況,我不嘮叨了,太深入不好吹水。

五、不想拷貝,又不想值被修改,怎么辦?

拷貝開銷大,使用指針參數(shù)又很可能在函數(shù)被修改了值,怎么辦呢?
這時(shí)候就要用const限定符了,如下代碼:

復(fù)制代碼 代碼如下:

void play(const Sprite* sp) {
}

這樣在函數(shù)內(nèi)部既不會(huì)修改sp指向的值,又可以避免值傳遞的額外開銷。

六、函數(shù)內(nèi)部的變量離開函數(shù)時(shí)就會(huì)被釋放

我們之前說過,只要不是new出來的變量,那么,在離開作用范圍后,就會(huì)被自動(dòng)釋放。
但是,來看看這個(gè)函數(shù):

復(fù)制代碼 代碼如下:

int getNum() {
    int num = 10;
    return num;
}

既然變量離開作用范圍后會(huì)被釋放,那么,num在離開getNum函數(shù)后,就會(huì)被釋放。
這時(shí)候return num的意義何在呢?getNum函數(shù)真的能成功獲取到數(shù)字10嗎?
答案是肯定的。

因?yàn)閞eturn 在返回num的時(shí)候,實(shí)際上是拷貝了一份的,返回的是拷貝的值,釋放的是原來的變量。
這就是return的秘密了。

但是,指針就不行了,看看下面的代碼:

復(fù)制代碼 代碼如下:

// 假設(shè)有這樣一個(gè)結(jié)構(gòu)體
struct People {
   int age;
};
People* getNewPeople() {
    People nPeople;
    nPeople.age = 20;
    return &nPeople;
}

這個(gè)函數(shù)返回的是一個(gè)指向People結(jié)構(gòu)體類型的內(nèi)存地址。
按照return的規(guī)則,返回的時(shí)候?qū)嶋H上是拷貝了一份,但這個(gè)時(shí)候拷貝的只是一個(gè)指針,也就是一個(gè)內(nèi)存地址。
這個(gè)內(nèi)存地址仍然指向函數(shù)內(nèi)部的nPeople變量。

所以即使getNewPeople函數(shù)成功返回了一個(gè)指針,但這個(gè)指針指向的內(nèi)存地址上的值仍然是被釋放了。
也就是說,我們獲取的只是一個(gè)野指針。

七、結(jié)束

好了,這篇寫得有點(diǎn)糟糕,太多內(nèi)容了,我只是抽取部分來吹吹水~

相關(guān)文章

  • C語言中的分支循環(huán)其嵌套語句

    C語言中的分支循環(huán)其嵌套語句

    這篇文章主要介紹了C語言中的分支循環(huán)其嵌套語句,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • opencv3.0識(shí)別并提取圖形中的矩形的方法

    opencv3.0識(shí)別并提取圖形中的矩形的方法

    這篇文章主要介紹了opencv3.0識(shí)別并提取圖形中的矩形的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • C++中std::is_object的具體使用

    C++中std::is_object的具體使用

    std::is_object是一種C++類型特性,其用途是判斷一個(gè)類型是否是一個(gè)對(duì)象類型,本文主要介紹了C++中std::is_object的具體使用,感興趣的可以了解一下
    2024-01-01
  • C++中std::find函數(shù)介紹和使用場景

    C++中std::find函數(shù)介紹和使用場景

    std::find函數(shù)是一個(gè)非常實(shí)用的通用查找算法,適用于各種場景,本文主要介紹了C++中std::find函數(shù)介紹和使用場景,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • opencv3/C++ 實(shí)現(xiàn)SURF特征檢測

    opencv3/C++ 實(shí)現(xiàn)SURF特征檢測

    今天小編就為大家分享一篇opencv3/C++ 實(shí)現(xiàn)SURF特征檢測,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • STL  priority_queue(優(yōu)先隊(duì)列)詳解

    STL priority_queue(優(yōu)先隊(duì)列)詳解

    這篇文章主要介紹了 STL priority_queue(優(yōu)先隊(duì)列)詳解的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • C++利用VLC庫制作音視頻的示例代碼

    C++利用VLC庫制作音視頻的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C++如何利用VLC庫制作音視頻,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以了解一下
    2024-01-01
  • C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)快速排序圖文示例

    C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)快速排序圖文示例

    這篇文章主要為大家介紹了C語言植物大戰(zhàn)數(shù)據(jù)結(jié)構(gòu)快速排序圖文示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • map插入自定義對(duì)象總結(jié)

    map插入自定義對(duì)象總結(jié)

    黑樹在插入節(jié)點(diǎn)時(shí),必須依照大小比對(duì)之后在一個(gè)合適的位置上執(zhí)行插入動(dòng)作。所以作為關(guān)鍵字,起碼必須有“<”這個(gè)比較操作符
    2013-09-09
  • VC解析XML文件-CMarkup的使用詳解

    VC解析XML文件-CMarkup的使用詳解

    本篇文章是對(duì)VC解析XML文件-CMarkup的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論