zoukankan      html  css  js  c++  java
  • 指针 && 双指针

    指针是C语言中的难点,C++中自然也免不了其身影。

    以下是我学习中的积累,不足之处望不吝赐教。

    指针类型:

    指针

    Const int* pstr     不能修改被指向的对象,可以使指针指向其他对象

      如:const int* pvalue {&value};

      *pvalue=6;     //will not compile

      pvalue=nullptr;  //ok

    Int* const pstr     不能修改指针中存储的地址,可修改指向的对象

      如:Int* const pvalue {&value};

      *pvalue=6;     //ok

      pvalue=nullptr;  //will not compile

    Const int* const Pstr  指针和指向的对象都不能修改

      如:Const int* const pvalue {&value};

      *pvalue=6;     //will not compile

      pvalue=nullptr;  //will not compile

    指针数组  char* pstr[]

    数组指针 char (*pstr)[4]

      double beans[3][4];

      double* pbeans;

      pbeans=&beans[0][0]; //指向数组第一个元素的位置

      pbeans=&beads[0];    //指向数组第一行元素的位置

      double(*pbeans)[4] = beans; //非=&beans,列数要相等

    函数指针

    double (*pfun) (char*,int)

    指针参数:

    先看一段双指针(二级指针)在mian函数里的地址输出

     1 int main()
     2 {
     3     int v = 9;
     4     int *p1 = &v;
     5     int **p2 = &p1;
     6 
     7     cout << "v=   " << dec << v << endl;
     8     cout << "&v=  " << hex << &v << endl;
     9     cout << "p1=  " << hex << p1 << endl;
    10     cout << "&p1= " << hex << &p1 << endl;
    11     cout << "&*p1=" << hex << &(*p1) << endl;
    12 
    13     cout << "p2=  " << hex << p2 << endl;
    14     cout << "&p2= " << hex << &p2 << endl;
    15     cout << "&(*p2)=" << hex << &(*p2) << endl;
    16     
    17     cin.get();
    18     return 0;
    19 }

    注:从中不难看出指针间的关系,二级指针p2指向p1,物理内存p2所在位置存储了指针p1的地址,而p1所在物理内存所在位置存储了变量V的地址。

      当指针同C语言中那样作为参数传递时,可以通过地址来观察函数调用情况。

     1 void  SetPoint(int *pu)
     2 {
     3     cout << "pu=  " << hex << pu << endl;
     4     cout << "&pu= " << hex << &pu << endl;
     5     *pu=*pu + 1;
     6 }
     7 int main()
     8 {
     9     int a = 5;
    10     int *pt = &a;
    11     SetPoint(&a);
    12 
    13     cout << "&a=  " << hex << &a << endl;
    14     cout << "pt=  " << hex << pt << endl;
    15     cout << "&pt= " << hex << &pt<<endl;
    16     cout << "&*pt=" << hex << &(*pt)<<endl;
    17     cout << "a=   " << dec << a<< endl;
    18     
    19     cin.get();
    20     return 0;
    21 }

    注:由上代码可以看出参数’pu‘的地址不等于变量’a‘的地址,所以‘pu'只是作为中间临时变量指向了变量’a'。

      而'a'的值却被改变,则说明编译器创建了临时变量对‘a'进行了操作。如果传递给函数的是按值传递,也是产生临时变量,即实参的副本。

      若传递的是数组本身则不会这样,编译器对数组将不采用按值传递。

      double average(double array[],int count);  //不按值

      double average(double *array,int count);  //传递数组时使用指针符号,则依旧会按值传递。

     1 void  SetPoint(int &pu)
     2 {
     3     cout << "pu=  " << hex << pu << endl;
     4     cout << "&pu= " << hex << &pu << endl;
     5     pu=pu + 1;
     6 }
     7 int main()
     8 {
     9     int a = 5;
    10     int *pt = &a;
    11     SetPoint(a);
    12 
    13     cout << "&a=  " << hex << &a << endl;
    14     cout << "&pt= " << hex << &pt<<endl;
    15     cout << "&*pt=" << hex << &(*pt)<<endl;
    16     cout << "a=   " << dec << a<< endl;
    17     
    18     cin.get();
    19     return 0;
    20 }

    注:而c++中的引用则是直接对变量’a'进行操作,由上面输出可以看出,‘pu’的地址等于‘a'的地址。

    双指针:

    网上常出现的一道面试题如下

    void GetMemory(char *p, int num) 
    { 
        p = (char *)malloc(sizeof(char) * num); 
    } 
    int main() 
    { 
        char *str = nullptr; 
        GetMemory(str, 100);
        strcpy(str, "Hello"); 
        cout << str << endl; 
        return 0; 
    }

    我试着输出了str和p的地址,结果于上。可以看出两个变量的地址并不一样,因此 p 是作为函数运行中的临时变量。可知此处与直接传参数一样,编译器会生成临时变量即常说的副本。

    可以将函数中的临时变量作为返回值传给 str ,以达到想要的效果。

    char * GetMemory(char *p, int num)
    {
        p = (char *)malloc(sizeof(char) * num);
        return p;
    }
    int main()
    {
        char *str = nullptr;
        str=GetMemory(str, 100);
        strcpy(str, "Hello");
        cout << str << endl;
        return 0;
    }

    效率高的还是直接用双指针(二级指针)

    void GetMemory(char **p, int num)
    {
        *p = (char *)malloc(sizeof(char) * num);    
    }
    int main()
    {
        char *str = nullptr;
        GetMemory(&str, 100);
        strcpy_s(str,6, "Hello");
        cout << str << endl;
    
        cin.get();
        return 0;
    }

    思考输出的地址, 指针 p [00AFFDDC] 指向了 str [00AFFEB4]的地址。从而以二级指针作为桥梁曲线操作来达到直接为 str 分配空间的目的。

    由此,进一步,以后申请动态分配内存,可以考虑使用双指针。在大的数据面前,复制移动显然浪费时间,也可以考虑使用。

  • 相关阅读:
    js 中的 EventLoop
    线程的并发工具类
    xpath获取某个节点下的全部字节点的文本
    2020中国 .NET开发者大会精彩回顾:葡萄城高性能表格技术解读
    .NET 控件集 ComponentOne V2020.0 Update3 发布,正式支持 .NET 5
    log4net配置
    TP5.1 爬虫
    pip下载慢
    TP5.1 二维码生成
    composer插件集合
  • 原文地址:https://www.cnblogs.com/yunqie/p/5887086.html
Copyright © 2011-2022 走看看