“指針的愛情故事”(指針\多級指針 詳解,常量指針\指針常量\常量指針常量,數組指針\指針數組,函數指針\指針函數)

“指針的愛情故事”(指針\多級指針 詳解,常量指針\指針常量\常量指針常量,數組指針\指針數組,函數指針\指針函數)

作者:譚丙章(AlexTan)
E-mail: [email protected]
注:轉載不貼上作者信息以及原文地址,必追究其法律責任

因爲最近要講課的原因,想着怎麼才能讓學弟學妹們把指針理解透,學指針學起來不枯燥。於是自己編寫了 ”指針的愛情故事“。

先聲明:此故事純屬虛構,如有雷同,不勝榮幸!

故事以及講解都在代碼註釋裏,所以就直接上代碼:

#include<iostream>
using namespace std;
/*-------------------------------------------指針的愛情故事---------------------------------------------*/

//講故事前,首先,介紹一下地址的概念   ps:其實地址就是變量的家啦~!  和人類世界不同的是,變量的整個一生都會待在家裏!
void address()
{
    int baby;    //一個叫baby的int類型的變量出生了,上帝會給他在棧區分配一個家(地址)。這裏的專業名字叫:聲明!  知識拓展一:局部變量的家(存放位置)是在棧區,全局變量和static變量的家(存放位置)在全局數據區。
    //我們來看一看baby是在什麼地方出生的!
    cout << &baby << endl;    //給baby加上“&”(取地址符),就能找到去baby家的路
    baby = 1;    //經過成長的磨練,baby長大啦!他有了自己的個性,包括價值觀、愛情觀、性格等等(用1來代替)。 這裏的專業名字叫:定義!
    //我們來看看baby的性格、價值觀、愛情觀是怎樣的
    cout << baby << endl;
}

/*有了地址的概念,那麼我們就開始來講講指針,指針也許是計算機世界裏最癡情的人~,就好像人類世界裏的“了不起的蓋茨比”。*/
//首先是指針變量
void pointer()
{
    int *Gatsby;   //蓋茨比出生了,同樣,上帝也會給他在棧區分配一個家(地址)。
    char baby;
    int lover;  //同時,另外兩個小孩兒也出生了
    //我們來看看蓋茨比的家在哪
    cout << &Gatsby << endl;
    //蓋茨比小時候,也以爲自己和其他小孩兒(變量)一樣
    baby = 'a';
    lover = 2;
    //*Gatsby = 1;
    //cout << *Gatsby << endl;
    //一次碰壁後,他才知道他與衆不同!他在人生的道路上不斷地尋找自己,通過他的努力,終於找到了正確的道路
    Gatsby = new int(1);     //知識拓展二:new int(1)代表從堆中給Int類型的值“1”(可以理解成結果等於1的Int類型變量)分配一個空間
    cout << *Gatsby << endl;
    //同時,他還有了一個驚奇的發現
    cout << Gatsby << endl; //他發現自己可以找到別人的家(地址)。
    //於是,他漸漸長大了,看了很多悲劇性的愛情電影,那時他就發誓,自己將來一定要好好對待一個女孩兒!懵懂的愛情在他腦中盪漾~。最開始,他遇到了baby,漸漸喜歡上了她,於是他向她表白了。
    //*Gatsby = baby;  //我喜歡你。。。一開始就被狠狠地拒絕了,可是,他不是那種輕易放棄的人
    //Gatsby = baby;    //結果,他直接在全班同學面前出糗了,很尷尬~!  於是他就開始反思,也許是他方法用得不對,於是他又去尋找不同的方法
    //*Gatsby = &baby;    //還是惹來同學的笑話
    //Gatsby = &baby;     //一次次地失敗,最終把他打擊得實在是沒有信心了....於是他就想:“也許他們倆根本就不適合!”
    //他放棄了baby... 果然,沒過多久,他就遇到了另外一個女孩兒,並且是一見鍾情!他有了上一次的經驗,一下就找準了方法
    *Gatsby = lover;         //我喜歡你... 批註:這裏只是給指針賦值,把lover的值賦給指針,並沒有讓指針指向lover
    cout << &lover << endl;
    cout << Gatsby << endl;
    cout << *Gatsby << endl; 
    Gatsby = &lover;         //漸漸的...我喜歡你,變成了我愛你...蓋茨比把lover的家,lover的個性都深深地烙印在了自己的心底。 批註:指針指向lover。
    cout << &lover << endl;  //lover的家
    cout << Gatsby << endl;  //lover的家
    cout << *Gatsby << endl; //lover的個性
    lover = 3;    //即使lover的個性或者是外貌改變了,蓋茨比也始終愛着她
    cout << *Gatsby << " " << lover << endl;
    *Gatsby = 4;  //lover或許是因爲蓋茨比的愛而感動,或許是因爲其他,lover也愛上了蓋茨比
    //他們形影不離,你變我也跟着變,彼此都住在對方的心底
    cout << *Gatsby << " " << lover << endl;
}

