Creating a stack in C, structure for nodes - c

I have been given a structure for the nodes that will make up my stack but I am having trouble understanding it.
struct stackNode
{
char data;
struct stackNode *nextPtr;
};
typedef struct stackNode StackNode;
typedef StackNode *StackNodePtr;
I understand that I have a structure called stackNode, renamed StackNode (or a second type with the same everything except name?), which has two types, a char and a pointer to a stackNode.
I am not sure what the final line means, can anyone step through and explain it to me? I think it means there is a new type, which is a pointer to a StackNode, called a StackNodePtr. Is this right?

Yes, whenever you use a StackNodePtr you are essentially using a StackNode* that is in turn equal to a struct stackNode*. The spacing and asterix placement can evidently lead to some confusion. I would personally write it as typedef StackNode* StackNodePtr; to be a bit clearer with what gets typedef-ed to what.
These three lines would be equal:
StackNodePtr myPointer;
StackNode *myPointer;
struct stackNode *myPointer;
The reason for the typedef struct stackNode StackNode is usually to avoid having to write struct whenever using it.

You have three things.
You are declaring a type named struct stackNode, and providing the structure definition.
You are defining a new type, StackNode, that is an alias of (and is type-compatible with) struct stackNode.
You are defining a new type, StackNodePtr, that is an alias of (and, again, type-compatible with,) StackNode * (and struct stackNode *).
The poing being, that instead of declaring your node variable as struct stackNode newNode, and your list head as struct stackNode *head, you declare your node variable as StackNode newNode and your list head as StackNodePtr head.
This is a fairly common idiom, although some people recommend against doing it this way. (And, of course, other people insist that this is the right way, too.)

Related

Pointer in typedef struct

I came across a stack tutorial in the C language and I can't seem to understand what the *Stack pointer is pointing towards nor the *next pointer.
I would just like to have a quick explanation on what these two pointers actually point to.
typedef struct StackElement
{
int value;
struct StackElement *next;
}StackElement, *Stack;
Neither points to anything in the example you've given. This code is just the declaration of the structure type itself. You could break the typedefs out into maybe simpler form:
struct StackElement
{
int value;
struct StackElement *next;
};
typedef struct StackElement StackElement;
typedef struct StackElement *Stack;
That is, there is a declaration of the structure itself, which contains a field next to be used by the implementation code of this stack. That field, when filled in, will point to another struct StackElement structure.
The typedef parts just make convenience names - StackElement can be used in place of struct StackElement, and Stack can be used instead of struct StackElement *.

How to typedef a forward declaration?

