在如下代码中,我的test函数要将结构体指针作为实参传递给function函数插入值,那么为什么必须传递二级指针才能正确进行插入呢
head_list.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct SListNode {
DataType data;
struct SListNode* next;
}node;
void SListPrint(node* phead);
void SLIitPushBack(node** pphead, DataType x);
function.c
void SLIitPushBack(node** pphead, DataType x) {
node* newnode = (node*)malloc(sizeof(node));
newnode->data = x;
newnode->next = NULL;
//找尾结点指针
if (*pphead == NULL) {//phead传过来的时候就是空的
*pphead = newnode;
}
else {
node* tail = *pphead;
while (tail->next != NULL) {
tail = tail->next;
}
//尾节点链接新的结点
tail->next = newnode;
}
}
test.c
void testpushback() {
node* plist = NULL;
SLIitPushBack(&plist, 1);
SLIitPushBack(&plist, 2);
SLIitPushBack(&plist, 3);
SLIitPushBack(&plist, 4);
SLIitPushBack(&plist, 5);
SLIitPushBack(&plist, 6);
SListPrint(plist);
}
理解:
在C语言中,如果只传递实参而不传递实参的地址,那么在对形参做出改变时就不会影响实参,所以必须传递实参的地址。
其中很重要的一点就是:如果传入的是地址,形参前边就要加 * ,如果传的是临时拷贝,那么形参的数据类型就和实参一致
看回上面的代码,已知我需要改变实参的值,那么实参(&plist)的数据类型就是node**, 而参数的传递中实参和形参的数据类型必须一致,所以我的形参就必须是node**类型的,即node ** = pphead,也就是说pphead = &plist,在函数体中改变形参就是改变实参,所以必须解引用才能得到plist,即*pphead = plist
结论:
所以如果要对实参的地址做出改变,那么形参就需要比实参多一个星号,而且实参的传递必须是地址
原理就是实参和形参的数据类型必须相一致
关于二级指针的理解出现了问题,纠正:二级指针