What is self-referencing structure in C? - c

struct LinkedList
{
int data;
struct LinkedList *next;
};
In the code, within the definition of struct LinkedList there is a pointer to the structure itself.
How does it work?

So, the code
struct LinkedList
{
int data;
struct LinkedList *next;
};
defines a struct type containing two members named data and next, with the next member storing the address of a different object of the same type. Given the code:
struct LinkedList Node1 = { .data = 1, .next = NULL };
struct LinkedList Node0 = { .data = 0, .next = &Node1 };
you get something that sort of looks like this:
Node0 Node1
+---+--------+ +---+------+
| 0 | &Node1 |--->| 1 | NULL |
+---+--------+ +---+------+
(Note that you would never create a linked list this way, this is just for illustration).
This is possible for two reasons:
C allows you to declare pointers to incomplete types;
Pointers to struct types all have the same size and representation.
This is an example of a self-referential data type, which simply means that the type stores a reference (pointer) to a different object of the same type.

What you talk about are recursive data structrues and the question is how to let a data structure reference itself.
In C this can be done by declaring a pointer to itself in the definition of the data structure, "self" meaning a thing of its own type.
Note that when you write the expression, the data structure is not yet complete. Therefore it is not possible to let a data structue contain an occurence of itself, for once because the definition is not yet completely known and for two because the data strutcure would be never ending containing an occurrence of itself, itself,...
But you can declare a pointer to itself. The compiler now only allocates storage for the pointer and if you later assign/dereference the pointer it knows the storage pointed to contains an occurrence of itself. That is what you do in your example.

A self-referential pointer which points to the address of whatever it is a part of. So for example,
typedef struct node {
char data[30];
struct node *this;
struct node *next;
} Node;
*this is a self-referential pointer if it is assigned to whatever is applied to.
,and
Clearly a Cell cannot contain another cell as it becomes a never-ending recursion.
However a Cell CAN contain a pointer to another cell.
Refer this post as well.

Related

difference between structure operators in c

I'm new to structures in c, I've been researching the difference between the . operator, and the -> operator. But I can't seem the find resources that explain what I want to know. So, why if I make structure without typedef, can I use it directly such as "header.first = x", and not having to say "struct header varName"? Also, what is the difference between the . and -> in this example, because it seems in this case I can use them interchangeably.
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int data;
struct node* next;
}node;
struct header{
int count;
node *first;
}header;
int main()
{
node *curptr = (node*)malloc(sizeof(node));
printf("%p\n",curptr);
header.first = curptr;
printf("%p\n",header.first);
header.count = 10;
printf("%i\n\n\n",header.count);
node* current = (node*)malloc(sizeof(node));
current->data = 5;
current->next = NULL;
printf("%i\n",current->data);
printf("%p",current);
}
struct header { ... } header; is simultaneously creating the struct type (struct header) as well as creating a global variable (named header, of type struct header). It is equivalent to doing:
struct header { ... };
struct header header;
When you write header.first = x, what you're doing is just modifying the global object named header.
typedef struct node { ... } node; is simultaneously creating the struct type (struct node) as well as a typedef to it (node). It is equivalent to doing:
struct node { ... };
typedef struct node node;
As for . vs ->: a->b is equivalent to (*a).b. It's just syntactic sugar.
struct in c is a place in memory which is big enough to keep data for all its fields. As with any other objects in 'c' you have a choice to use it as a variable or use a pointer to it. A pointer is essentially a memory address of this variable.
Also, every variable in 'c' has a type. The latter behaves like a template for creating variables and check their usage.
So, in the following example you create a struct type struct header and describe what it contains.
struct header{
int count;
node *first;
};
Now, using the type, you can create the variable named my_header:
struct header my_header;
or, as in your example, variable header.
struct header header;
As in you example you can combine both into a single statement.
Now, if you created a variable of type 'struct header', you can access its members using the . operator. The following operator will cause 'c' to access member count of your struct variable. It will calculate correct place in memory to put '10' into it.
header.count = 10;
as for pointers, you can create a variable which will keep an address to your object. In 'c' it needs to know what type of object it points to. So, the pointer ptr in the following example is assigned address & of the variable header.
struct header *ptr = &header;
Now you can use the pointer to access fields in the header, but it requires a different syntax ->. so, the following statement will be equivalent to the previous one:
ptr->count = 10;
Note that in both cases '10' was assigned to absolutely the same object, field of the variable 'header'.
Also to make life easier ant to stop typing struct every time, you can use the typedef operator to declare a named type, i.e.
typedef struct node myNodeType;
typedef struct node node;
now you have to 'named' types: myNodeType and node which are the same. you can use them to declare variables and pointers:
myNodeType var1; // variable
node *next; // pointer.
and as in case with variable declaration, you can combine it with struct declaration as in your example.
And malloc just allocates a chunk of dynamic memory and returns its address, aka pointer to it. so, node* current = (node*)malloc(sizeof(node)); just assigns address of allocated memory to the pointer current.
Hope it helps a bit.

