C语言中的部分代码在这里:
typedef struct List {
double v;
struct List *next;
} List;
void deleteList (List **p) {
*p = (*p)->next;
}
我对删除列表功能的工作方式感到困惑。因此,参数是指向列表结构的指针。所以我们有:
p : pointer_2 --> pointer_1 --> List
所以我有一些问题:
- 那么函数 deleteList(( 中的 *p 是什么?是pointer_1还是别的什么?
- = 之前的 *p 是否与 = 符号后的 *p 相同?
- *p 和 (*p( 之间有区别吗?
假设我们有:
... la --> lb --> lc --> ld ....
并假设我们要删除磅。从理论上讲,我明白了。您将旁边的 la-> 更改为指向 lc。但我对指针业务感到困惑。 删除列表((的参数是什么? 是,删除列表(la->下一个(?还是别的什么? 然后是真正令人困惑的部分。 *p = ...应该是 la->next,因为这是我们想要更改的指针。 但是...(*p(->接下来,这不就是磅吗?但是我们想要lc?所以看起来 *p在同一行中有不同的含义?!
Let;首先正确写入函数。
void deleteList( List **head )
{
while ( *head != NULL )
{
List *tmp = *head;
*head = ( *head )->next;
free( tmp );
}
}
指向头节点的指针通过引用传递给函数。
如果你将定义这样的函数
void deleteList( List *head )
{
while ( head != NULL )
{
List *tmp = head;
head = head->next;
free( tmp );
}
}
也就是说,如果指针不会通过引用传递,则该函数将处理指针的副本。更改副本不会影响原始指针。
请考虑以下演示程序。
#include <stdio.h>
#include <stdlib.h>
void f( int *p )
{
p = NULL;
}
int main(void)
{
int x = 10;
int *px = &x;
printf( "Before the function call px = %pn", ( void * )px );
f( px );
printf( "Adter the function call px = %pn", ( void * )px );
return 0;
}
它的输出可能看起来像
Before the function call px = 0x7ffe26689a2c
Adter the function call px = 0x7ffe26689a2c
这是原始指针px
没有更改,因为该函数处理指针的副本。
要更改指针,您需要通过引用将其传递给函数
#include <stdio.h>
#include <stdlib.h>
void f( int **p )
{
*p = NULL;
}
int main(void)
{
int x = 10;
int *px = &x;
printf( "Before the function call px = %pn", ( void * )px );
f( &px );
printf( "Adter the function call px = %pn", ( void * )px );
return 0;
}
现在程序输出可能看起来像
Before the function call px = 0x7ffed60815fc
Adter the function call px = (nil)
在函数中,您需要取消引用参数以获取对传递的引用指针的访问权限。
*p = NULL;
^^^^
函数deleteNode
中也会发生同样的情况。要检查传递的指针是否等于 NULL,请使用以下语句
while ( *head != NULL )
^^^
要访问原始指针指向的节点的数据成员next
,您必须再次取消引用该参数以访问原始指针
*head
因此,此表达式生成原始指针。因此,接下来要访问数据成员,您必须编写
( *head )->next
您之所以使用括号,是因为后缀运算符 -> 具有更高的优先级,但您首先需要获取原始指针。
也就是说,如果你没有引用的指针,你会写
head->next
但是,当您有一个引用的指针时,当您有一个指向原始指针的指针时,要获得原始指针,您必须取消引用引用指针,例如
( *head )->next
可以在不接受指向头节点的指针的情况下编写函数。但在这种情况下,您应该在调用方中添加另一个语句,该语句会将指针头设置为 NULL。
例如
void deleteList( List *head )
{
while ( head != NULL )
{
List *tmp = head;
head = head->next;
free( tmp );
}
}
在来电者中,您需要写
List *head - NULL;
// the code thatf fills the list
deleteList( head );
head = NULL;
或者该函数可以返回一个空指针,例如
List * deleteList( List *head )
{
while ( head != NULL )
{
List *tmp = head;
head = head->next;
free( tmp );
}
return head;
}
在来电者中你可以写
List *head - NULL;
// the code thatf fills the list
head = deleteList( head );
定义通过引用接受指向头节点的指针的函数的优点是,函数的用户不需要记住自己将指针设置为 NULL。
deleteList
函数中:在传递到下一个元素之前,您必须释放指向的元素。
void deleteList (List **p) {
while(*p != NULL){
List *nextNode = (*p)->next;
free(*P);
*p= nextNode;
}
}