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个缺陷。
                传统数组也叫静态数组。

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


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


        跨函数使用内存的问题








阅读更多
个人分类: C语言
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