What is the differences in these declarations? - c

I am learning about uses of data structures and came across some doubts:
struct node
{
int data;
struct node *next;
}*head;
Question1: In the above structure, what does declaring a struct node *next within the structure mean?. And how is it different from simply declaring a pointer variable within structure as int *next
Question2: We can see that, at the end of the structure definition, a pointer *head is declared of type node and is used to access the structure members if I am right. Is this same as declaring it like this:
struct node *head;
Any help with this would be great. Thank you all in advance.

"struct node *next" declares a variable called next which points to a "struct node". In other words, a singly linked list.
You are correct in that the statement does two things:
Declares a struct called node (with an int called data and a
pointer to the next struct node)
Declares a variable called head pointing to the struct node.
These could have been done separately as follows:
struct node
{
int data;
struct node *next;
};
struct node *head;

This is very commonly how Linked Lists are declared in C. Recall — a linked list is a series of nodes which contain data as well as a link (in this case, a pointer) to the next node in the series.
So, each object of type struct node should contain a pointer to another struct node. This is characterized by declaring a field next in the struct with type struct node *.
As for your second question: the code you provided both defines struct node (allowing you to instantiate objects of type struct node), and declares a pointer to such a struct called head. You could certainly define the variable head the way you asked, but you would still need to define the struct somewhere earlier in the code. This is usually done in a separate header file, but could be done in the same .c source code file for brevity.
Now, note that both these methods will not actually create a struct node object. All you're doing is declaring a pointer to one. The object doesn't yet exist anywhere since you never allocated space for it. To do that, you'd need to use malloc:
struct node {
int data;
struct node * next;
} * head;
head = malloc(sizeof(struct node));
You could also declare a runtime stack instance of the struct, which just means you won't need to explicitly free the memory you allocated with malloc(). The memory allocated for the struct is deallocated when you return from the function, or when your program terminates if declared outside of any functions.

Declaring next as struct node *next means that it points to a struct node, presumably the next node in the list. If it were instead declared as int *next then it would point to an int, which it doesn't seem there's any need for.
The answer to question 2 is yes. They are simply combining the definition of struct node with the declaration of head. They could be split apart as you indicated.

Related

What is the difference between these two pointers

In linked list I came across the following structures
struct node
{
int data;
struct node *next;
};
struct node *list;
What is the difference between list and next?
They are both pointers to the struct node.
But the difference is that next is a member of the struct while list is an object.
That means that you can use list as
list->data;
But to use next, you need to use
list->next->data;
or
struct node a;
a.next->data;
That is, it behaves like needs an object just like any other members of the struct.
You can refer this code
> There is no difference between these Two Pointers both are refrences
and store the adress of the object.
but the *next behaves as the variable of the struct and the other pointer behaves as an object of the Struct.
1st of all in the snippet shown there only "exists" one pointer, that is list.
However:
list is an instance of a pointer pointing to struct node. It uses memory.
next is a member of, part of the definition of the type struct node and of type pointer to struct node. next is no instance of a pointer. It does not use memory.
The Both pointers list and next are pointing to node structure.
The Main Difference is:
list is not part of the structure node, where as next is part of the structure node.

Declaring structs in C

struct node
{
int data;
struct node *next;
}*head;
Why do we have *head? And is this different (better?) than doing
typedef struct
{
int data;
struct node *next;
}head;
The first section defines a variable head which is a pointer to a struct node type. It can be NULL, indicating that your linked list has zero elements.
The second block just declares a type called head. It's not a variable at all. And it does not compile as the type of its next field, struct node, does not exist.
You probably wanted
typedef struct node {
int data;
struct node *next;
} node;
node *head;
This form declares 2 types, struct node and node (the same), and defines a variable head. I'd go for the 1st form without the typedef, as it's more simple, and you cannot refer to the typedef inside the struct's next field anyway.
The first version declares a type (struct node), and a variable head which is a pointer to struct node. All lists need a head, so that's helpful.
The second declares head as the type name for an (otherwise unnamed) struct. It won't actually compile, since the inner struct node *next refers to a type which doesn't exist.
In your first example, you define the struct but also declare the head variable to be a pointer to such struct.
In your second example (typedef) you just declare some type synonym (but
no variables!)
struct node
{
int data;
struct node *next;
}*head;
in the code above you have declare object head as a pointer so in order to access its element data you need to use -> operator that is for example head->data=4; and so on
you can create nodes to append the head pointer
typedef struct
{
int data;
struct node *next;
}head;
where as in this code every node that you create will be of head type it will create a problem when you delete the head node if you write linked list code for deleting head you are unable redefine the new head
where as in earlier code head being a pointer can be change by updating its next element in struct after updating the head->next in previous code we can then easily delete the previous head without losing the new head
the gdb debugger (and perhaps other debuggers)
can only see the contents/format of a struct that contains a tag name.
The use of a typedef hides the tag name and defines a new type.
however, gdb will not properly display the contents of any instance of the struct.
The correct way is:
struct tagname { ... };
Notice no struct name to clutter the symbol table and create confusion
Of course, then each defining instance of this struct needs to be written as:
struct tagname myName;
but that should not be a problem and adds the visible documentation
that myName is a struct
Along with the increased visibility of the struct, both to gdb and the reader
of the resulting code, any pointer to that struct should never be defined
as part of the struct definition. Such a formatting hides the
fact that such name is a pointer. rather declare an instance of a pointer as:
struct tagname * pMyStruct;
And, never use this syntax:
struct { ... } structName;
as that is a depreciated syntax

Structures and typedefs and pointers in C

I am trying create a doubly linked list in C and I have a question regarding the code below:
typedef struct Node{
double coeff;
int exp;
struct Node* next;
struct Node* prev;
}Node;
My question:
In line(5) above; Is it correct to say that I am creating a pointer variable called next? And this variable is of type Node? This variable will point to the address of the next Node stored in memory?
Is the Node* the same as Node *pointer?
Thanks for the help; I want to get my foundation solid before I progress further.
In line(5) above; Is it correct to say that I am creating a pointer variable called next?
You have defined a type struct Node with a member named next( and others ).
And this variable is of type Node?,
next has a type struct Node*
This variable will point to the address of the next Node stored in memory?
If you assign it a correct value then it will.

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