删除 C 中带有指针指向指针的列表



C语言中的部分代码在这里:

typedef struct List {
double v;
struct List *next;
} List;
void deleteList (List **p) {
*p = (*p)->next;
}

我对删除列表功能的工作方式感到困惑。因此,参数是指向列表结构的指针。所以我们有:

p : pointer_2 --> pointer_1 --> List

所以我有一些问题:

  1. 那么函数 deleteList(( 中的 *p 是什么?是pointer_1还是别的什么?
  2. = 之前的 *p 是否与 = 符号后的 *p 相同?
  3. *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;
}
}

相关内容

  • 没有找到相关文章

最新更新