C++入門系列博客三 引用和指針

C++ 引用和指針


作者:AceTan,轉(zhuǎn)載請標明出處相艇!


引用和指針對于C++來說很重要椎麦,是學習C++繞不過去的一道坎。

引用

引用(reference) 就是給對象起別名暖璧。對引用的操作與對變量直接操作完全一樣。

這里說的引用泛指“左值引用(lvalue reference)”琳袄,C++11新增了一種引用江场,即所謂的“右值引用(rvalue reference)”,這里不作討論。

引用即別名窖逗,引用并非一個對象址否,不能定義引用的引用。

定義引用時碎紊,程序把引用和它的初始值進行綁定(bind)在一起佑附,而不是將初始值拷貝給引用。一旦初始化完成矮慕,引用和它的初始值對象一直是綁定在一起的,死也不分開啄骇。

舉個栗子:胡一菲的小名叫小菲菲痴鳄,那么對小菲菲的所有操作既是對胡一菲的操作。同樣缸夹,小菲菲這個名字就是胡一菲綁定在一起了痪寻。當然,胡一菲還可以有其他的別名虽惭,比如叫菲菲菲橡类。但需要注意的是,一旦有了這個小名芽唇,那么這個小名就不能指代其他人顾画。不然會死的很慘。

引用的定義

引用定義時就需要初始化匆笤。允許一條語句定義多個引用研侣,其中每個引用標示符都必須以符號&開頭。

int value = 1;
int &refValue = value;      // refValue 指向value
int &refValue2;             // 報錯炮捧,引用必須初始化 

引用的寫法也還可以是這樣:

int value = 1;
int& refValue = value;      // refValue 指向value
int& refValue2;             // 報錯庶诡,引用必須初始化 

注意&符號和int之間是否緊挨著,兩種寫法都是對的(下面介紹的指針也可以用這兩種寫法), 這個只是個人的代碼風格問題咆课,并無實質(zhì)差異末誓。

引用更為常見的用法應(yīng)該是作為函數(shù)的參數(shù),利用引用的特性书蚪,可以讓一個函數(shù)返回多個"返回值"喇澡。另外,當使用一個類作為函數(shù)參數(shù)時殊校,比較好的做法也是使用引用撩幽。這樣可以減少創(chuàng)建類副本的一些開銷。請看一個具體的示例:

#include <iostream>

using namespace std;

const double PI = 3.14;

// 圓的數(shù)據(jù)結(jié)構(gòu)
struct Circle
{
    double radius;          // 半徑
    double circumference;   // 周長
    double square;          // 面積
};

// 給出圓的半徑,計算圓的周長和面積窜醉,返回是否計算成功宪萄。
bool CalCirle(Circle& c)
{
    // 給的圓的半徑為負數(shù),返回計算錯誤
    if (c.radius <= 0)
    {
        return false;
    }

    // 周長的計算
    c.circumference = 2 * PI * c.radius;

    // 面積的計算
    c.square = PI * c.radius * c.radius;

    return true;

}

int main()
{
    Circle c;
    cout << "請輸入圓的半徑:";
    cin >> c.radius;

    if (CalCirle(c))
    {
        cout << "該圓的周長是" << c.circumference<< endl;
        cout << "該圓的面積是" << c.square << endl;
    }
    else
    {
        cout << "您輸入的半徑不合法榨惰!" << endl;
    }

    return 0;
}

指針

指針(pointer) 是“指向(point to)”另外一種類型的復(fù)合類型拜英。

復(fù)合類型(compound type) 是指基于其他類型定義的類型。比較常見的是指針和引用琅催。

指針本身就是一個對象居凶,允許對指針的復(fù)制和拷貝,而且藤抡,在指針的生命周期內(nèi)侠碧,它可以先后指向幾個不同的對象。指針和其他變量一樣缠黍,定義的時候可以不賦值弄兜。如果指針未被初始化,那么它將擁有一個不確定的值瓷式。指針未初始化和空指針經(jīng)常引起程序崩潰替饿。

指針通常難以理解,即使是有經(jīng)驗的程序員也常常因為調(diào)試指針引發(fā)的bug而備受折磨贸典。

舉個栗子视卢,便于理解指針:指針好比門牌號,它所指向的是這個房間的東西廊驼,它本身也在有值的据过,它就是門牌上的號碼。你可以把門牌號取下來妒挎,掛在別的房間蝶俱,那么這個門牌號就指向了另一個房間。當然饥漫,你覺得有個門牌號不吉利榨呆,把它重新刷成其他門牌號,這樣也是允許的庸队。但你不能把兩個不同的房間都掛一樣的門牌號积蜻,那么別人就分不清了。某天你打開了某個房間(你需要鑰匙彻消,鑰匙就是解引用)竿拆,發(fā)現(xiàn)里面有個門牌號,這個就是多級指針宾尚。房間里的門牌號告訴你丙笋,你要找的東西在這個門牌號所指代的房間里谢澈。

指針存放某個對象的地址,要想獲得該地址御板,需要使用取地址運算符(操作符&)锥忿。

注意這里的取地址運算符&聲明引用時標示符以符號&開頭的意義和用法是不一樣的。

int value = 2;
int* p = &value;    // p存放變量value的地址怠肋,或者說p是指向變量value的指針

利用指針訪問對象:如果一個指針指向一個對象敬鬓,則允許解引用符(操作符*) 來訪問該對象。

