C语言学习笔记-指针-郝斌老师讲解

指针:
         内存单元的编号,就是地址。
指针就是地址,地址就是指针。
地址就是内存单元的编号。

指针变量就是存放地址的变量。
指针和指针变量是两个不同的概念
但是要注意:通常我们叙述时,会把指针变量简称为指针,实际它们含义并不一样


指针的重要性:
    表示一些复杂的数据结构
    快速地传递数据,减少了内存的耗用
    使函数返回一个以上的值
    能直接访问硬件
    能够方便地处理字符串
    是理解面向对象语言中引用的基础

    总结:指针是C语言的灵魂。


指针的定义:
    地址:内存单元的编号
                 从零开始的非负整数
             范围:4G [0, 4G-1]

    指针
         指针就是地址,地址就是指针
         指针变量就是存放内存单元编号的变量,或者说指针变量就是存放地址的变量。
         指针的本质就是一个操作受限的非负整数

指针的分类:
    1. 基本类型指针【重点】
          int *p; //p是变量的名字, int * 表示p变量存放的是int类型变量的地址
// int * p; 不表示定义了一个名字叫做*p的变量
//int * p; 应该这样理解:p是变量名,p变量的数据类型是int * 类型,
// 所以int * 类型实际就是存放int变量地址的类型
int i = 3;
int j;

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

*p 就是以p的内容为地址的变量


  */


//p = i; //error,因为类型不一致,p只能存放int类型变量的地址,不能存放int类型变量

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

附注:
*号的含义:
                     1) 乘法
                     2)定义指针变量        
                             举例:
                                      int *p; //p是变量的名字, int * 表示p变量存放的是int类型变量的地址
                     3)指针运算符
                             该运算符放在已经定义好的指针变量前面
                             如果p是一个已经定义好的指针变量,则*p表示以p的内容为地址的变量。

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



    2. 指针和数组
             指针和一维数组
                     一维数组名是个指针常量
                     它存放的是一维数组第一个元素的地址
                         
                         printf("%#x\n", &a[0]);          //以 十六进制输出

                     下标和指针的关系
                         如果p是个指针变量,则p[i]永远等价于*(p+i)

             确定一个一维数组需要哪些信息?
             如果一个函数要处理一个一维数组,则需要接受该数组的哪些信息
                 需要两个参数:
                                         数组第一个元素的地址
                                         数组的长度

                     指针变量运算
                             指针变量不能相加,不能相乘,不能相除
                             如果两个指针变量指向的是同一块连续空间中的不同的存储单元,则这两个指针变量才可以相减。

         一个指针变量到底占几个字节?一个指针变量无论它指向的变量占几个字节,该指针变量本身都是占4个字节
         一个变量的地址都是用该变量的首地址来表示。

             指针和二维数组

    3. 指针和函数


    4. 指针和结构体


    5. 多级指针


专题:
    动态内存分配
             传统数组的缺点:
                 1. 数组长度必须事先指定,且只能是常整数,不能是变量
                     例子:
                             int a[5];    //正确
                             int len = 5;    int a[len];    //error
                 2. 传统形式定义的数组,该数组的内存,程序员无法手动释放
                         数组一旦定义,系统为该数组分配的存储空间就会一直存在,
                         直到该函数运行完毕时,数组的空间才会被系统释放
                 3.  数组的长度一旦定义,其长度就不能再更改
                        数组的长度不能在函数运行的过程中动态地扩充或者缩小。
                 4. A函数定义的数组,在A 函数运行期间可以被其它函数使用,但A函数运行完毕后,A函数中
                     的数组将无法再被其它函数使用。                      
                 传统方式定义的数组不能跨函数使用。

             为什么额需要动态内存分配?
                 动态数组很好地解决了传统数组的这4个缺陷。
                 传统数组也叫静态数组。

             动态内存分配举例——动态数组的构造


             静态内存和动态内存的比较
                 静态内存由系统自动分配,由系统自动释放,静态内存是在栈中分配
                 动态内存是由程序员手动分配,手动释放。
                 动态内存是在堆分配的。


         跨函数使用内存的问题








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值