Pointer to a structure as a structure itself - c

I have the following snippet of code:
typedef int T;
typedef struct Node *pNode;
typedef struct Node{
T item;
pNode next;
}Node;
The first and the last typedef statement are pretty clear to me, but I don't seem to understand the second.
Why is it defined as a structure when it's just a pointer to a Node? And why is it not referred to as a pointer in the pNode next; statement?

This:
typedef struct Node *pNode;
creates pNode as an alias for the type struct Node *, i.e. "pointer to struct Node".
I'm opposed to "hiding" pointers with typedef, but this is quite common.
I'd write it:
typedef struct Node {
int item;
struct Node *next;
} Node;

Related

Typedef/Global structure in C, without using "typedef"?

Language: C
I wish I knew how to reference this in the title better. I recently came across this piece of code concerning struct definition, and I am unfamiliar with the syntax, particularly the "*Node" portion. Might someone please help me understand what's going on? Why/how aren't we using typedef/ is this something else entirely? For further reference, the source code uses "Node" (no *asterisk) within some function definitions without passing or declaring any "Node" variables within the function itself. This leads me to think it's some sort of global variable declaration. Any help appreciated!
struct node {
char word[MAX];
struct node *left;
struct node *right;
} *Node;
In struct declaration, the right brace that terminates the list of members may be followed by list of variables. So, here
struct node {
char word[MAX];
struct node *left;
struct node *right;
} *Node;
Node is of type struct node * which can hold pointer of any struct node type variable. That means, if you have
struct node anode;
you can do
Node = &anode;
If you have this kind of global struct declaration followed by variables after right brace, that terminates the list of members, then all those variable are global variables of that struct type. That means, if you have
struct node {
char word[MAX];
struct node *left;
struct node *right;
} Node, *ptrNode;
and this struct node type defined globally then both Node and ptrNode are global variables.
Don't confuse this with typedef. typedef is used to create an alias name for another data type.
For e.g.
tyepdef struct node {
char word[MAX];
struct node *left;
struct node *right;
} stNode, *ptrStNode;
Now the stNode is an alias of struct node and ptrStNode is alias of struct node *. That means, you can use them to declare variables of struct node and struct node* type respectively.
For struct node type, this
stNode aNode;
is same as
struct node aNode;
and for struct node * type, this
ptrStNode ptrNode;
is same as
stNode *ptrNode;
is same as
struct node *ptrNode;
Hope this helps.
Code defines a pointer name Node to a struct. See declare Node as pointer to struct node;
Perhaps it is more understandable broken down into two step equivalent code.
// Define `struct node`
struct node {
char word[MAX];
struct node *left;
struct node *right;
};
// Define & declare a pointer: `Node`
struct node *Node;
Why/how aren't we using typedef/ is this something else entirely?
Author did not want to define an alias for the type struct main via typeface. Just to define a type called struct main and declare a pointer.

Typdef in C, using * what does this do?

I've used typedef before, but I've never used one with a pointer. What effect does this have on the typedef?
Code for reference:
typedef struct node NODE, *PNODE, **PPNODE;
Instead of using struct node you can replace it with NODE
Instead of using struct node* you can replace it with PNODE
Instead of using struct node** you can replace it with PPNODE
The statement can be broken down to
typedef struct node NODE;
typedef struct node* PNODE; // PNODE is pointer to node
typedef struct node** PPNODE; // PPNODE is pointer to pointer to node
The single typedef line defines three type aliases. The second and third are "pointer to node" and "pointer to pointer to node" respectively.
It may be easier to understand if split into three statements:
typedef struct node NODE;
typedef struct node *PNODE; // PNODE is pointer to node
typedef struct node **PPNODE; // PPNODE is pointer to pointer to node
It doesn't affect the typedef, it affects the type.
PNODE is a pointer to struct node
PPNODE is a pointer to a pointer to struct node

typedef struct used for definition

