I'm using this structure as a linked list:
typedef struct Node{
int value;
struct node_t* next;
}node_t;
And everything works fine until I put struct node_t* next before int value field, then I have a lot of trash values working with that structure.
Is it about wrong implementation or something else in the code?
You are calling your structure Node and defining a node_t type. Then you are using node_t as if it was the name of the structure and not the type.
Try this
typedef struct node {
int value;
struct node *next;
} Node;
Or
typedef struct node Node;
struct node {
int value;
Node *node;
};
If you call it struct Node, then
struct Node {
int value;
/* The compiler doesn't know what `struct Node' is yet */
struct Node *next;
/* But you can always declare pointers, even of types the compiler
* doesn't know everything about. Because the size of a pointer
* does not depend on the type of the pointee.
*/
};
In your example, it's even worse. You typedefed something that is a new type as the compiler understand it, to use it you MUST not use struct. The whole idea behind typedefing is that you DEFINED a new type, so suppose the following
typedef struct Node node;
then to declare a pointer of type node (note, again node IS A TYPE),
node *anode;
but you attempted something like
struct node *anode;
and it's wrong because there is no struct node in the code above, it's struct Node.
Another mistake in your code is that, the node_t type does not exist when the compiler finds the
struct node_t *next;
which is already wrong because if the type were defined before the struct which is possible like this
typedef struct Node node_t
it'd still be wrong to use struct on the node_t type, because for the compiler node_t is not a struct it's a new type, which in turn is simply an alias for struct Node.
Typedefing structures in my experience is more trouble than benefit anyway. And it's not so hard to type struct Something instead of just Something. It also has the benefit of being more explicit, so if another programmer reads your code, they will immediately know that Something is a struct.
Note: I deliberately changed the name to node because it's considered bad practice to suffix your own defined types with _t. It's not necessarily a bad thing, but over the years that I've been working with this I developed some habits and one of them is not to use _t as a suffix for my own defined types. Which by the way only exist in my code if they will improve readability a lot. Otherwise I simply use the name of the structure with the struct keyword.
You are using a non existing type node_t. The type doesn't exist because the type struct Node is not even complete and you are using it's alias. Another thing to remember while using typedefs with structures don't use struct keyword along with alias
eg.
/* This is correct */
typedef struct Node
{
int x;
struct Node *next;
} node_t;
/* while these are incorrect */
/* Prefixing struct keyword to a typedef'ed type */
struct node_t *listhead;
/* The type is inclomplete and you are using an alias of the type
which doesn't even exist */
typedef struct Node
{
int x;
node_t *next;
};
You are trying to create a pointer to the structure which you are yet to create. So, it should have been,
typedef struct Node{
int value;
struct Node* next;
}node_t;
Related
Sorry first for my bad English. I'm begginer in C, trying to make a Singly Linked List.
This is my setup of the List:
#include <stdio.h>
#include <stdlib.h>
typedef int Element;
struct
{
Element Data;
struct Node *Next;
} Node;
typedef struct Node *Position;
typedef Position List;
This is how I initialize this Struct (i dont know if this function is wrong):
void resetList(List *L)
{
*L = (struct Node *)malloc(sizeof(Node));
};
My problem is, wherever I used the (->), I will got this error
error: invalid use of undefined type ...
the compiler mark the error at any (->) in my code. For example:
int isEmpty(List L)
{
return (L->Next == 0);
};
will get the error at (->).
I know my code is so dump. Please help me. Thanks.
My problem is, wherever I used the (->), I will got this error
Your struct needs to be defined as a type and at the same time a self-referencing type, able to point at a variable which is of the same type as itself. In can be done like this:
typedef struct Node
{
Element Data;
struct Node *Next;
} Node;
Where the first Node is a struct tag, which is a name allowed to co-exist with the type name Node later defined at the } Node;.
Hiding pointers behind a typdef like typedef struct Node *Position; is horrible practice, because it achieves nothing except making the code much harder to read for everyone including yourself. There's no need for a typedef at all here, just declare a variable Node* Position.
Similarly, drop the typedef Position List;, creating new types just for the heck of it only creates clutter.
This is how I initialize this Struct (i dont know if this function is wrong):
The reason why you aren't sure, is because of all the obscure typedefs. Consider rewriting the function as:
void resetList (Node** list)
{
*list = malloc(sizeof(Node));
};
The reason why it has to be a pointer-to-pointer is explained here: Dynamic memory access only works inside function
As for what this function does, resetList is a very weird name for a function allocating a single node. I would expect it to delete the previous list if present and then maybe allocate a new node.
In general, the first declaration of struct Node is not correct. If you specify the name of the structure at the end of its declaration, you are not specifying data type, but you create only the struct variable. Therefore, the compiler doesn't know how to allocate struct Node *Next; item in your struct.
You can simply repair your code by moving the name of the structure:
typedef int Element;
struct Node
{
Element Data;
struct Node *Next;
};
typedef struct Node* Position;
typedef Position List;
I have the following struct defined with the typedef keyword:
typedef struct{
int data;
NODE *next;
}NODE;
It gives me the following error when compiling:
error: unknown type name ‘NODE’
I looked it up, and found this stack overflow post, which said I should change it to
typedef struct n{
int data;
n *next;
}NODE;
I have two question about this.
First, what is the n? I thought NODE was the name of the struct, so is that a second name?
The second is, why can I put the n as a data type, but not NODE?
NODE is not the name of the struct. It's a typedef, i.e. an alias for the struct. In the first case, the struct is unnamed. In the second case, the struct is named struct n.
The reason you can't use NODE inside of the struct is because that name hasn't been defined yet at the time it is used. So you need to use the actual name of the struct (which is defined) in order to create a pointer to it.
Also note that the struct keyword is required in C when using the struct's name, i.e.:
struct n *next;
With your combined structure definition and typedef, the name NODE is not yet defined at the location when you try to use it.
typedef struct{
int data;
NODE *next; // name NODE used here
}NODE; // name NODE defined here
You can do the typedef before the structure definition to use it for a pointer.
typedef struct n NODE; // NODE defined as incomplete type
struct n {
int data;
NODE *next; // use as pointer is OK
};
// from here NODE is completely defined
But you cannot define a variable or structure field of type NODE before the structure is really defined.
typedef struct n NODE;
#if 0
// does not work because NODE is an incomplete type here
struct wrapper {
NODE node;
};
#endif
// using a pointer to an incomplete type is OK
struct n {
int data;
NODE *next;
};
// works
struct wrapper {
NODE node;
};
You can use
typedef struct n{ // type "struct n" known here
int data;
struct n *next; // use known type
}NODE; // type alias NODE known here
because the type struct n is already known when you use it for the pointer.
Note that in C you have to use struct n *next (in contrast to C++).
Code without typedef (and it works):
struct Node {
int data;
struct Node *next;
struct Node *prev;
};
I'm trying to make a code using typedef for the structure "Node" in Doubly Linked List, but this does not work:
typedef struct {
int data;
Node *next;
Node *prev;
} Node;
Is there a way around this using typedef?
You can use a forward declaration of the struct
typedef struct sNode Node; // this is a typedef and a declaration of the struct
struct sNode{
int data;
Node *next;
Node *prev;
};
This way Node is known (but not defined), in the definition of your struct.
This can be compressed as it is done by Yunnosch. But then you need to use the struct Name notation inside your declaration.
This way it is possible to already use the typedefed name also the forward declaration is necessary if you have some circular dependencies in your structs.
It is also possible to use the struct name as the typedef:
typedef struct Node Node;
struct Node{
int data;
Node *next;
Node *prev;
};
I personally prefer the first style, it seems "clearer" to me, but there is nothing wrong with the second example, as long as the compiler is not from the pre-standard era (before 1989).
As Jens Gustedt pointed out the first style might be incompatible if this is included in C++.
So maybe I should change my preference to the first.
Inside the typedef, the to-be-defined type is not yet known, so you need to introduce and use a struct tag:
typedef struct Node_tag {
int data;
struct Node_tag *next;
struct Node_tag *prev;
} Node;
The Node_tag is the struct tag, because of where it is introduced (and not because of the name part "_tag"). It is not a type in itself, only the combination as struct Node_tag is a type which can be used for the struct members.
Afterwards, when the typedef is done, the type Node has been defined.
To clarify, a second typedef would be possible as typedef struct Node_tag NodeToo;. This demonstrates that the type struct Node_tag is also useable. That is why I prefer to use the "_tag" name fragment, to allow to be clear of what is used.
Inside the structure, you have indeed to use types that are already known by the compiler. A way to be compliant with this rule in your case is to use the struct Node * type after having declared typedef struct Node. In this case, even if the type struct Node is incompletely defined when the compiler encounters it inside the structure, the name is known and the compiler knows the size of a pointer (to reserve in memory), so it has no reason to complain !
Morevover it is also accepted to use the same name for the type as after struct: you can use Node for both.
Here is my suggested solution:
typedef struct Node {
int data;
struct Node *next;
struct Node *prev;
} Node;
I am new to c programming and creating linked list data structure, MY teacher gave me some code which seems a bit confusing :
typedef struct node *ptr;
ptr start,current;
typedef struct node{
int value;
ptr next;
};
This code works fine and using the other functions i can create a linked list , my confusion is that, when i change the code like this:
node *start;
node *current;
typedef struct node{
int value;
node *next;
};
it doesn't work .What is wrong with this code why cant i forward declare the node pointers anymore.
typedef struct node *ptr;
ptr start,current;
typedef struct node{
int value;
ptr next;
};
The typedef for the struct itself won't work this way, I guess you're missing a node at the end (It's missing the identifier of the newly defined type).
At this point, I'd tell your teacher to please not confuse everyone by typedefing a pointer type. It's widely common to have the pointer type modifier visible on every usage, just to make it obvious it is a pointer. But now to the actual answer:
node *start;
node *current;
typedef struct node{
int value;
node *next;
};
Start at the first line: you use node here as a type identifier. But you didn't tell the compiler yet what kind of type node should be. In fact, what you're actually missing is a forward declaration. It would work like the following:
/* forward-declare "struct node" and at the same time define the type
* "node" to be a "struct node":
*/
typedef struct node node;
/* now use your type by declaring variables of that type: */
node *start;
node *current;
/* finally fully declare your "struct node": */
struct node {
int value;
node *next;
};
Or, without the typedef, that easily confuses a beginner:
struct node; /* forward declaration (not strictly necessary in this little example) */
struct node *start;
struct node *current;
struct node {
int value;
struct node *next;
};
What you're doing in the second case is not a forward declaration. It's attempting to use a type (node) without defining it.
The first case doesn't quite work either. It gives the following warning:
warning: useless storage class specifier in empty declaration
That is because you're not assigning a type alias for struct node. You'd have to do it like this:
typedef struct node{
int value;
ptr next;
} node;
Now, you can use node in place of struct node.
I'm implementing a linked list in C. Here's a struct that I made, which represents the linked list:
typedef struct llist {
struct lnode* head; /* Head pointer either points to a node with data or NULL */
struct lnode* tail; /* Tail pointer either points to a node with data or NULL */
unsigned int size; /* Size of the linked list */
} list;
Isn't the "llist" basically useless. When a client uses this library and makes a new linked list, he would have the following declaration:
list myList;
So typing llist just before the opening brace is practically useless, right? The following code basically does the same job:
typedef struct {
struct lnode* head; /* Head pointer either points to a node with data or NULL */
struct lnode* tail; /* Tail pointer either points to a node with data or NULL */
unsigned int size; /* Size of the linked list */
} list;
You need to give a struct a name if you will reference it in its declaration.
typedef struct snode {
struct snode* next;
struct snode* prev;
int id;
} node;
But if you won't reference the struct inside it you dont need to give it a name.
EDIT
Notice that typedef is and struct are two different statements in C.
struct is for creating complex types:
struct snode {
struct snode* next;
struct snode* prev;
int id;
};
Which reads like make a structure called snode that stores two references to itself (next and prev) and an int (id).
And typedef is for making type aliases:
typedef struct snode node;
Which reads like make a type alias for struct snode called node.
Yes, you are correct. It is only a matter of habit or convention to explicitly name the struct in addition to the typedef.
Note that there is little to no cost either way, since llist is not a variable and does not take up memory. It is like the difference between naming a variable i or index - the compiled form is the same, but one may be more readable than the other.
It's useless in that particular case but, if you wanted a pointer to that struct within the struct itself, it would be needed.
That's because the struct is known at the opening brace while the typedef isn't known until the final semicolon (simplistic, but good enough here).
So you would need it for something like:
typedef struct sNode { // structure can be used now
int payload;
struct sNode *next; // cannot use typedef yet
} tNode; // typedef can be used now
You could turn this around: not the structure tag, but the whole typedef is superfluous.
struct snode {
struct snode* next;
struct snode* prev;
int id;
};
Now you can declare a pointer with:
struct snode *ptr;
You can even declare an array of them:
struct snode mynodes[10];
You'll have to type the struct keyword, but that won't hurt the compiler or the human reader (look at that syntax highlighting!).
You could even declare a pointer to an unknown type (at this moment of compilation) using an incomplete type:
struct xnode *xptr=NULL;
That will come in handy when you want to create an API to some library, where the actually implementtation of the library is not known to the caller:
struct gizmo *open_gizmo(char *path, int flags);
int fiddle_with_gizmo(struct gizmo *ptr, int opcode, ...);
Et cetera. A typedef would force the header file to "broadcast" all its internals to the caller, even if that is not needed.