C(指针)

2021-01-15

指针(重点)

  int *p;//1、p是变量名字,int *表示p变量存放的是int类型变量的地址
        //2、int *p;不表示定义了一个名字叫做 *p 的变量
        //3、int *p;应该这样理解:p是变量名,p变量的数据类型是int *类型,所谓int * 类型就是存放int 变量地址的类型
  p =&i;//1、p保存了i的地址,因此p指向i;
        //2、p不是i,i也不是p,准确说:修改p的值不影响i的值,修改i的值也不影响p的值
        //3、如果一个指针变量指向了某个普通变量,则 *指针变量 就完全等同于 普通变量
              例子:如果p是个指针变量,并且p存放了普通变量i的地址,则p指向了普通变量i; *p 就完全等同于 i ;或者说:在所有出现 *p 的地方都可以替换成i;在所有出现i的地方都可以替换成 *p
  j= *p;//等价于 j =i;
        // *p 就是以p的内容为地址的变量

  1、指针是什么?
        指针就是地址,地址就是指针;
        地址是内存单元的编号;
  2、指针和指针变量是两个不同的概念
        指针变量是存放地址的变量,通常讲述时会把指针变量简称为指针,实际含义并不一样。
  3、指针的重要性:
        (1)指针能表示一些复杂的数据结构;
        (2)能快速传递数据;
        (3)始函数返回一个以上的值;     
        (4)能方便的处理字符串;
        (5)理解面向对象语言中引用的基础;
        总结:C语言灵魂;
  4、指针的定义
        地址:
              内存单元的编号;
              从零开始的非负整数;
              范围:4G【0到4G-1】;
        指针:
              指针就是地址,地址就是指针;
              指针的本质就是一个操作受限的非负整数;(可以相减)
  5、指针的分类
        (1)基本类型指针;
        (2)指针和数组;
        (3)指针和函数;
        (4)指针和结构体;

*的含义

        1、乘法
        2、定义指针变量
              int * p;//定义了一个名字叫P的变量,int *表示p只能存放int变量的地址;
        3、指针运算符
             该运算符放在已经定义好的指针变量前面 例如:*p表示以p的内容为地址的变量;

如何通过被调函数修改主调函数普通变量的值

  1、实参必须为普通变量的地址;
  2、形参必须为指针变量;
  3、在被调函数中通过
        *形参名 = 。。。的方式可以修改主调函数相关变量的值;

指针和数组

指针和一位数组

  一维数组名:
        一维数组名是个指针常量;
        存放的是一维数组第一个元素的地址;
  下标和指针的关系:
        如果p是个指针变量,则 p[i] 永远等价于 *(p+i) ;
        确定一维数组需要两个参数:数组第一个元素的地址 和 数组的长度;
  指针变量的运算:
        指针变量不能相加,不能相乘,不能相除
        如果两个指针变量指向的是同一连续空间中的不同存储单元,则这两个指针变量才可以想见。
  一个指针变量到底占几个字节?*
      预备知识:
              sizeof(数据类型)或者 sizeof(变量名)
              功能:返回值就是该数据类型或者变量名所占的字节数
              例子:sizeof(int) == 4 sizeof(char) == 1
        假设p指向char类型变量 (1个字节)
        假设q指向int类型变量  (4个字节)
        假设r指向double类型变量(8个字节)
        p q r本身所占的字节数是否一样?
              是一样,本身所占的字节数都是一样的,
  总结:一个变量指针,无论它指向的变量占几个字节,指针本身只占4个字节,
        一个变量的地址是同该变量受字节的地址来表示

动态内存分配

  1、传统数组的缺点:
        数组长度必须事先制定,且只能是常整数,不能是变量;
        传统形式定义的数组,该数组的内存程序员无法手动释放;
        在一个函数运行期间,系统为该函数中数组所分配的空间会一直存在,直到该函数运行完毕时,数组的空间才会释放;
        数组的长度一旦被定义,数组长度就不能在函数运行期间进行动态扩充或缩小;
        A函数定义的数组,在A函数运行期间可以被其他函数使用,单A函数运行完毕后,A函数中的数组无法被其他函数使用;
        传统方式定义的数组不能跨函数使用;
  2、为什么需要动态分配内存
        动态数组很好解决了传统数组的4个缺陷;
        传统数组也叫静态数组;
  3、动态内存分配距离——动态数组的构造
        int *p = (int *)malloc(4);
              //要使用malloc函数,必须添加malloc.h这个头文件;
              //malloc函数只有一个形参,并且形参是整形;
              //4表示请求系统为本程序分配4个字节;
              //malloc函数只能返回第一个字节的地址;
              //一共分配了8个字节,p变量占4个字节,p指向的内存也占四个字节
              //p本身所占的内存是静态分配的,p所指向的内存是动态分配;
        free(p);//表示把p指向的内存给释放掉,p本身的内存是静态的
  4、静态内存和动态内存的比较
        1、静态内存是由系统自动分配,由系统自动释放;
        静态内存是在栈分配的;
        2、动态内存是由程序员手动分配,手动释放;
        动态内存是在堆分配的;
  5、跨函数使用内存的问题
        动态内存可以跨函数使用;

多级指针

        int i= 10;
        int *p = &i;
        int **q = &p;
        int ***r= &q;

指针和二维数组

posted @ 2021-01-19 15:46  一名初学者  阅读(409)  评论(0)    收藏  举报