What would happen if a linked list was implemented without pointers?

The standard struct for list node is:
struct node {
int x;
struct node *next;
};
But, what would happen if we defined a node without a pointer, like this:
struct node {
int x;
struct node next;
};
?
I assume that the main problem would be not knowing where the list ends, since there wouldn't be a NULL pointer. But apart from that is there any other effects to be taken into consideration?
What would happen if we defined a node without a pointer, like this:
struct node {
int x;
struct node next;
};
This declares a structure with unterminated recursion. Hence the declaration is invalid and is rejected by the compiler.
Let's calculate this:
sizeof(struct node)
Well, we have an int, possibly some padding and sizeof(struct node). Putting it into one formula:
sizeof(struct node) = sizeof(int) + padding + sizeof(struct node)
This cannot be solved.
Thinking about it less theoretically, it would be a structure containing an infinite number of itself.
Languages that don't have value semantics but use reference semantics instead, like Haskell, allow this kind of data structures (types). I'm oversimplifying a lot here, but think of every structure member (record field) as a pointer, then it's probably clear why or works there:
data List = EndOfList | Node Int List
A struct type may not contain an instance of itself as a member for two reasons.
First, the type definition isn't complete until the closing } of the struct type; until the type definition is complete, the compiler won't know how much space to allocate for that member. Secondly, a struct type that contains an instance of itself would be infinitely large.
A struct type may contain a pointer to itself as a member since pointers to incomplete types are allowed, and all struct pointer types have the same size and representation.
You can create linked lists without using pointers; I did it Fortran 77, which didn't have pointer types. You simply use an array as your storage, and use array indices as your "pointers".

What is the differences in these declarations?

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.

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.

Linked-list is confusing

I am stuck, as I don't understand what is this code doing:
struct node
{
int info; /* This is the value or the data
in the node, as I understand */
struct node *next; /* This looks like a pointer. But
what is it doing in real life? */
} *last; /* What is this and why is it
outside the body? What is this
thing doing? */
I know that when a node is created, it has a value, and it is pointing to some other node
but I don't understand the syntax.
Is this a better way of writing the code above?
Is there a simpler way of writing the same struct for better understanding?
In my lectures they presume that the student has understanding of what they teach.
Well, we can explain this to you, but we can't understand it for you.
Code snippet you've provided is definition of variable last, being pointer to newly defined structure type node. It can be written other way as:
typedef struct _node_t {
int info;
node_t *next;
} node_t;
node_t *last;
This way we define typedef, which is, say, alias of type definition to some short name — in this particular case, it aliases structure of two fields as the name node_t. Wherever you define something as being of type node_t, you tell compiler that you mean 'this should be aforementioned structure of two fields', and node_t *last means 'variable last should be pointer to node_t type'.
So, back to syntax:
struct foo {
int a;
float b;
void *c;
} bar, *baz;
means 'Define structure type foo, and make it contain three fields — integer a, float-point b and untyped pointer c, then make variable bar to be of this structure type, and make variable baz to point to this structure type'.
Now to pointer. What you see is called 'recursive definition', e.g. type mentions itself in it's own definition. They are okay, if language supports them (C does), but one could avoid recursive definitions in linked list node structure by specifying next node pointer to be just untyped:
struct node_t {
int info;
void *next;
};
This way you no longer reference node_t type from node_t type, but that adds you some inconveniences when using this type (you have to explicitly cast next to node_t type, like ((*node_t)(last->next))->info instead of just last->next->info).
If you feel you need additional reference, consider taking a look at interactive online tutorials, like http://www.learn-c.org/ (I'm not affiliated).
that is the simplest way to write a linked list node , but why name it last ? name it node instead , this makes it more understandable , but here's how it works.
when a linked list is first created it contains only the root node (the first node in a linked list) , when you add a node , you fill the info field with the data that node will hold (note that info may be any kind of data , character , string , int ...) then set next to NULL , since that node is the last node in the list.
when you add another node , you change the value of next to point to the node you just added and you set the value of next to NULL in the node you just created because now that is the last node in the list .
you can repeat this to add as many nodes as your memory allow you to.
this link may help you to better understand structures
typedef struct marks {
int m;
struct marks *next;
} marks_t;
This way we define a structure so that a Linked List can be formed. Now we have defined the last variable next as a "structure pointer" which gives us the address of the next element in the list (i.e. as structure only)!
The last element does not point to any node (here marks structure) and hence the pointer variable has NULL value.
Now to define the first element:
marks_t *list;
if (list == NULL) {
list = (marks_t *) malloc(sizeof(marks_t));
}
list->m = 15;
list->next = NULL;
Now if we want to add an element next to this (i.e. second element):
marks_t *next1;
next1 = (marks_t *) malloc(sizeof(marks_t));
next1->m = 27;
next1->next = NULL;
list->next = next1; // Storing address of next1 structure in list

Resources