結論:
1、當普通變量需要在被調函數中使用並修改,並且在主調函數中也體現修改時就需要一級指針;
2、當一級指針變量需要在被調函數中使用並修改(變量的值就是一個地址數),並且在主調函數中也體現修改時就需要二級指針指針;
3、當N級指針變量需要在被調函數中使用並修改,並且在主調函數中也體現修改時就需要N+1級指針指針;
以鏈表的創建,遍歷爲例;
主調函數如下:
//主調函數
int test() {
Stu *head = NULL;
SlistCreat(&head);//創建鏈表
return 0;
}
遇見這種情況,那麼被調函數只能是這樣寫了,因爲要從NULL修改爲某個值
//創建單鏈表
//做到手動輸入id創建鏈表,當輸入-1時取消
int SlistCreat(Stu ** headP) {
if (headP == NULL)
{
return -2;//參數爲空
}
int data = 0;//用於輸入
int ret = 0;
*headP= (Stu *)malloc(sizeof(Stu));
Stu* pCur = *headP;//當前
pCur->id = -1;//第一個作爲頭節點不放入數據
Stu* pNew = NULL;//下一個
while (1)
{
printf("請輸入數據:");
scanf("%d",&data);
if (data==-1)
{
return -1;
}
pNew = (Stu*)malloc(sizeof(Stu));
if (pNew == NULL) {
ret = -1;
}
//第一個作爲頭節點不放入數據
pNew->id = data;
pNew->next = NULL;
//建立當前節點與這個節點的關係
pCur->next = pNew;
//讓當前節點指向下一個節點
pCur = pNew;
}
return ret;
}
因爲在主調函數中需要只是聲明瞭一個 Stu* 的變量 head;head在棧區又內存,但是這個內存中放入的是NULL而不是一個Stu變量的地址;
要在函數中給head賦值,並且在主調函數中還要生效,那麼就只能是幫 head的地址傳輸到被調函數中,即**headP = &head.
這個時候傳送的就是一個二級指針,類型爲 Stu** ;
被調函數在堆區創建了一個Stu 類型的空間以後,將這個地址賦值給*headP;這個時候head的值就從NULL變成了新創建的Stu空間地址;
如果主調函數換一種寫法,則可以不使用二級指針,因爲我們不需要把head從NULL進行修改;
int main() {
Stu *head = (Stu *)malloc(sizeof(Stu));
SlistCreat(head);//創建鏈表
return 0;
}
int SlistCreat(Stu * head) {
if (head == NULL)
{
return -2;//參數爲空
}
int data = 0;//用於輸入
int ret = 0;
Stu* pCur = head;//當前
pCur->id = -1;//第一個作爲頭節點不放入數據
Stu* pNew = NULL;//下一個
while (1)
{
printf("請輸入數據:");
scanf("%d",&data);
if (data==-1)
{
return -1;
}
pNew = (Stu*)malloc(sizeof(Stu));
if (pNew == NULL) {
ret = -1;
}
//第一個作爲頭節點不放入數據
pNew->id = data;
pNew->next = NULL;
//建立當前節點與這個節點的關係
pCur->next = pNew;
//讓當前節點指向下一個節點
pCur = pNew;
}
return ret;
}