| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1211 人关注过本帖, 1 人收藏
标题:关于二级指针的疑问
只看楼主 加入收藏
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
结帖率:58.18%
收藏(1)
已结贴  问题点数:40 回复次数:29 
关于二级指针的疑问
wmf2014版主以前写过的
void f(int **p)
{
    int i=10;
    *p=&i;  //如果这里改为NULL,则会在printf时显示内存不能read
}
void main()
{
    int i=5,*p=&i;
    f(&p);
    printf("%d\n",*p);  //这样一来,虽然可以正常显示10,但实际指针p已经是个野指针了
}

要想改变指针变量地址需要二级指针,今天我没事忽然想为什么调用链表插入函数时没用二级指针,这是为什么?
两个指针变量间的赋值是改变地址吧,可形参并不会改变实参的值啊。。。

再看下面这个求多项式和的程序,每次都将新项加入表尾,
void Attach ( int coef,int expon,PtrPoly *PtrRear )就用到了二级指针改变表尾指针的值,以记录更新后表尾的地址。


程序代码:
#include <stdio.h>
#include <stdlib.h>

typedef struct node PolyNode ;
typedef struct node* PtrPoly ;

struct node
{
    int coef ;
    int expon ;
    struct node* next ;    
} ;

//建立一个不带表头结点的链式多项式


int Compare( int e1,int e2 )
{
    if(e1>e2) return 2 ;
    else if(e1<e2) return 1 ;
         else return 0 ;
}



PtrPoly Create( int N)
{
    int i ;
    PtrPoly PtrCurrent,PtrPrevious ;
    PtrPoly head ;

    head=NULL;

    for(i=0 ; i<N ; i++)
    {
        PtrCurrent=(PtrPoly)malloc( sizeof(PolyNode) ) ;

        PtrCurrent->next = NULL ;
        scanf("%d" , &PtrCurrent->coef) ;
        scanf("%d" , &PtrCurrent->expon) ;

        if( head==NULL )
            head=PtrCurrent ;
        else
            PtrPrevious->next = PtrCurrent ;

           PtrPrevious = PtrCurrent ;
    }
    return head;    
}


void Attach ( int coef,int expon,PtrPoly *PtrRear )
{
    /*记录尾项位置才能将未处理完的
    另一个多项式的项依次复制到结果多项式,
    并且每次改变的都是表达式尾项的值,我们需要改变的是结点指针的地址*/
    PtrPoly p;
    
    p = (struct node*)malloc( sizeof (struct node) );
    p->coef = coef ;
    p->expon = expon ;

    // 将p指向的新结点插入到当前结果表达式尾项的后面
    (*PtrRear)->next = p ;
    // 修改PtrRear的值
    *PtrRear = p ;        
}


PtrPoly Add( PtrPoly p1,PtrPoly p2 )
{
    PtrPoly front,rear,temp;

    //为了方便链表插入,先用一个临时空结点作为结果多项式链表表头
    rear = ( PtrPoly )malloc( sizeof(PolyNode) ) ;
    front = rear ;

    while( p1&&p2 )
    {
        switch ( Compare(p1->expon,p2->expon) )
        {
            case 2 ://e1>e2
                Attach( p1->coef , p1->expon , &rear ) ;
                p1 = p1->next ;
                break ;
            case 1 ://e1<e2
                Attach( p2->coef , p2->expon , &rear ) ;
                p2 = p2->next ;
                break ;
            case 0 :
                if( (p1->coef + p2->coef) != 0 ) 
                Attach((p1->coef+p2->coef) , p1->expon , &rear ) ;
                p1 = p1->next ;
                p2 = p2->next ;
                break ;
        }
    }

    for( ; p1 ; p1=p1->next) Attach( p1->coef , p1->expon , &rear ) ;
    for( ; p2 ; p2=p2->next) Attach( p2->coef , p2->expon , &rear ) ;

    rear->next = NULL ;
    temp = front ;
    front = front->next ; //链表头结点为空,指向下一个结点即指向结果多项式第一个非0项
    free( temp ) ;

    return front ;

}
搜索更多相关主题的帖子: 多项式 
2015-11-07 17:30
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:10 
參考以下代碼的用法:
程序代码:
// 刪除指定的結點node,返回鏈頭
// 對單向鏈表,爲了查尋前面的元素,必須從鏈表開始檢索,所以需要傳入鏈頭
Node* DeleteNode(Node** head, Node* node)

 {
     if (node == *head)
     {
         *head = node->Next;
     }
     else
     {
         Node* previous = NULL;      // 前一個元素
        Node* p = *head;            // 遍歷指針
        while ((p != NULL) && (p != node))
         {
             previous = p;
             p = p->Next;
         }
         previous->Next = node->Next;
     }
     free(node);

     return *head;

 }