I need help with declaring some structures to use in my code. The idea is that I need to declare some structures that are included in each other and use typedef to have a good coding style.
I have tried to declare these:
typedef struct cell
{
T_Tree list_of_sons;
struct cell *next;
}ListCell, *T_List, **Adr_List;
typedef struct node
{
int value;
T_List list;
}Node, *T_Tree;
It doesn't work because the type "T_Tree" is not declared before, but I would like to find a way to declare them while keeping the type definitions shown above.
Never (except function pointers) hide pointers in the typedef-s. It makes code more error prone and hard to read (you don't know when you see the declaration if something is a pointer or not).
struct node;
typedef struct cell
{
struct node *list_of_sons;
struct cell *next;
}ListCell;
typedef struct node
{
int value;
ListCell *list;
}Node;
Insert typedef struct node *T_Tree; before the first declaration. Then remove T_tree from the last declaration.
That declares T_Tree to be a pointer to a struct node. You may declare a pointer to a struct even though the struct does not have a complete definition.

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;

typedef confusion in C

I'm having a hard time understanding the typedefs in this C structure.
typedef struct node {
int value;
list rest;
} node;
typedef struct node *list;
What's the difference between the "node" typedef declaration and the "list" declaration? Why is list prefaced as a pointer? Isn't "node" a pointer as well? Why can't I simply say "typedef struct node list" and omit the asterisk? I've been searching everywhere and I can't really find a satisfactory answer.
The first typedef defines node as an alias for struct node, to allow you to refer to it simply as node without writing struct node every time (in C "regular" type names and struct names live in two different namespaces). It's equivalent to:
struct node
{
int value;
struct node* rest;
};
typedef struct node node;
The second typedef, instead, defines list as an alias for node *, i.e. defines the type list as a pointer to a node structure.
(by the way, personally I find that this is very bad style: hiding pointers inside typedefs is almost always a bad idea; one can argue that a pointer to the first element in a list could be identified as the list, but the usage of list even for the rest pointer is IMHO not very nice)
node is not a pointer; it is a struct. list is a typedef for a pointer to node.
You typedef a struct in C to avoid typing struct node ... everywhere.
Whether or not this is good practice is questionable (most will agree that hiding a pointer type behind a typedef, unless it is truly opaque, is a bad idea), but that's the gist of it.
The first declaration says that a node is the structure. The second says that a list is a pointer to a node.
So, this would be proper code using those declarations:
list x;
node n;
x = &n;
Declaring an item using typedef struct node list is not correct. The typedef statement declares a new type. The keyword typedef is not part of the type's name.
node is a struct, which is (confusingly) named the same thing as struct node. list is a pointer to struct node. So the following are equivalent:
struct node *a;
node *a;
list a;
node is just a synonym for struct node
list is a pointer to a struct node (or node)
Each node instance contains a list pointer which enables you to build data structures such as (singly) linked lists, etc.

How to use a struct in C?

This is code for a linked list in the C programming language.
#include <stdio.h> /* For printf */
#include <stdlib.h> /* For malloc */
typedef struct node {
int data;
struct node *next; /* Pointer to next element in list */
} LLIST;
LLIST *list_add(LLIST **p, int i);
void list_remove(LLIST **p);
LLIST **list_search(LLIST **n, int i);
void list_print(LLIST *n);
The code is not completed, but I think it's enough for my question. Here at the end of struct node "LLIST" is used, and it's also used as a return type in the prototyping of the function list_add. What is going on?
That's a typedef. It's actually doing two things at once. First, it defines a structure:
struct node {
int data;
struct node *next;
}
And then does a typedef:
typedef struct node LLIST;
That means LLIST is a type, just like int or FILE or char, that is a shorthand for struct node, your linked-list node structure. It's not necessary - you could replace LLIST with struct node in all of those spots - but it makes it a bit easier to read, and helps hide the implementation from pesky end-users.
LLIST is just another type name for the struct that has been created. In general, the following format will create a type "NAME" that is a "struct x":
typedef struct x { ... } NAME;
C requires that you reference structs with a "struct" prefix, so it's common to introduce a typedef for less verbose mention.
That is, the declaration of your struct has two parts, and can be rewritten as such:
struct node {
int data;
struct node *next; /* pointer to next element in list */
};
typedef struct node LLIST;
So, LLIST is just another name for struct node (thanks Chris Lutz).
typedef creates a new "type" in your program, so the return value and types of parameters of those functions are just your struct. It is just shorthand for using struct node for the type.
If you were to create a new node, you could do it like this (using the type):
LLIST *node = malloc(sizeof(LLIST));
node->data = 4;
node->next = someOtherItem;
list_add(node, 1)
Also, with the function prototypes in your question, you don't really need the double pointers; since the data in your struct is just an int, you could do something like
LLIST *list_add(int data, int position);
then the list_add function would handle the allocation, copy the int into the struct and add it to the linked list.
Putting it in at a certain position is as simple as changing the next pointer in the node before it to the address of the newly allocated node, and the next pointer in the new node to point at the next one (the one the node before that one was originally pointing at).
Keep in mind that (given the rest of your function prototypes) you will have to keep track of pointers to every node you create in order to delete them all.
I'm not sure I understand how the search function will work. This whole thing could be implemented a lot better. You shouldn't have to provide the location of a node when you create it (what if you specify a higher number than there are nodes?), etc.
LLIST* is a pointer to a structure defined by the LLIST struct.
You should do
LLIST* myList = malloc(sizeof(LLIST)*number_of_elements);
to have some memory allocated for this list. Adding and removing items requires you to reallocate the memory using realloc. I've already written some piece of code for lists (made with arrays).
I might post the code as soon as I'm home, which is currently not the case.

Resources