• 指针--解决的疑惑


    void aaaa(char *s)
    {
        s = "445566";
        printf("%s",s);
    }

    char *p = "112233";

    aaaa(p);

    问一下:printf("%s",p);   打印的是什么

    简单的就不说了,今天学链表,在链表中遇到了自己疑惑的事情,后来在网上查二级指针,搜出来一个,才解除了自己的疑惑

    下面是对原文的复制,,最后有自己的链表程序--原文链接http://www.jb51.net/article/37516.htm

    好久没有用过C/C++的二级指针了,总觉的它就是指针的指针,没什么大不了的,但是今天看到一道面试题,感觉自己对二级指针的理解还是不够深刻。于是,从网上找资料,学习了一番……

    题目是这样的:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    void GetMemory(char *p, int num)
    {
     p = (char *)malloc(sizeof(char) * num);
     //p = new char[num];  //C++当中
    }
    int main(int argc, _TCHAR* argv[])
    {
     char *str = NULL;
     GetMeory(str, 100);
     strcpy(str,"Hello");
     cout << str << endl;
     return 0;
    }

    问:程序能否达到目的:在GetMemory()中为main函数中的开辟空间,并将str指向这段空间?

    分析:str是一个指针,指向NULL,形参p也是一个指针,初始也指向NULL,在GetMemory函数中,这个指针又指向了新开辟的空间。但是只是形参的指向改变了,实参str仍然指向NULL,并没有改变。因此,程序达不到题目的要求,而且运行时会出现错误,由于str一直指向NULL,执行strcop时,会出现错误,提示某某内存不能写入。

    正确的方法应该采用双指针,程序如下:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    void GetMeory(char **p, int num)
    {
     *p = (char *)malloc(sizeof(char) * num);
     //*p = new char[num];  //C++当中
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
     char *str = NULL;
     GetMeory(&str, 100);
     strcpy(str,"Hello");
     cout << str << endl;
     return 0;
    }

    分析:str是一个指针,指向NULL。而调用GetMemory函数时,传递的是str的地址,p是一个二级指针,*p是一个指针。因此,将str的地址赋给临时变量p,则*p就是指针str的值,改变*p的值就相当于改变str的值。因此这种方法能够得到题目要求的效果。另外还有一种方法,采用一级指针,让函数返回一个指针变量,指向新分配的内存,程序如下:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    char * GetMeory2(char *p, int num)
    {
     p = (char *)malloc(sizeof(char) * num);
     //p = new char[num];  //C++当中
     return p;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
     char *str = NULL;
     str = GetMeory2(str, 100);
     strcpy(str,"Hello");
     cout << str << endl;
     return 0;
    }

    2. 另外用二级指针还经常用在动态申请二维数组。

    void main() 
    { 
    int m , n , **p; 
    scanf("%d%d" , &m , &n); 
    p = (int **)malloc(m * sizeof(int *)) 
    //C++中建议使用:p = new int* [m]; 
    for(i = 0 ; i < m ; i++) 
    p[i] = (int *)malloc(n * sizeof(int)); 
    //C++:p[i] = new int[n]; 
    } 

    这样就实现了二维数组的动态申请,因为一般数组声明时,不允许下标是变量,所以如果想动态决定数组各维的大小,最好这样做。

    关于那个面试题,,,我也挂了,看后才有所警觉

    下面看我的关于链表的

    struct MyStruct
    {
        int num;//编号
        float corse;//成绩
        struct MyStruct *pNext;//链表的下一个节点
    };
    typedef struct MyStruct st;
    
    void add(st **p, int inum, float icore)//传入头结点地址,插入数据
    {
        if(*p == NULL)//判断链表是否为空
        {
            st *fast ;//创建结构体指针
            fast = (st *)malloc(sizeof(st));//为新指针分配内存
            fast->num = inum;
            fast->corse = icore;
            fast->pNext = NULL;
            *p = fast;
        }
        else//链表不为空
        {
            st *pp = *p;//*p是结构体指针,,,,pp是结构体指针
            while(pp->pNext != NULL)//
            {
                pp = pp->pNext;//pp往后搜索
            }
            //退出循环说明找到了最后一个节点pp
            st *last ;//创建结构体指针
            last = (st *)malloc(sizeof(st));//分配空间
            pp->pNext = last;
            last->corse = icore;
            last->num = inum;
            last->pNext = NULL;
        }
    }
    
    void main()
    {
        st *pfast = NULL;//定义一个头结点地址
    
        add(&pfast, 1, 1);//传入头结点地址,插入数据
        printf("%p
    ",pfast);
    
        add(&pfast, 2, 2);//传入头结点地址,插入数据
        printf("%p
    ",pfast);
    
        add(&pfast, 3, 3);//传入头结点地址,插入数据
        printf("%p
    ",pfast);
    
        add(&pfast, 4, 4);//传入头结点地址,插入数据
        printf("%p
    ",pfast);
    
        printf("%d,%f
    ",pfast->num,pfast->corse);
        printf("%d,%f
    ",pfast->pNext->num,pfast->pNext->corse);
    
        getchar();
    }

    我打印了一下

    add(&pfast, 1, 1);//传入头结点地址,插入数据
    经过这一句pfast的指向当然是fast

    我一直在怀疑

    add(&pfast, 2, 2);//传入头结点地址,插入数据
    经过这一句pfast的指向应该是last
    所以我怀疑
    printf("%d,%f
    ",pfast->pNext->num,pfast->pNext->corse);
    这一句应该会报错
    因为
    我感觉如果pfast的指向永远指向最后一个链表那么
    pfast->pNext->num
    就不存在
    可是我一打印,,,
    pfast的地址一直没变,,,,,永远指向第一个链表的地址
    看了上述文章以后才有所警觉
    其实如果一开始链表为空

    *p = fast;

    pfast确实指向了第一个链表

    可是接着

    add(&pfast, 2, 2);//传入头结点地址,插入数据

    只是把第一个链表的地址赋值给了pp,,但是并没有改变*p的指向

    下面的pp->pNext = last;只是给pp赋了新值

    就如同

    #include"stdio.h"
    #include"stdlib.h"
    
    void main()
    {
        int i = 4;
        int *p = &i;
        int *pp = p;//就只是变量间的赋值 就像int a=1; int b; b=a;a的值并没有改变
      
        int j=3;
        pp = &j;
    
        printf("%p
    ",p);
        printf("%p
    ",pp);
    }

    
    
    
    
    




  • 相关阅读:
    DocKer 创建容器 镜像端口映射失败
    Window中的Docker 拉取Mysql镜像 并在本地Navicate链接
    Mysql之主从复制
    Nginx 实现负载均衡
    如何将composer设置为全局变量?
    Linux安装telnet
    LINUX 安装扩展(笔记)
    PHP 开发 APP 接口 学习笔记与总结
    504 Gateway Time-out
    Luogu P1542包裹快递【实数域二分】 By cellur925
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/5771000.html
Copyright © 2020-2023  润新知