Reputation: 15
I'm currently working on a question from a book that I've been reading titled "How to program in C". The question reinforces the use of linked list data structures. From what the book explained, linked list data structures have 3 main functions "delete", "insert", and "print". However, this question specifically states that we should keep all manipulations inside of the "main" function (so I don't have the ability to copy the code directly from the book).
This is the question from the book:
Assume that the list pointed to by
startPtr
currently consists of 2 nodes—one containing "Jones" and one containing "Smith". The nodes are in alphabetical order. Provide the statements necessary to insert in order nodes containing the following data for lastName and grade:
"Adams" 85.0
"Thompson" 73.5
"Pritchard" 66.5
Use pointers
previousPtr
,currentPtr
andnewPtr
to perform the insertions. State whatpreviousPtr
andcurrentPtr
point to before each insertion. Assume thatnewPtr
always points to the new node, and that the new node has already been assigned the data.
This is the code I currently have:
//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("%s\n%d",currentPtr->lastName,currentPtr->grade);
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
else
{
puts("Critical Error encountered closing program!");
break;
}
}
}
There are two things I'm trying to understand:
GradeNodePtr currentPtr = *startPtr;
. The compiler is stating that the two variables are incompatible. My assumption was that you declare currentPtr equal to *startPtr with the use of the indirection operator because the currentPtr needed to point to the data inside of the startPtr and not the memory address.Also, if there's anything that you think should be added to the code after reading the question please let me know.
Thanks!
Upvotes: 0
Views: 74
Reputation: 181419
- There is a synonym for the structure keyword "GradeNode" and "*GradeNode".
No, there isn't. As a minor matter, "GradeNode" is no kind of keyword, but rather one of the type names being declared. But the main point is that *GradeNodePtr
is two separate things, *
and GradeNodePtr
.
This part of the code was given by the book. Why was the indirection operator used with "*GradeNode"?
In that context, it is not the indirection operator. It is part of the name of type GradeNode *
, which, in light of the preceding typedef
, is an alias for type struct gradeNode *
.
How does this effect variables that are declared with this structure type?
It's not a structure type, it's a pointer (to structure) type. And of course it has the effect that variables declared with that type take pointer values, not structure values.
- Upon compiling the code I receive an error for the following statement:
GradeNodePtr currentPtr = *startPtr;
. The compiler is stating that the two variables are incompatible.
Indeed so. This is in part a manifestation of the issue I remarked upon in comments, that typedefs that conceal pointer nature are confusing and should be avoided.
My assumption was that you declare currentPtr equal to *startPtr with the use of the indirection operator because the currentPtr needed to point to the data inside of the startPtr and not the memory address.
Consider it strictly from a type analysis point of view. The type of startPtr
is GradeNodePtr
, also known as struct gradeNode *
. The type of currentPtr
is also GradeNodePtr
. The types are correct for assignment of one to the other without any dereferencing. The result of dereferencing a pointer has a different type than the pointer itself does (one less level of indirection), so your attempt cannot be type-correct.
But also consider it semantically. What you seem to mean by "the
data inside of the startPtr" is the data to which startPtr
's (pointer) value points. startPtr
's value is the address of that data. You do want currentPtr
to point to that same data. The data itself is *startPtr
, so its address is &*startPtr
. Thus, you could write
GradeNodePtr currentPtr = &*startPtr;
, but it is equivalent and more idiomatic to write
GradeNodePtr currentPtr = startPtr;
And lo! As we already discussed, startPtr
has the correct type for assignment to currentPtr
without dereferencing, so everything is consistent.
Upvotes: 0