“指针的爱情故事”(指针\多级指针 详解,常量指针\指针常量\常量指针常量,数组指针\指针数组,函数指针\指针函数)

“指针的爱情故事”(指针\多级指针 详解,常量指针\指针常量\常量指针常量,数组指针\指针数组,函数指针\指针函数)

作者:谭丙章(AlexTan)
E-mail: [email protected]
注:转载不贴上作者信息以及原文地址,必追究其法律责任

因为最近要讲课的原因,想着怎么才能让学弟学妹们把指针理解透,学指针学起来不枯燥。于是自己编写了 ”指针的爱情故事“。

先声明:此故事纯属虚构,如有雷同,不胜荣幸!

故事以及讲解都在代码注释里,所以就直接上代码:

#include
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) <//调用指针函数,输出的是地址,如果输出 *f1(a,b) 将输出值。
    f2 = max;  //函数指针指向max函数
    cout << (*f2)(a, b) << endl;    //通过函数指针调用函数
}

/*----------------------------------主函数----------------------------------*/

int main()
{
    //address(); //地址
    //pointer(); //一级指针
    //multipointer(); //多级指针
    //ConstPointer(); //常量指针、指针常量、常量指针常量
    //ArrayPointer(); //数组指针、指针数组
    //FuncPointer();   //函数指针、指针函数
    return 0;
}

建议不懂的同学把代码一步一步调试一下,如果还有什么不懂的欢迎评论留言!

最后留下一句话(ps:也是自己编的):

程序猿的我爱你,是像指针那样,爱你胜过爱自己,把两个地址都连在了一起,有了你,我才有存在的价值;如果你爱着别人,那么我就是多级指针,爱你所爱的人,当然包括你~!

你可能感兴趣的:(C++)