Unable to get this data structure to work (newbie) - c

I'm pretty new to C, and I've been trying to make a program with this data structure:
struct node {
char command[100];
char prereq[100][80];
char *targ;
int isUpdated;
} Node;
However, whenever I try to implement it in the code, like this:
Node n = malloc(sizeof(*n));
I get compiler errors such as "nmake.c:13:31: error: unknown type name ‘Node’".
I've tried code such as:
typedef struct node *Node;
with similar results. What's wrong?

I think you are confused about what typedef does.
A declaration such as this one:
struct node { ... };
will define a type named struct node. Do not forget the word struct! If you say just node it will mean nothing (note that this is different in C++).
So now to create a local variable you do:
struct node x;
And to do a dynamic one:
struct node *px = malloc(sizeof(struct node));
Now, if you want to make an alias to the type, you use the same exact syntax than to create a variable, but you write typedef at the beginning of the declaration:
typedef struct node Node;
Or if you prefer the pointer type:
typedef struct node *PNode;
Then to create variables:
Node a;
Node *b = malloc(sizeof(Node));
PNode c = malloc(sizeof(Node)); //do not use sizeof(PNode) as it is useless here
Some people, as #WhozCraig says in the comments, and you seem to intend in the original code prefer to use the declaring variable for sizeof instead of the type:
Node *b = malloc(sizeof(*b));
PNode c = malloc(sizeof(*c));
Actually there is no real difference, other than the style, so pick your favorite!
Note that when defining the original struct you can use the same declaration to create variables or typedefs, but not both:
struct node { ... } a; //a is a variable
typedef struct node {...} b; //b is a type
Some people like to force the syntax and do something like this:
typedef struct node {...} Node, *PNode; //tree types in one line!
but personally I find this practice a bit dumb: don't typedef a pointer unless you want to hide the fact that it is a pointer.

What you probably want is:
typedef struct _node {
char command[100];
char prereq[100][80];
char *targ;
int isUpdated;
} Node;
/*
* This defines a structure named _node.
* To use it, you must add struct everytime, for instance:
* struct _node foo;
*
* It also defines a typedef named Node which is a synonym to struct _node - Node
*/
Node *n = malloc(sizeof(*n));
/*
* Because we want to dynamically allocate we need a pointer, so we declared it as a Node *
*/

Related

Creating a pointer directly from a typedef struct definition

I want to check what the following code means. I think I am creating a pointer to a list of pointers to adjlistnode structures but I'm not sure.
Here is the code:
typedef struct adjlistnode {int node; int cost; struct adjlistnode *next;}
**AdjMatrix;
I'm confused as to what **AdjMatrix actually is. Like I said above, I think it is a pointer to a list of pointers to adjlistnode structures but I'm not sure. Am I right in my assumption?
The rules around a typedef can be simplified to the following generalization: if you have any valid variable declaration in C (without a storage class such as extern, static or register, etc.), then strapping a typedef at the front turns the variable name into a new type name, based on the type of the variable.
So here, without the typedef:
struct adjlistnode {int node; int cost; struct adjlistnode *next;}
**AdjMatrix;
AdjMatrix is variable of type pointer to pointer to struct adjlistnode.
But in your post, because of the typedef, AdjMatrix is a name for the type pointer to pointer to struct adjlistnode.
I think it is a pointer to a list of pointers to adjlistnode structures
No, it isn't.
AdjMatrix becomes a type representing a pointer to pointer to struct adjlistnode
As an example it can be used like:
AdjMatrix p = NULL; // p is now a pointer to pointer to struct adjlistnode
The code seems to be for building a linked list and AdjMatrix seems to be a short hand for referring to a pointer to the head pointer. It could be used like:
void addNode(AdjMatrix pHead, int node, int cost)
{
struct adjlistnode *tmp = malloc(sizeof *tmp);
tmp->node = node;
tmp->cost = cost;
tmp->next = *pHead;
*pHead = tmp;
}
void deleteNode(AdjMatrix pHead)
{
if (*pHead)
{
struct adjlistnode *tmp = *pHead;
*pHead = tmp->next;
free(tmp);
}
}
int main(void) {
struct adjlistnode *head = NULL;
// Add nodes
addNode(&head, 1, 2);
addNode(&head, 3, 4);
addNode(&head, 5, 6);
// ... use the list
// Delete nodes
while(head) deleteNode(&head);
return 0;
}
Notice that typedef of pointers is often considered bad practice. Instead it would be better to do:
typedef struct adjlistnode {int node; int cost; struct adjlistnode *next;} AdjMatrix;
and use it like:
void addNode(AdjMatrix **pHead, int node, int cost)
to make it clear the pHead is a pointer to pointer to AdjMatrix
From typedef [emphasis added]:
typedef is a reserved keyword in the C and C++ programming languages. It is used to create an alias name for another data type. 1 As such, it is often used to simplify the syntax of declaring complex data structures consisting of struct and union types, but is just as common in providing specific descriptive type names for integer data types of varying lengths.
The AdjMatrix is an alternative name of struct adjlistnode ** type, which is a pointer to pointer to struct adjlistnode.
You can use it to declare variables like this:
AdjMatrix pp_st_adjlistnode;
which means pp_st_adjlistnode is a pointer to pointer to struct adjlistnode.

Linked list Implementation in C with structure

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;

Difference between these c struct declarations?