//儘管蓋茨比他們彼此已經非常非常相愛了,但是,現實最終打敗了他們,不過,蓋茨比卻得到了昇華~
void multipointer()
{
    int lover = 2;
    int *Gatsbyago=&lover; //以前的蓋茨比只是純粹的愛上lover。知識拓展三:聲明這裏初始化可以這樣寫,其他地方必須得這樣寫:Gatsbyago=&lover,代表Gatsbyago指針指向lover。
    //知識拓展四:如果指針未被初始化(未指向一個地址),那麼也不能進行*Gatsbyago = 3 之類的操作,指針本身的地址只能指向一個地址,不能存放普通值。
    int family=3;
    int *lovers = &family; //lovers愛自己的家人
    int **Gatsbynow;  //如今的蓋茨比
    cout << &lovers << " " << &family << " " << lovers << " " << &Gatsbynow << endl;
    Gatsbynow = &lovers;
    cout << **Gatsbynow << " " << *Gatsbynow << " " << Gatsbynow << " " << &Gatsbynow << endl;
    //如果family改變,其他所有人都跟着改變
    family = 4;
    cout << family << " " << *lovers << " " << **Gatsbynow << endl;
    //如今的蓋茨比,不僅愛着lovers,他還愛着他愛人所愛的所有人。正所謂:愛屋及烏...
    /*-----------------------------END------------------------------*/
    //*Gatsbynow = &lover;  //知識拓展五:清楚二級指針 **xxx(二級指針所指向的“一級指針指向的地址的值”),*xxx(一級指針所指向的地址),xxx(一級指針的地址)代表什麼後,可以進行篡改操作,這樣的篡改同時會把lovers一級指針所指向的地址改變(即,蓋茨比的愛人愛的人變了,他所愛的人同樣跟着變)
    //cout << family << " " << *lovers << " " << **Gatsbynow << endl;
    //多級指針同理
}

/*------------------------常量指針、指針常量、常量指針常量------------------------*/

void ConstPointer()
{
    const int a = 1; //常量變量
    //a = 2; //非法操作:常量不能被改變
    int b = 2;
    int c = 3;
    const int *pointer = &a; //常量指針,是一個指針,即可以理解爲指向常量的指針,常量的值不能變,指針指向的地址可以變
    //*pointer = 4; //非法操作
    //pointer = &b; //合法操作
    int const *pointer2 = &b; //常量指針的另外一種聲明方式
    //*pointer2 = 4; //非法操作
    //pointer2 = &c;  //合法操作
    int *const pointer3 = &c; //指針常量,是一個常量,即可以理解爲指針是常量,指針指向的地址的值可以變,指針指向的地址不可以變,
    //*pointer3 = 4; //合法操作
    //pointer3 = &b; //非法操作

    const int *const pointer4 = &a; //常量指針常量,全都是常量,不管是指針指向的地址,還是值都不能被改變
    //*pointer4 = 8;  //非法操作
    //pointer4 = &b;  //非法操作    
}

/*------------------------------------數組指針、指針數組---------------------------*/

void ArrayPointer()
{
    //顧名思義,數組指針:是一個指針,這個指針是指向數組的指針;指針數組:是一個數組,這個數組是存放指針(地址)的數組
    int *a[4]; //指針數組
    cout << &a << endl;
    int b[4] = { 1, 2, 3, 4 };
    //給指針數組賦值
    for (int i = 0; i < 4; i++) // int 
    {
        a[i] = &b[i];
    }
    //輸出:
    for (int i = 0; i < 4; i++)
    {
        cout << *a[i] << " ";
    }
    cout << endl;
    int (*c)[4];//數組指針
    c = &b; //數組指針指向b這個數組
    //輸出:
    for (int i = 0; i < 4; i++)
    {
        cout << (*c)[i] << " ";
    }
}

/*------------------------------指針函數、函數指針-------------------------*/

int *f1(int a, int b) //指針函數
{
    int *c;
    if (a > b)
    {
        c = &a;
        cout << &a << endl;
        return c;
    }
    else
    {
        c = &b;
        cout << &b << endl;
        return c;
    }
}
int(*f2)(int a, int b); //聲明函數指針
int max(int a, int b)   //普通函數
{
    if (a > b)
        return a;
    else
        return b;
}
void FuncPointer()
{
    //同樣,顧名思義,指針函數:是一個函數,不過這個函數返回的類型是一個指針;函數指針:即是一個指針,不過這個指針指向的是一個函數
    int a = 1, b = 2;
    cout << f1(a,b) <<endl;  //調用指針函數,輸出的是地址,如果輸出 *f1(a,b) 將輸出值。
    f2 = max;  //函數指針指向max函數
    cout << (*f2)(a, b) << endl;    //通過函數指針調用函數
}

/*----------------------------------主函數----------------------------------*/

int main()
{
    //address(); //地址
    //pointer(); //一級指針
    //multipointer(); //多級指針
    //ConstPointer(); //常量指針、指針常量、常量指針常量
    //ArrayPointer(); //數組指針、指針數組
    //FuncPointer();   //函數指針、指針函數
    return 0;
}

建議不懂的同學把代碼一步一步調試一下,如果還有什麼不懂的歡迎評論留言!

最後留下一句話(ps:也是自己編的):

程序猿的我愛你,是像指針那樣,愛你勝過愛自己,把兩個地址都連在了一起,有了你,我纔有存在的價值;如果你愛着別人,那麼我就是多級指針,愛你所愛的人,當然包括你~!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章