Why does using Node(..Node{..), as below, while defining a struct type gives a compile time error.
typedef struct node Node;
Node{
int data;
Node *next;
};
There is a very basic concept that is confusing me, please advise or refer me to a relevant link.
Typedef is used to provide an alias to some another type. It is not a macro, it is not substituted for something at the place of use.
The correct definition might be:
typedef struct node {
int data;
struct node* next;
} Node;
At the very least, you need it to say
typedef struct node Node;
struct Node{
int data;
Node *next;
};
However, you can do this:
typedef struct {
int data;
struct Node *next;
}Node;
Now you can easily create instances of the struct Node you have created by:
Node node, *pNode;
Where node is the name of a new variable of type struct Node.
and *pNode is a pointer to the same, initialized by:
pNode = &node;

What is the purpose of the first "node" in the declaration: "typedef struct node { - - - } Node;"?

I am studying code examples from my professor in order to become better acquainted with linked data structures.
In our linked-list.c example the professor defines a type Node as follows:
typedef struct node {
int data;
struct node *next;
} Node;
What's the point of the lower case node? I was under the impression that you could just write, for example:
typedef struct {
int data;
struct node *next;
} Node;
and then use Node as its own type. Does it have something to do with the fact that if you don't include a lower case node then when the compiler is evaluating the code it will not be able to understand what is meant by "struct node *next"?
Take a look at this declaration:
struct node {
int data;
struct node *next;
};
typedef struct node Node;
This can be combined into a single statement (simplifying a declaration):
typedef struct node {
int data;
struct node *next;
} Node;
Does it have something to do with the fact that if you don't include a lower case node then when the compiler is evaluating the code it will not be able to understand what is meant by "struct node *next"?
Yes.
The node in struct node is the tag of the struct type. If you give the struct a tag, you can refer to that type from the moment on the tag is complete, so in
typedef struct node {
int data;
struct node *next;
} Node;
the struct node *next; declares a member next that is a pointer to the struct type being defined. The typedef name Node is not available before the ; ending the definition is reached.
If you omit the tag, you cannot refer to the type being defined in any way before the typedef is complete, so in
typedef struct {
int data;
struct node *next;
} Node;
the line struct node *next; declares a new, unrelated, incomplete struct type with the tag node that next points to.
That's valid, but nothing about struct node is known (unless it is defined somewhere else), so you can't use the next pointer without casting it to a pointer to a complete type everywhere (not quite everywhere, Node foo; foo.next = malloc(12); etc. would still work).
He is defining a temporary name for the node because he is using a well know technique to avoid writing struct node on the declaration of each struct object.
If he would just do:
struct node {
int data;
struct node *next;
};
you would have had to use:
struct node* node;
to declare a new node. And to avoid that you would have to define later:
typedef struct node Node;
in order to be able to declare objects like the following:
Node* node;
In the end:
typedef struct node {
int data;
struct node *next;
} Node;
Is just a shortcut for struct node { ... }; in addition to typedef struct node Node;.
Here struct node is a type like int
and Hence
struct node {
int data;
struct node *next;
}NodeVar;
means you are declaring a single variable Node of struct node.
like int intVar;
typedef is to make your code understandable.
so that when you use
typedef struct node Node;
you can use the same declaration as
Node NodeVar;
Consider this code:
#include <stdio.h>
typedef struct {
int data;
struct node *next;
} Node;
int main()
{
Node a, b = {10, NULL};
a.next = &b;
printf("%d\n", a.next->data);
}
This won't compile. The compiler has no idea what a struct node is, other than it exists. So you might change the definition in the struct to Node *next;. The typedef isn't in scope before it's declared, so it still won't compile. The simple answer is to do as he said, use the node tag after struct, and it works fine.
The lower case 'node' is a structure type... i.e. a struct node { stuff } is a node structure containing stuff.
On the other hand, the upper case "Node" is a completely new data type which refers to a 'struct node'
Generally (though in C++ I think you can), you cannot pass around a "node" in a C program... for example as an argument to a function. Rather, you would have to pass a 'struct node' as your argument...
// this will throw a syntax error because "node" is not a data type,
// it's a structure type.
void myFunc( node* arg );
// while this will not because we're telling the compiler we're
// passing a struct of node
void myFunc( struct node* arg );
// On the other hand, you *can* use the typedef shorthand to declare
// passing a pointer to a custom data type that has been defined
// as 'struct node'
void myFunc( Node* arg );

creating Typedef pointers to Typedef structs in C

Have a question about typedef in C.
I have defined struct:
typedef struct Node {
int data;
struct Node *nextptr;
} nodes;
How would I create typedef pointers to struct Node ??
Thanks !
You can typedef them at the same time:
typedef struct Node {
int data;
struct Node *nextptr;
} node, *node_ptr;
This is arguably hard to understand, but it has a lot to do with why C's declaration syntax works the way it does (i.e. why int* foo, bar; declares bar to be an int rather than an int*
Or you can build on your existing typedef:
typedef struct Node {
int data;
struct Node *nextptr;
} node;
typedef node* node_ptr;
Or you can do it from scratch, the same way that you'd typedef anything else:
typedef struct Node* node_ptr;
To my taste, the easiest and clearest way is to do forward declarations of the struct and typedef to the struct and the pointer:
typedef struct node node;
typedef node * node_ptr;
struct node {
int data;
node_ptr nextptr;
};
Though I'd say that I don't like pointer typedef too much.
Using the same name as typedef and struct tag in the forward declaration make things clearer and eases the API compability with C++.
Also you should be clearer with the names of your types, of whether or not they represent one node or a set of nodes.
Like so:
typedef nodes * your_type;
Or:
typedef struct Node * your_type;
But I would prefer the first since you already defined a type for struct Node.

Resources