指针初阶二三(开心)

 

指针初阶二

  • 野指针
    野指针成因
    如何避免野指针
    • 野指针概念
      指的是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)大街上的野狗
    • 野指针的成因
      • 没有对指针初始化


        {int* p;p是一个局部的指针变量,局部变量不初始化的话,默认是随机值
        ​p现在放的是随机值
        当我们对指针进行解引用的话,通过对p里存的随机的地址在内存找了一块由它指向的内存空间,这个空间是不是属不属于我们空间的呢?不是
        *p = 20;那个地址指向的空间可能不是你的,非法访问内存
        在这里的p就被称为野指针
        运行起来不让你运行,用都不让你用
        注意:内存里的是你申请了的,分给你的空间才叫你的空间
        就像有个宾馆,我就睡觉了,他不属于你的,要掏钱
        ​}
      • 指针越界访问


        int arr [10] = {0};
        int* p = arr;
        int i =0 ;
        for()循环十次
        *p = i;
        p++
        这个数组有是个元素
        数组名交给指针变量p
        p现在指向这个地方没大问题
        现在循环十一次
        你去解引用的时候越界然后解引用,这个p就是野指针
      • 指针指向的空间释放
        这个空间是你的,也申请好了,然后你也知道地址是啥
        但是后来空间释放了,不属于你了空间还给操作系统
        但地址你还记着
        这个时候你再通过指针访问这个空间,不行
        我还回去,p记住了,但是去用不行
        就像你找个女朋友,后来有一天生气分手了
        你再打电话就是骚扰比喻
        退房以后再去住就是不行的
      • 空间释放的详解


        这个代码有没有问题呢?
        首先调用test函数
        有个局部变量a
        当我们进入test函数
        a这个局部变量被创建
        这个空间创建后这块空间的地址0x1121434

        return &a之后要返回
        返回放到p里去
        返回的时候把地址返回来
        但是return&a以后返回去了a的变量周期到了

        这个空间被销毁了,还给操作系统了
        但是这个时候p还是存着这个地址0x1121434
        ​这个时候*p=20 去访问的时候出问题
        你说你还通过这个地址找到a的这个空间
        放置成20;放也许是可以放的,但是这不属于你了,你还要强行放进去
        这就非法访问内存了
        因为a出test已经被销毁了
        销毁是指把这四个字节的内容还给操作系统了
        这个时候通过p存的地址去访问a不行的
        这个p就是一个野指针
      • 如何避免野指针

        • 指针初始化
          我们习惯每个变量都会初始化;
          int a;
          教材垃圾
          编译器都不放过你
          所以我们初始化
          当然我们也要指针进行初始化
          当前不知道p应该会初始化什么地址的时候,直接初识化空指针NULL
          头文件include<stdio.h>
          其实你会发现
          #define NULL ((void *)0)
          ​void*也是指针类型
          把0强制类型转换成void *类型
          ​但还是0
          NULL就是0
          你到路上遇到一条野狗,给他拴上一条链子,防止她乱害人
          而现在这个p指针也一样,初识化空指针不要随便用它
          //明确知道初识的值
          int * ptr = &a ;
          都叫初始化没问题
        • 小心指针越界
          C语言本身不会检查数据的越界类型的
        • 指针指向的空间释放以后及时置成NULL(及时置空)
          当我们一个指针指向的空间被释放了,那我们应该及时把这个指针置成空指针 int * = NULL;我们也不会去强行使用他了
        • 指针使用之前检查有效性


          比如我们及时初识化空指针我们也不能用它
          这个地方 空指针不能使用
          我们这有一个点
          使用之前一定要检查有效性
          if ( p ! = NULL)
          * p = 10;
          使用我们不知道这个指针指向哪时,把她初始化为空指针
          当这个指针指向的空间被释放不用的时候,你也把这个指针置向空指针,当她指向有效空间的时候,你就给他一个有效的地址,这样的话,指针要么指向有效地址,要么指向空指针

          使用之前先判断


          ​用if,避免野指针的出现
    • 指针的运算

      • 指针+-整数


        图三:
        指针关系运算
      • 指针-指针


        &arr [9] - &arr [0];
        ​答案是多少呢验证一下
        哎呦9
        为什么是9,问题不大
        这个数组放了十个地址
        九个元素
        指针-指针和我们所的是两个指针之间的元素个数
        但有前提:必须两个指针指向同一块空间

        我们现在灵活应用一下
        strlen - 求字符串长度
        头文件<string.h>
        int len = strlen ("abc");
        printf("%d",len);

        结果是三

        在讲函数的时候模拟实现了strlen

        my_strlen计数器的方法实现(图三)

        递归的时候还有一种方法

        指针-指针
        ​拿到a的地址 拿到/0的地址
        还有一种版本指针-指针
        ​图四

指针初阶三 

  • 指针的关系运算


    两种写法神仙打架
    但有标准规定

    图二中有标准规定
    数组从0开始数的,不能数到-1 但可以从5数到6
    从右向左不符合标准
  • 指针与数组
    • 数组名是什么


      看例子:直接看打印真逗
      数组名就是数组首元素的地址

      我们就可以这样去理解[图二]
      产生的就是下标为i这个元素的地址

      图三是在访问数组

       
    • 扩展


      arr数组名是首元素地址
      int * p = arr;
      等价 交换律 无限套娃
      可以呀
      竟然没毛病
      arr[2] p [2 ]
      都是三关键在于这个操作符
      C语言确实很灵活呀
    • 二级指针


      是什么:其实呀
      套娃四级指针三级指针
      但最常用的就是二级指针
    • 指针数组


      理解要有自己的认识

      主语是什么? --数组
      好孩子
      ​指针数组到底是个怎样的数组呢?

      int arr [10];//这是一个整形数组:--存放整形的数组就是整形数组
      char ch [5];//字符数组 - --存放的是字符
      指针数组 ---存放指针的数组

      int * parr [5]; //整形指针的数组
      整形指针数组

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值