• 深入理解C语言-深入理解指针


    关于指针,其是C语言的重点,C语言学的好坏,其实就是指针学的好坏。其实指针并不复杂,学习指针,要正确的理解指针。

    指针是一种数据类型

    指针也是一种变量,占有内存空间,用来保存内存地址

    指针就是告诉编译器,开辟4个字节的存储空间(32位系统),无论是几级指针都是一样的

    *p操作内存

    在指针声明时,* 号表示所声明的变量为指针
    在指针使用时,* 号表示操作指针所指向的内存空间中的值
    *p相当于通过地址(p变量的值)找到一块内存;然后操作内存
    *p放在等号的左边赋值(给内存赋值)
    *p放在等号的右边取值(从内存获取值)

    指针变量和它指向的内存块是两个不同的概念

    1. 给p赋值p = 0x1111;只会改变指针变量值,不会改变所指的内容;p = p +1;``p++
    2. *p赋值*p='a';不会改变指针变量的值,只会改变所指的内存块的值
    3. 等号左边*p表示给内存赋值,等号右边*p表示取值,含义完全不同
    4. 等号左边char *p(处理字符串,指针指向字符串首地址:char *p = buf;p++;)
    5. 保证所指的内存块能修改,即不要出现野指针和指向系统内存区域以及修改常量区数据

    指针是一种数据类型,是指它指向的内存空间的数据类型

    指针步长(p++),根据所致内存空间的数据类型来确定
    p++ = (unsigned char )p + sizeof(a);
    结论:指针的步长,根据所指内存空间类型来定

    通过*p/*p++ 来改变变量的值是指针存在的最大意义

    指针变量和它指向的内存块变量

    这完全是两码事

    指针指向某个变量,就是把某个变量地址否给指针

    指针实际上记录的就是地址

    *p间接赋值成立条件

    需要满足三个条件

    1. 2个变量(通常一个实参,一个形参)
    2. 建立关系,实参取地址赋给形参指针
    3. *p形参去间接修改实参的值
    int num = 0; //实参
    int *p = NULL;
    p = #
    num = 1;
    *p = 2; //通过*形参 间接 地改变实参的值
    

    间接赋值的应用场景

    1. 在一个函数之内:
    *p1++ = *p2++;
    
    1. 函数调用:
    int getStr(int *a)
    {
        ···
    }
    

    函数调用时,用n指针(形参)改变n-1指针(实参)的值

    改变0级指针(e.g. int num = 1)的值有2种方式
    改变1级指针(e.g. char *p = 0x1111)的值,有2种方式
    改变2级指针的(e.g. char **pp = 0x1111)的值,有2种方式
    函数调用时,形参传给实参,用实参取地址,传给形参,在被调用函数里面用*p,来改变实参,把运算结果传出来
    间接赋值的推论 ==> 指针做函数参数
    指针作为函数参数的精髓

    • 用1级指针(形参)去改变了0级指针(实参)的值(通过*p去间接修改了实参的在值)
    • 用2级指针(形参)去改变了1级指针(实参)的值(通过*p去间接修改了实参的在值)
    • 用3级指针(形参)去改变了2级指针(实参)的值(通过*p去间接修改了实参的在值)
    • 用n级指针(形参)去改变了n-1级指针(实参)的值(通过*p去间接修改了实参的在值)

    深入理解指针必须和内存四区概念相结合,注意指针的输入输出特性

    ####主调函数 被调函数

    1. 主调函数可把堆区、栈区、全局数据内存地址传给被调用函数
    2. 被调用函数只能返回堆区、全局数据

    内存分配方式

    指针做函数参数,是有输入和输出特性的

    应用指针必须和函数调用相结合(指针做函数参数)

    序号 指针 堆栈 主调函数参数 被调函数参数 备注
    1 1级指针(做输入) 分配 使用 一般禁用
        分配 使用 常用
    2 1级指针(做输出) 使用 传出结果 常用
    3 2级指针(做输入) 分配 使用 一般禁用
        分配 使用 常用
    4 2级指针(做输出) 使用 分配 常用,不建议用,一般转为2
    5 3级指针(做输出) 使用 分配 不常用

    1级指针做输入

    int showbuf(char *p);
    int showArray(int *p; int num);
    

    1级指针做输出

    int getLen(char *pFileName, int *pFileLen);
    

    2级指针做输入

    int main(int argc, char *args[]);//指针数组
    int shouMatrix(int [3][4], int len);//二维数组字符串
    

    2级指针做输出

    int getData(char **data, int *dataLen);
    int getData_Free(void *data);
    int getData_Free(void **data);//避免野指针
    

    3级指针做输出

    int getFileAllLine(char ***content, int *pLine);
    int getFileAllLine_Free(cahr ***content, int *pLine);
    
  • 相关阅读:
    Protocol Buffer详解
    RPC进阶篇
    RPC基础篇
    测试控制器
    更加简洁的tableview
    storyboard中Unwind segue使用
    IOS开发Apache服务器搭建
    IOS多线程操作
    IOS使用Svn的trunk、branches、tag分别的侧重
    在设计IOSapp时为了代码的扩展性可可维护性需要遵守的原则
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664770.html
Copyright © 2020-2023  润新知