c语言 - 链表中的底层指针



我目前正在研究我一直在读的一本书中的一个问题,标题为"如何在C中编程"。这个问题强化了链表数据结构的使用。根据本书的解释,链表数据结构有3个主要功能"删除","插入"和"打印"。但是,这个问题特别指出我们应该将所有操作保留在"main"函数中(所以我无法直接从书中复制代码)。

这是书中的问题:

假设startPtr指向的列表当前由 2 个节点组成 — 一个包含"Jones",另一个包含"Smith"。节点按字母顺序排列。提供在顺序中插入包含以下数据的节点所需的语句 姓氏和等级:

"Adams" 85.0
"Thompson" 73.5
"Pritchard" 66.5

使用指针previousPtrcurrentPtrnewPtr来执行插入操作。陈述什么previousPtrcurrentPtr指向每次插入之前。假设newPtr总是 指向新节点,并且已为新节点分配了数据。

这是我目前拥有的代码:

//fig 12_4.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct gradeNode{
char lastName[20];
double grade;
struct gradeNode *nextPtr;
};
typedef struct gradeNode GradeNode;
typedef GradeNode *GradeNodePtr;
void insert(GradeNodePtr);
int main(void)
{
//part a
GradeNodePtr startPtr = NULL;
//part b
GradeNodePtr newPtr = malloc(sizeof(GradeNode));
startPtr = newPtr; 
// checking to see if memory was allocated properly 
if(newPtr != NULL)
{
newPtr->grade = 91.5;
strcpy(newPtr->lastName,"Jones");
newPtr->nextPtr = NULL;
}
//part c
//Creating the previousPtr, currentPtr, and NewPtr to make insertions
GradeNodePtr previousPtr = NULL;    // intializing both the previousPtr and currentPtr to begin insertion process
GradeNodePtr currentPtr = *startPtr;

for(int i; i>4; i++)
{
if(currentPtr != NULL)
{
puts("Please enter a last name and grade");
scanf("%sn%d",currentPtr->lastName,currentPtr->grade);
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;   
}
else
{
puts("Critical Error encountered closing program!");
break;
}
}
}

我试图理解两件事:

  1. 结构关键字"GradeNode"和"*GradeNode"有一个同义词。这部分代码是由书中给出的。为什么间接寻址运算符与"*GradeNode"一起使用?这对使用此结构类型声明的变量有何影响?
  2. 编译代码时,我收到以下语句的错误:GradeNodePtr currentPtr = *startPtr;.编译器声明这两个变量不兼容。我的假设是,您使用间接寻址运算符声明 currentPtr 等于 *startPtr,因为 currentPtr 需要指向 startPtr 内部的数据而不是内存地址。

另外,如果您在阅读问题后认为应该将任何内容添加到代码中,请告诉我。

谢谢!

  1. 结构关键字"GradeNode"和"*GradeNode"有一个同义词。

不,没有。作为一件小事,"GradeNode"不是一种关键字,而是被声明的类型名称之一。 但重点是*GradeNodePtr是两个独立的东西,*GradeNodePtr

这部分代码是由书中给出的。为什么 与"*GradeNode"一起使用的间接运算符?

在这种情况下,它不是间接寻址运算符。 它是类型GradeNode *名称的一部分,根据前面的typedef,它是类型struct gradeNode *的别名。

这是如何影响的 使用此结构类型声明的变量?

它不是结构类型,而是指针(指向结构)类型。 当然,它的效果是使用该类型声明的变量采用指针值,而不是结构值。

  1. 编译代码时,我收到以下语句的错误:GradeNodePtr currentPtr = *startPtr;.编译器是 声明这两个变量不兼容。

确实如此。 这部分体现了我在评论中提到的问题,即隐藏指针性质的 typedef 令人困惑,应该避免。

我的假设是 您声明当前 Ptr 等于 *startPtr 使用 间接寻址运算符,因为当前 Ptr 需要指向 startPtr 中的数据,而不是内存地址。

严格从类型分析的角度考虑它。startPtr的类型是GradeNodePtr,也称为struct gradeNode *currentPtr的类型也很GradeNodePtr。 这些类型对于将一个类型分配给另一个类型是正确的,无需任何取消引用。 取消引用指针的结果具有与指针本身不同的类型(间接寻址级别少一个),因此您的尝试不能类型正确。

但也要从语义上考虑。 你所说的"这似乎是什么意思 startPtr内的数据"是startPtr(指针)值指向的数据。startPtr的值该数据的地址。 您确实希望currentPtr指向相同的数据。 数据本身是*startPtr的,所以它的地址&*startPtr。 因此,你可以写

GradeNodePtr currentPtr = &*startPtr;

,但写起来是等效的,更惯用

GradeNodePtr currentPtr = startPtr;

瞧!正如我们已经讨论过的,startPtr具有正确的类型,可以在不取消引用的情况下分配给currentPtr,因此一切都是一致的。

相关内容

  • 没有找到相关文章

最新更新