int value = 2;
int* p = &value;        // p存放變量value的地址笙各,或者說p是指向變量value的指針

*p = *p * 3;            // 取這個變量钉答,并乘以3

cout << *p << endl;     // 輸出結(jié)果為6
cout << value << endl;  // 輸出結(jié)果為6

指針可以為空(引用是不可以的)¤厩溃空指針不指向任何對象数尿,一個良好的習慣就是使用指針前,一定要判斷是否為空惶楼。

得到空指針最直接的方法是用字面值nullptr 來初始化指針右蹦。(C++11引入的一種方法)

以前的方法是將指針初始化為字面值0或者NULL。(NULL為一個預(yù)處理變量鲫懒,它的值就是0)嫩实。

void* 指針 是一個特殊類型的指針,它可用于存放任意對象的地址刽辙。

指針的指針 指針級數(shù)是沒有限制的窥岩。但常見的也就是一級指針和二級指針,二級以上比較少見宰缤。給出一個多級指針的例子:

#include <iostream>

using namespace std;

int main()
{
    int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    int b[3][4] = 
    {
        11, 22, 33,
        44, 55, 66,
        77, 88, 99,
        111, 222, 333
    };

    int *p1 = nullptr, *p2 = nullptr, **p3 = nullptr;

    p1 = a;     // p1指向a數(shù)組
    p3 = &p1;   // p3指向p1

    for (int i = 0; i < 10; ++i)
    {
        cout << *(*p3 + i) << " ";  // 輸出: 0 1 2 3 4 5 6 7 8 9
    }

    cout << endl;

    for (p1 = a; p1 - a < 10; ++p1)
    {
        p3 = &p1;
        cout << ** p3 << " ";       // 輸出: 0 1 2 3 4 5 6 7 8 9
    }

    cout << endl;

    for (int i = 0; i < 3; ++i)
    {
        p2 = b[i];
        p3 = &p2;
        for (int j = 0; j < 4; ++j)
        {
            cout << *(*p3 + j) << " ";  // 輸出:11 22 33 44 55 66 77 88 99 111 222 333
        }
    }

    return 0;
}

函數(shù)指針 是C++中最大優(yōu)點之一了颂翼。一般來說,使用函數(shù)指針比函數(shù)引用更為方便一些慨灭。

函數(shù)指針的聲明使用方式:

<想要指向的函數(shù)之 返回類型>(*函數(shù)指針的 名稱)<想要指向的函數(shù)之 參數(shù)類型…>

#include <iostream>

using namespace std;

void sayHello(const char* name)
{
    cout << "Hello, " << name << endl;
}

int add(int a, int b)
{
    return a + b;
}

int main()
{
    void(*pFunc1)(const char*);
    pFunc1 = &sayHello;
    pFunc1("Ace Tan");              // 輸出:Hello, Ace Tan

    int(*pFunc2)(int, int);
    pFunc2 = &add;
    cout << pFunc2(1, 2) << endl;   // 輸出3

    return 0;
}

函數(shù)指針也可以作為函數(shù)的參數(shù)朦乏,在這兒不做詳細介紹了。


總結(jié)

引用和指針有如下區(qū)別:

  • 修改性:指針可以重新賦值以指向另一個對象氧骤。引用在初始化時就被綁定對象呻疹,以后無法改變。

  • 非空性: 指針可為空筹陵,引用不可為空

  • 傳遞性: 指針傳遞參數(shù)和值傳遞是一樣的刽锤,被當做局部函數(shù)來處理,不影響主調(diào)函數(shù)的實參變量朦佩。引用傳遞對形參的任何操作都影響了主調(diào)函數(shù)中的實參變量并思。


結(jié)束語

引用和指針在C++中應(yīng)用非常多,也非常靈活语稠。指針也是C++最難學的部分之一宋彼,少年弄砍,趕快去征服它吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末输涕,一起剝皮案震驚了整個濱河市音婶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌占贫,老刑警劉巖桃熄,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異型奥,居然都是意外死亡瞳收,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門厢汹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來螟深,“玉大人,你說我怎么就攤上這事烫葬〗缁。” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵搭综,是天一觀的道長垢箕。 經(jīng)常有香客問我,道長兑巾,這世上最難降的妖魔是什么条获? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮蒋歌,結(jié)果婚禮上帅掘,老公的妹妹穿的比我還像新娘。我一直安慰自己堂油,他們只是感情好修档,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著府框,像睡著了一般吱窝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上迫靖,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天院峡,我揣著相機與錄音,去河邊找鬼袜香。 笑死撕予,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蜈首。 我是一名探鬼主播实抡,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼欠母,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吆寨?” 一聲冷哼從身側(cè)響起赏淌,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎啄清,沒想到半個月后六水,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡辣卒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年掷贾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荣茫。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡想帅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出啡莉,到底是詐尸還是另有隱情港准,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布咧欣,位于F島的核電站浅缸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏魄咕。R本人自食惡果不足惜衩椒,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚕礼。 院中可真熱鬧烟具,春花似錦梢什、人聲如沸奠蹬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽囤躁。三九已至,卻和暖如春荔睹,著一層夾襖步出監(jiān)牢的瞬間狸演,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工僻他, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宵距,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓吨拗,卻偏偏與公主長得像满哪,于是被迫代替她去往敵國和親婿斥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容