調用代碼:
DeleteNode(&linkHead, node->Next);

授人以渔,不授人以鱼。
2015-11-07 17:35
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
void f(int **p)
 {
     int i=10;
     *p=&i;  //如果这里改为NULL,则会在printf时显示内存不能read
 }

之所以在後續printf()時出錯,是因爲你此處返回的是指向局部變量的指針。以前有人測試過,在某些環境中,偶爾可以“正確”顯示這樣返回的數據。

授人以渔,不授人以鱼。
2015-11-07 17:43
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
回复 3楼 TonyDeng
程序代码:
#include <stdio.h>
int main()
{
    int *p,**a;
    int d=1;
    p=&d;
    
    a=p;
  
    
    printf("%x   %d\n",p,*p);
    printf("%x   %d\n",a,a);
    printf("%x   %d\n",*a,*a);
        printf("%x   %d\n",**a,**a);
    printf("\n");

    *a=p;

    printf("%x   %d\n",a,a);
    printf("%x   %d\n",*a,*a);    
    printf("%x   %d\n",**a,**a);
}


这是我一开始认为的输出结果,
图片附件: 游客没有浏览图片的权限,请 登录注册


然后运行后结果与我想的不同,版主能解释下么?
图片附件: 游客没有浏览图片的权限,请 登录注册

2015-11-08 22:14
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
收藏
得分:10 
运行看看一下
2015-11-09 08:08
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
回复 3楼 TonyDeng
其实我主要想问的是为什么链表的插入不需要用二级指针。
每个链表结点都保存着数据和地址,改变表结点中的地址是改变空间的内容,并不是说改变地址就得用二级指针。关键看是改变空间的地址还是改变空间的内容。
2015-11-09 10:25
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
回复 5楼 tlliqi
程序代码:
#include <stdio.h>
int main()
{
    int *p,**a;
    int d=1;
    p=&d;
    
    a=p;
  
    
    printf("%x   %d\n",p,*p);
    printf("%x   %d\n",a,a);
    printf("%x   %d\n",*a,*a);
        //printf("%x   %d\n",**a,**a);
    printf("\n");

    *a=p;

    printf("%x   %d\n",a,a);
    printf("%x   %d\n",*a,*a);    
    printf("%x   %d\n",**a,**a);
}

已经运行了,看图

图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2015-11-9 10:35编辑过]

2015-11-09 10:26
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
以下是引用tlliqi在2015-11-9 08:08:42的发言:

运行看看一下

不好意思,我忘记把第四个输出语句注释掉,复制代码的时候忘记了
2015-11-09 10:36
令狐少侠56
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:320
专家分:175
注 册:2014-4-10
收藏
得分:0 
回复 2楼 TonyDeng
这里的调用函数为什么是DeleteNode(&linkHead, node->Next);不应该是DeleteNode(&linkHead, node);么?
还有为什么是 previous->Next = node->Next;?

我后来是画了图形,然后觉得链表的插入不需要返回头指针。
若果是删除,比如删除空间2,觉得就是让我用红笔写的p->next的值变成003,
释放以002为地址的空间后对链表不造成破坏。
然后因为002是保存在一个空间里,而p->next是以p为地址中的内容,换句话说p->next是引用p为址的内容,与一级指针的引用
类似,这样我是通过改变001地址中的内容改变变量的值,形参真实改变了实参。
我现在已经糊了。。。。
这里面空间1的地址是001,空间2的地址是002,以此类推。

图片附件: 游客没有浏览图片的权限,请 登录注册

图片附件: 游客没有浏览图片的权限,请 登录注册


[此贴子已经被作者于2015-11-9 22:36编辑过]

2015-11-09 22:29
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
我這兩天都在外面,後天回去詳細跟你說。

授人以渔,不授人以鱼。
2015-11-09 22:32
快速回复:关于二级指针的疑问
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026022 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved