二级指针

本文通过四个具体案例介绍二级指针在C/C++中的实际应用,包括字符串交换、链表节点删除、二叉搜索树转换为双向链表及内存分配错误示例。深入探讨了二级指针如何解决特定问题并提高程序效率。
int **p;
int *q;
int a;
q=&a;
p=&q;//p为指向指针q的指针;
//*p=q,为指向a的指针
//**p=*q=a

二级指针作为函数参数的作用:在函数外部定义一个指针p,在函数内给指针赋值,函数结束后对指针p生效,那么我们就需要二级指针。
二级指针在函数中的应用:
1,交换字符串变量

/*
    a、b为指向str_a、str_b的指针
    交换字符串即交换str_a、str_b的指向
    更改指针的指向即更改指针内存中的值
    传入函数时需要获取地址进行更改,不然不会改变实参的值,与变量是一个道理
*/
void swap_str(char **a , char **b)
{
    char *temp = *a;
    *a = *b;
    *b = temp;
}

int main(void)
{
    char *str_a = "hello world";
    char *str_b = "world hello";
    swap_str(&str_a , &str_b);
    printf("%s %s\n",str_a,str_b);
    system("pause");
    return 0;
}

2,O(1)时间删除链表节点

/*
    O(1)时间删除链表节点,将待删除节点的Next复制给该节点,并删除Next节点
    当链表中只有一个节点时,需要改变头指针的指向,指向NULL
    所以需要传入指向头指针的指针
*/
void DeleteNode(ListNode** pListHead,ListNode* pToBeDeleted)
{
    if(!pListHead||!pToBeDeleted)
    {
        return;
    }
    //待删除节点为中间节点(有Next节点)
    if(pToBeDeleted->m_pNext != NULL)
    {
        ListNode* pNext =pToBeDeleted->m_pNext;
        pToBeDeleted->m_nValue=pNext->m_nValue;
        pToBeDeleted->m_pNext=pNext->m_pNext;
        delete pNext;
        pNext=NULL;
    }
    //链表只有一个节点,删除头节点
    if(*pListHead==pToBeDeleted)
    {
        delete pToBeDeleted;
        pToBeDeleted=NULL;
        *pListHead=NULL;
    }
    //删除尾节点
    else
    {
        ListNode *pNode=*pListHead;
        while(pNode->m_pNest!=pToBeDeleted)
        {
            pNode=pNode->m_pNext;
        }
        pNode->m_pNext=NULL;
        delete pToBeDeleted;
        pToBeDeleted=NULL;
    }
}

3,二叉搜索树转换为有序的双向链表

/*
  递归
  中序遍历的顺序,左子树转换后的最后一个节点与根节点相连,
  根节点与右子树转换后的第一个节点相连
*/
BinaryTreeNode* Convert(BinaryTreeNode* pRootNode)
{
    BinaryTreeNode* pLastNodeInList=NULL;
    ConvertNode(pRootNode,&pLastNodeInList);//传入二级指针
    BinaryTreeNod* pHeadofList=pLastNodeInlist;
    while(pHeadofList->mLeft!=NULL & pHeadofList!=NULL)
    {
        pHeadofList=pHeadofList->mLeft;
    }
    return pHeadofList;
}

//需递归调用函数,改变pLastNodeInList的指向,所以传入二级指针
void ConvertNode(BinaryTreeNode* pNode,BinaryTreeNode** pLastNodeInList)
{
    if(pNode==NULL)
        return;
    BinaryTreeNode* pCurrent=pNode;
    if(pCurrent->mLeft!=NULL)
    {
        ConvertNode(pNode->mLeft,pLastNodeInList);
    }
    pCurrent->m_Left=*pLastNodeInList;
    if(*pLastNodeInList != NULL)   //不要忘记判断节点存在
    {
        pLastNodeInList->mRight=pCurrent;
    }
    *pLastNodeInList=pCurrent;
    if(pCurrent->mRight!=NULL)
    {
        ConvertNode(pNode->mRight,*pLastNodeInList);
    }
}

4,改错

void GetMemory( char *p )//此处应传入二级指针
{  
    p = (char *) malloc( 100 );
} 
void Test( void )  
{  
    char *str = NULL;  
    GetMemory( str );   
    strcpy( str, "hello world" );  
    printf( str ); 
}
/*
Test函数使用str作为形参传入,会产生指针的拷贝str_cpy即p传入GetMemory中,此时所分配的内存的地址是给拷贝的指针p。
*/
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值