从C出发 31 --- 指针专题经典问题剖析

int a = 0;
int* p = &a;  //p作为指针指向了a, p 保存的是a 变量的内存地址,
    // p 这个指针本质是变量,这个变量有没有内存地址?
    // 有内存地址,为什么?
    // 因为它作为变量,肯定要占用内存空间的
    // p 这个变量的地址如何拿到?
    // 使用取地址操作符作用于 p 这个变量 ------- &p   其结果就是 p 这个变量的内存地址
    // 这个内存地址( &p ) 如何保存?
    // 显然,要保存一个内存地址,只能定义指针?
    // 那么,怎么定义指针指向另一个指针呐?

在 c 语言里面有多级指针的概念,多级指针就是指针。这种指针用来保存其他指针的地址,换句话说,也就是指向指针的指针

Type *   ----   表示一个指针类型 ,    指针类型后面再加一个 * 号,是另一个指针类型,是不同的指针类型,于是,这个 ppv 就是一个指针,这个指针用来指向 这个类型的变量 ---- Type*,而Type*类型的变量是什么?是另一个指针,所以有了这样的初始化写法 ---- Type** ppv = &pv;

使用 pv ,也就是 Type* 类型的变量的地址来初始化 ppv ,这样的话 ppv 是一个二级指针。这个二级指针的本质还是变量,只有是指针本质就是变量

ppv 这个二级指针还是变量,肯定有地址,怎么获得它的地址  -------   &ppv

怎么保存 ppv 这个二级指针变量的地址?

        再定义指针,

        ppv 它的类型是 : Type**     

        它的地址类型是 : 就是 ppv 的类型再加一个 * 号


 

#include <stdio.h>

int main()
{
    int a = 0;
    int b = 1;


    int* p = &a; //定义一级指针 p ,让一级指针p ,指向 a
    int** pp = &p; 定义二级指针 pp,并使得它指向一级指针 p

    **pp = 2;   // a = 2;

    *pp = &b;   // p = &b;

    *p = 3;     // b = 3;

    printf("a = %d, b = %d\n",a, b);
    

    return 0;
}


既然是二级指针,意味着我们调用这个函数的时候,第一个参数必须是   一个一级指针的地址

 就是在函数里面,申请一片堆空间,通过函数外的指针指向这片堆空间

#include <stdio.h>
#include <stdlib.h>

int getDouble(double** pp, unsigned n)
{
    int ret = 0;
    double* pd = malloc(sizeof(double) * n);

    if(pd != NULL)
    {
        printf("pd = %p\n",pd);
        *pp = pd;
        ret = 1;
    }

    return ret;
}

int main()
{
    double* p =NULL;
    
    if(getDouble(&p, 5))
    {
        printf("p = %p\n",p);

        free(p);
    }


}

 我们应用了二级指针,在函数内部改变了函数外部指针变量的值


 b 的类型是什么?

C 语言里面没有多维数组,只有一维数组,我们所看到的多维数组,其实就是数组的数组

 

实验结论 : 一维数组的数组名是一个 一级指针类型

                    二维数组的数组名是一个 也是一个一级指针类型,绝非二级指针类型

 


 

 

#include <stdlib.h>


int* func()
{
    int var = 100;
    
    return &var;
}

int main()
{
    int* p = func(); //OPPS!!!!
                    // p 指向了不合法的地址,这个地址处没有变量存在
                    // p 是一个野指针,保存不合法地址的指针都是野指针 

    printf("*p = %d\n", *p);

    *p = 200;   //改变 func 函数中局部变量 var 的值,是不是非常奇怪???
    
    printf("*p = %d\n", *p);

    return 0;

}

可以定义指针的指针 ,来保存另一个指针的地址

 

 想要在函数返回之后,操作函数内部的局部变量,这显然不合法,因为函数返回之后,局部变量和函数参数都被销毁了,所以返回的地址就不合法了,于是导致我们在main 函数中操作了野指针

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长生君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值