• C/C++指针


    指针的概念

    指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。所有指针在32位上都是4个字节,在64位系统是8个字节。

    为什么要用指针

    1)指针的使用使得不同区域的代码可以轻易的共享内存数据,这样可以使程序更为快速高效;

    2)C语言中一些复杂的数据结构往往需要使用指针来构建,如链表、二叉树等;

    3)C语言是传值调用,而有些操作传值调用是无法完成的,如通过被调函数修改调用函数的对象,但是这种操作可以由指针来完成,而且并不违背传值调用。

    六大常用指针

    int *arr; //单指针
    
    int **arr; //双重指针,指向指针的指针
    
    int (*arr)[3]; //数组指针,指向int型的的一维数组
    
    int *arr[3];          //指针数组,该数组有3个元素,每个元素都是一个指向int型对象的指针
    
    int (*arr)(int, int); //函数指针,指向一个有两个int参数的函数
    
    int *arr(int, int); //指针函数,函数的返回类型为int型指针

    技巧:是指针都是变量单独带括号,优先级:()>[]>*,后面以指针结尾,其就是指针。

    怎么解析复杂指针?

    右左法则:首先从最里面的圆括号(应该是未定义的标识符)看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

    int (*func)(int *p);

    首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是 int。

    int (*func)(int *p, int (*f)(int*));

    func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。

    int (*func[5])(int *p);

    func右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰 func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。
    int (* (*func) [5] ) (int *p);

    func被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。

    int (*(*func)(int *p))[5];

    func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。

    int (*(*func)[5][6])[7][8];

    func是一个指向数组的指针,这类数组的元素是一个具有5X6个int元素的二维数组,而这个二维数组的元素又是一个二维数组。typedef分解:

    typedef int (*PARA)[7][8];
    typedef PARA (*func)[5][6];

    int (*(*(*func)(int *))[5])(int *);

    func是一个函数指针,这类函数的返回值是一个指向数组的指针,所指向数组的元素也是函数指针,指向的函数具有int*形参,返回值为int。typedef分解:

    typedef int (*PARA1)(int*);
    typedef PARA1 (*PARA2)[5];
    typedef PARA2 (*func)(int*);

    int (*(*func[7][8][9])(int*))[5];

    func是一个指针数组,这个数组的元素是函数指针,这类函数具有int*的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。typedef分解:

    typedef int (*PARA1)[5];
    typedef PARA1 (*PARA2)(int*);
    typedef PARA2 func[7][8][9];

    复杂指针的宏替换

    过于复杂的指针,会给他人阅读代码带来麻烦,一般会使用宏定义来替换复杂的指针

    举个例子:

    //int *(*(*fun)(int*))[10];
    
    typedef int *Arr[10];
    typedef Arr*(pFun)(int*);
    
    Arr* myfun(int *)
    {
        static int a[10]={1,2,3,4,5,6,7,8,9,10};
        static int* array[10];
        for (int i = 0; i < 10; i++)
        {
            array[i]=&a[i];
        }
        return &array;
    }
    
    void main()
    {
        pFun fun;
        fun=&myfun;
    }

    同样,以下函数可以写为:

    //int(*func)(int*,int(*),pFun pf);
    typedef int(*pFun)(int*);
    typedef int(*pFunType)(int*,pFun pf);
    pFunType func;
    
    //int (*func[5])(int *);
    typedef int (*pFun)(int *);
    pFun func[5];
    
    //int (*(*func)[5])(int *); 
    typedef int (*pFun)(int *);
    typedef pFun (*Func)[5];
    Func func;
    
    //int (*(*func)(int *))[5];
    typedef int *Ar[5];
    typedef Ar *(*pFun)(int *);
    pFun fun;
    
    //int *(*func(int *))[5]
    typedef int *Ar[5];
    Ar *func(int *);

    野指针

    不是NULL指针,是指向垃圾内存的指针

        1.声明一个指针没有进行合法的初始化

        2.free后,没有置NULL

    指针与const

    const int *p = &a;    //p所指向的内容不能改变,指针可以改变
    int const *p1 = &a;    //p1所指向的内容不能改变,指针可以改变
    int *const p2 = &a;    //p2指针不能改变,内容可变 
    const int *const p3=&a;    //p3指针不能改变,内容不能改变
  • 相关阅读:
    python自省函数getattr的用法
    python-mysqldb安装
    weblogic部署脚本
    netcat使用
    ssh批量互信脚本
    yum安装出错
    centos文件误删除恢复
    lamp php的ssl,ssh支持
    ssh免密码登陆
    python 学习笔记 四 条件, 循环以及其他
  • 原文地址:https://www.cnblogs.com/WindSun/p/11280077.html
Copyright © 2020-2023  润新知