当前位置: 首页 > 知识库问答 >
问题:

结构和指针指向指针

蔺山
2023-03-14

我正在学习链表,以及如何在C中使用结构和指针创建链表。下面我举一个例子。据我所知,被调用的push()将头节点所在的结构的开始内存位置作为参数传递。push()函数的参数将结构节点作为指向指针的指针,因此它作为引用传递,而不是实际副本。因此,我们的结构节点**headref的第一个指针只是指向头部节点的内存位置的指针,第二个指针指向该值,该值是头部节点指向的下一个内存位置。我们通过为结构节点分配一些内存,在结构节点内创建一个名为newnode的新节点。然后,我们在这个节点内创建一个int类型的数据。

好吧,假设我所说的一切都是正确的,下一部分就是我所困惑的。

newNode->next= *headRef; 

我可以理解的是,这一行取消了对Headref的引用,所以这将使Headref指向头节点。然后我们有一个指针操作,其中Headref指向的也将是我们的指针下一个指向的。基于此,我们的新节点(新节点)中的下一个指针将指向头指针。

我也感到困惑的下一行是:

*headRef = newNode;

取消引用的headref指针指向的是头部节点,现在将指向我们的新节点。

基于此,应该有一个名为newnode的新节点,其中包含int数据和下一个指针,将我们的newnode链接到头部。然后是headref指针(或者是head节点?)将指向新节点。我知道这是不正确的,因为newnode旁边的指针应该指向第二个节点,这样我们的newnode可以在结构中链接。我也不相信我理解了上面两行代码中指向指针的指针和去引用。

代码:

void Push(struct node** headRef, int data) {
  struct node* newNode = malloc(sizeof(struct node));

  newNode->data = data;
  newNode->next = *headRef;
  *headRef = newNode;
}

void PushTest(void) {
  struct node* head = BuildTwoThree(); // suppose this returns the list {2, 3}

  Push(&head, 1);
  Push(&head, 13);
  // head is now the list {13, 1, 2, 3} 
}

共有3个答案

汪高岑
2023-03-14

好吧。我想我可以解释。

head是链表的头指针<代码>头EF指向头部。因此,*headRef是头指针(通过引用传递)。

所以newNode-

现在,在这一行中,*head Ref=newNode;*head Ref被分配了newNode的值,因此head现在在原始结构中被更改为newNode

当您通过

方弘
2023-03-14

你实际上既正确又不正确。推送函数在列表的头部添加一个新节点。在这个函数被调用之后,新节点是新的head,前一个head节点现在是列表中的第二个(下一个)节点。所以你的观察是正确的,但你的结论不是。

我建议您在调试程序中一步一步地检查代码,同时观察所有指针及其内容,看看会发生什么。这可能会让你更清楚。

阙奇思
2023-03-14
void Push(struct node** headRef, int data) {

headRef包含结构节点所在地址的地址。它是PushTest函数中head变量的地址。

struct node* newNode = malloc(sizeof(struct node));

这里我们创建了一个新节点。它包含节点结构所在的内存地址。

newNode->data = data;

将newNode的数据设置为传递到Push函数-OK的数据参数的值。

newNode->next = *headRef;

设置新节点-

 void Push(struct node* head, int data) {
 ...
 newNode->next = head;

接下来,我们需要将head变量更改为newNode。如果head变量是通过引用传递的,我们可以简单地编写如下代码,如C中所示:

void Push(struct node* &head, int data) {
...
head = newNode;

但在普通C中,我们必须传递head变量所在的地址,因此我们可以将指向我们在Push函数中创建的结构newNode的指针写入该地址:

*headRef = newNode;

相当于将newNode指针写入地址位于headRef变量内部的变量

你的逻辑有一个问题:

我们的ush()函数的参数将一个结构节点作为指针,因此它作为引用传递,而不是实际的副本。

实际上,我们传递一个临时变量的副本,该副本包含节点变量的地址,而不是引用。在C中有一个passbyreference方法,它使用符号AND来声明传递给函数的变量是引用,而不是原始变量的副本。

 类似资料:
  • Go 语言中指向结构体的指针和 C 语言一样 结构体和指针 创建结构体指针变量有两种方式 package main import "fmt" type Student struct { name string age int } func main() { // 创建时利用取地址符号获取结构体变量地址 var p1 = &Student{"lnj", 33}

  • 问题内容: 我不理解以下代码的行为。在创建作为结构指针切片的匹配结构列表时,代码始终会打印原始数组的最后一个元素(实际上不是匹配项),它会打印12和12。但是,如果将匹配项更改为[]窗口小部件代替[] * Widget,然后将输出10和11。 为什么是这样? 问题答案: 那是因为当您使用指针时,您将添加到数组。 请注意,实际上这是循环中使用的局部变量,因此,这不是您要添加到数组中的地址。 (即使变

  • 问题内容: 另一个链接的问题是在使用strcpy()时出现细分错误吗? 我有一个结构: 如何初始化指向上述类型结构的指针,以及如何初始化指向结构内部的10个字符串(incall [])的指针。 我首先初始化字符串,然后初始化结构。 谢谢。 编辑:我猜我用错了字,应该说分配。实际上,我将此结构作为线程的参数传递。线程数不是固定的,作为参数发送的数据结构对于每个线程都必须是唯一的,并且是“线程安全的”

  • 我正在学习如何在C中使用并写了以下示例: 问:是否保证在所有情况下指向一个结构的指针都是指向它的第一个元素的完全相同的指针? 在这种特殊的情况下,它能像我预期的那样工作,但我不确定它是否能得到保证。编译器可以在开始时插入一些填充吗? 我唯一能找到的关于结构类型布局的是N1570的类型: 结构类型描述了一组按顺序分配的非空成员对象(在某些情况下,还包括一个不完整的数组),每个对象都有一个可选的指定名

  • 问题内容: 我看到一些具有以下构造的代码示例: 我有C ++背景,对我来说似乎是错误。这种结构的语义是什么?是否在堆栈或堆上分配了新点? 问题答案: Go执行指针转义分析。如果指针转义了本地堆栈(在这种情况下会这样做),则在堆上分配对象。如果它没有对本地函数进行转义,则编译器可以自由地在堆栈上分配它(尽管它不作任何保证;这取决于指针转义分析是否可以证明该指针在该函数中保持局部)。

  • 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为 二级指针,或者 指向指针的指针。 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: 指针变