zoukankan      html  css  js  c++  java
  • 指针的指针的作用(传说中的二级指针)

    二级指针的作用用处特别大!!!

    首先主要在数据结构之中当改变指针的时候就需要通过改变指针的指针的值来改变!

    在数据结构中用处很广.最普遍的比如说链表,通过调用函数改变了链表中的元素,那么整个链表就发生了变化,这种情况下就会用到二级指针,因为链表的起始是通过指向头结点的指针来执行的,所以必须要改变这个指针,怎么样使一个指针改变?在形参传递时,必须传递指针的地址,也就是指向指针的指针.

    指向指针的指针的作用 :当要修改实参指针的指向的时候,形参必须使用指向指针的指针。

    当修改的是实参指针指向的内容时,则形参只需是指针即可

    以下是经典程序(载自林锐的从cc++高质量编程),讲解的部分是我个人理解

    void GetMemory(char *p,int num)
    {
          p=(char*)malloc(sizeof(char)*num);       //p是形参指向的地址
    }
    void main()
    {
          char *str=NULL;
          GetMemory(str,100);                            //str是实参指向的地址,不能通过调用函数来申请内存
          strcpy(str,"hello");
    }

    结构是编译能通过,却不能运行,为什么呢?

    先说一下指针作为函数参数的意义:当将指针作为参数时,实参向形参传递的是地址,在函数执行过程中,既可以对该参数指针进行处理,也可以对该参数指针所指向的数据进行处理,(以上程序段来说就是可以对p或*p进行处理)。由于此时形参和实参都是指向同一个存储单元,因此当形参指针所指向的数据改变时,实参指针所指向的数据也作相应的改变,因此这时的形参可以作为输出参数使用。(str和p应同时更改!)

    按照上面的说法,这个程序应该没有问题的啊,实参str和形参p指向同一个存储单元,给形参分配的内存单元应该也给实参分配了才对啊,问题就是在这里

    实参和形参是指向同一个地址,它们只是指向相同,但它们自身的地址不是同时申请的,就是说p在申请内存时,str并不可以通过调用Getmemory同时申请内存,所以尽管str调用了GetMemory,但它仍然是个空指针,所以进行strcpy是就不能运行。

    要使程序可以运行,只要小小的改动就行了(用指向指针的指针):

    void GetMemory(char **p,int num)
    {
    *p=(char*)malloc(sizeof(char)*num);       //此时*p就变成了是形参本身的地址
    }
    void main()
    {
    char *str=NULL;
    GetMemory(&str,100);                            //&str是实参的地址,所以实参和形参之间就可以直接调用
    strcpy(str,"hello");
    free(str);

    程序就会如你所愿,输出hello了

  • 相关阅读:
    .NET反编译工具:de4dot
    Hadoop API:遍历文件分区目录,并根据目录下的数据进行并行提交spark任务
    hive优化之——控制hive任务中的map数和reduce数
    Spark:将RDD[List[String,List[Person]]]中的List[Person]通过spark api保存为hdfs文件时一直出现not serializable task,没办法找到"spark自定义Kryo序列化输入输出API"
    spark算子:combineByKey
    spark分区数,task数目,core数,worker节点个数,excutor数量梳理
    spark算子:partitionBy对数据进行分区
    算子:sample(false, 0.1)抽样数据
    hive:默认允许动态分区个数为100,超出抛出异常:
    Oracle ADDM性能诊断利器及报告解读
  • 原文地址:https://www.cnblogs.com/hao02171990/p/3262346.html
Copyright © 2011-2022 走看看