在最近的一段时间内,对一级指针和二级指针有一个疑惑,什么时候用二级指针,什么时候用一级指针?尤其是在二叉树的创建和不带头的单链表的头插时,前者参数列表使用的是一级指针,后者参数列表使用的是二级指针,伪代码如下:
二叉树的创建:
typedef struct BtNode
{
int val;
struct BtNode *left;
struct BtNode *right;
}BtNode;
BtNode *CreateSortBtTree(BtNode *root,int *val,int len)
int main()
{
int arr[] = { 56,43,15,78,59,100,99,30 };
int len = sizeof(arr) / sizeof(arr[0]);
BtNode *root = NULL;
root = CreateSortBtTree(root, arr, len);
}
不带头的单链表的头插:
typedef struct ListNode
{
int val;
struct ListNode *next;
}ListNode;
void LinkListPushFront(ListNode** pHead, int data)
{
assert(pHead);
ListNode* NewNode = LinkListCreatNode(data);
NewNode->_pNext= (*pHead);
*pHead = NewNode;
}
int main()
{
ListNode *List = NULL;
LinkListPushFront(&List);
}
在这两个代码中我发现:
BtNode *CreateSortBtTree(BtNode *root,int *val,int len) 的返回值为 BtNode*
而 void LinkListPushFront(ListNode** pHead, int data),返回值非 ListNode*
当我再一次使用 CreateSortBtTree 时,新的数据还可以接在树的跟(root)中,当然这个发现只是 表象;因此写了如下代码来说明使用二级指针的使用时机,代码实现如下:
void func(int *p)
{
p = NULL;
}
int main()
{
int a = 10;
int *p = &a;
cout << p << endl;
func(p);
cout << p << endl;
return 0;
}
针对此代码的分析:func函数的最初期望是将传来的指针 p置为NULL;函数执行后,p的值还是没有变化;即func函数没有达到期望的功能,分析如下:
实参p 和形参 p是两个不同地址的变量,他们只是值相同,当在函数func中将形参 p设置为NULL时,对实参p毫无影响,因为本就是不一样的两个变量。因此对代码实现如下修改,func函数就能预期目标:
void func(int **p)
{
*p = NULL;
}
int main()
{
int a = 10;
int *p = &a;
cout << p << endl;
func(&p);
cout << p << endl;
return 0;
}
得出结论:如要在另一个函数中修改本函数中的指针,需要用二级指针
而在代码:
void LinkListPushBack(Node** pHead, DataType data) //空链时需要2级指针
{
Node* NewNode = LinkListCreatNode(data);
assert(pHead);
//如果链表为空,则直接让头指针指向新申请的节点即可
if (*pHead == NULL)
{
*pHead = NewNode;
return;
}
//否则从头开始遍历链表,直到当前节点的指针域指向NULL,然后让当前节
//点的指针域指向新申请的节点即可
Node* pTail = *pHead;
while (pTail->_pNext)
{
pTail = pTail->_pNext;
}
pTail->_pNext = NewNode;
}
有可能链表的初始就是一个空链,当是空链时,对链表进行插入操作,即在另一个函数中修改本函数中的指针,需要用二级指针,所以这就是为什么不带头结点的单链表中不必使用二级指针的原因!因为链已经由头节点标记了,不必要考虑修改指针的值的问题。
结合上述在二叉树的创建和不带头的单链表的头插时,前者参数列表使用的是一级指针,后者参数列表使用的是二级指针的问题,得出如下结论:
1.如要在另一个函数中有可能修改本函数中的指针,需要用二级指针
2.若返回值为void等内置类型时,需要用二级指针;否则可考虑用一级指针,如:
BtNode *CreateSortBtTree(BtNode *root,int *val,int len)