I have a code looking like this :
struct point {
int a;
int b;
}
which can be further used like this :
struct point p;
p.x = 10;
p.y = 5;
now I came to know that this can also be written like this :
typedef struct{
int x;
int y;
} point;
and can be used as point p
The confusion started when I started learning linked-list, this is the code I saw.
typedef struct node {
int val;
struct node * next;
} node_t;
I have a couple of questions:
If we can define the struct by simply using typedef struct { ... } node whats the use of writing typedef struct node {.....
The node_t at the end of the code is really confusing because from my understanding it has already defined a type node so we can call node x to create a node , then what's the need of the node_t or basically writing anything after the } what it means ?
shouldn't this work ?
typedef struct {
int val;
struct node * next;
} node;
If we can define the struct by simply using typedef struct { ... } node whats the use of writing typedef struct node {.....
The node_t at the end of the code is really confusing because from my understanding it has already defined a type node so we can call node x to create a node , then what's the need of the node_t or basically writing anything after the } what it means ?
In C, structures can have both tag and a typedef name. In the structure declaration:
typedef struct node {
int val;
struct node * next;
} node_t;
node is a tag and node_t is typedef name. Latter you can declare your structure variable either by using tag or typedef name.
struct node *new_node; // OK
node_t *head; // OK
In fact, the tag and typedef name can even be same, although that's not required:
typedef struct node {
int val;
struct node * next;
} node;
shouldn't this work ?
typedef struct {
int val;
struct node * next;
} node;
No. This will not work . Why?
The reason is that, when a structure has a member that points to the same kind of structure, as node does, we are required to use a structure tag. Without the node tag, we would have no way to declare the type of next.
Suggested reading: As Op is asking for good resource on data structure. Here you can go:
Tutorial: Introduction to Data Structures.
Book: Classic Data Structures.
The third block of code, which you seem to have a question about, has a redundant identifier.
typedef struct node {
int val;
struct node * next;
} node_t;
is identical to
struct node{
int val;
struct node * next;
};
typedef struct node node_t;
They're identical, but merged into the same line. The syntax around a typedef is
typedef [original name] [new name];
Normally, when we typedef a struct, the ONLY way to reference it afterwards would be the typedeffed name (in the first code example, you could only access it by node_t) while a slightly more redundant declaration allows for accessing by the "struct node" variable type too.
To answer your other question the node_t that confused you is what you can refer to the struct as... for example
node_t node1;
struct node node2;
Are the two valid declarations for a node struct.
Here, you can also use 'struct p' by typedefing it using 'struct p typedef P;'. It sometimes makes me confused when typedef a complex function pointer.
I don't know the reason why the C std. support such a syntax sugar.
Here is my explanation.
struct
{
int i;
};
declares an unnamed structure and apparently there is no real usage of this. Please correct me if I am wrong.
struct
{
int i;
} T;
now T is an object in the given scope and type is unnamed.
struct TT
{
int i;
} T;
declares a structure TT and an object T. You can use TT to create more objects. The best way to think about this is, just consider struct TT{ int i} as a single type such as double.
typedef struct TT
{
int i;
};
has the same meaning as (at least in nowadays compiler. I'm not sure about the older ones)
struct TT
{
int i;
};
and
typedef struct
{
int i;
} TT;
declares a type TT (not an object) for the given structure as you are using typedef int Int;
Hope this resolves the mess.

Useless variable name in C struct type definition

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.

what does typedef struct node *NODE indicate?

struct node
{
int coef;
int exp;
struct node *link;
};
typedef struct node *NODE;
It defines NODE as a synonym for the type struct node *, so when you'll be declaring a variable of type NODE you'll be actually declaring a pointer to struct node.
Personally, I don't think that such declaration is a good idea: you're "hiding a pointer" (which is almost always a bad idea), and, moreover, you are not highlighting this fact in any way into the new name.
It makes NODE a typedef for a struct node *.
NODE becomes an alias for struct node*.
EDIT: Okay, for the comment (if I write my answer as comment, it would be too long and not formatted):
There's no different way to write this. Here, typedef is used just to create a synonym/alias for pointer to struct node.
An example for usage would be:
void f()
{
// some code
NODE p = NULL;
// do something with p
// for example use malloc and so on
// like: p = malloc( sizeof( struct node ) );
// and access like: p->coef = ..; p->expr = ..
// do something with p and free the memory later (if malloc is used)
}
is the same as
void f()
{
// some code
struct node* p = NULL;
// do something with p
}
Using NODE makes it just shorter (anyway, I wouldn't advise such typedef, as you're hiding, that it's a pointer, not a struct or other type, as mentioned in #Matteo Italia's answer).
The format, you're referring: "typedef struct{}type_name format" is something else. It's kind of a trick in C, to avoid writing struct keyword (as it's obligatory in C, and NOT in C++). So
typedef struct node
{
//..
} NODE;
would make NODE alias for struct node. So, the same example as above:
void f()
{
// some code
NODE p;
// do something with p
// note that now p is automatically allocated, it's real struct
// not a pointer. So you can access its members like:
// p.coef or p.expr, etc.
}
is the same as
void f()
{
// some code
struct node p;
// do something with p
}
NOTE that now, p is NOT a pointer, it's struct node.
simply tells you can create pointer of node type using only NODE every time instead of writting struct node * everytime
what does typedef struct node *NODE indicate?
UPPERCASE IS NO GOOD
Reserve ALL UPPERCASE identifiers for MACROS.

Resources