Structure type in C - c

I have a very basic question. In C, we declare a structure like so:
Snippet 1:
struct node {
int a;
int b;
char c;
};
I understand the basic concept behind structures. It can be viewed from many angles. It's a "structure", it is used to create a user defined type.
A structure is useless unless we define objects for it. We can create objects for it like so:
struct node obj1;
obj1.a=10; // corresponds to the value of obj1
obj1.c='A'; // ....
and so on..
Okay,
Now this following code snippet I cannot understand.
Snippet 2:
struct node {
node* left;
node* right;
int value;
};
How can we define node* left and node* right in the structure named node when the structure node hasn't even been completely formed yet?
What does it even mean? How can it point to something that hasn't even been formed yet?
How does it even know the size of the object to allocate when we create an object of node?
Can anyone help me out on this?
Edit: The code in the question is not valid C code, but it is valid C++ code

How can we define node* left and node* rightin the structure named node when the structure node hasn't even completely formed yet?
node * is pointer and a pointer does not require complete definition. Only declaration of type is enough.
What does it even mean? How can it point to something that hasn't even been formed yet?
Such structures are known as self-referencing. They can refer to the an object which (must)have same type as they have. This is one of the basis of linked list, trees, graph and many data structure.
How does it even know the size of the object to allocate when we create an object of node?
As object contains pointer, size of pointer is fixed and is known before knowing the complete object. Hence, size of object can be allocated. In this case, it will be size of data members+size of pointers+some padding.

Adding to the previous answer.
First you need to understand this What is the difference between a definition and a declaration?
Self referencing is a feature programming languages offer. It gives the user (the programmer) flexibility in building data types (graphs, linked list and many more).
Self referencing is using the fact that pointers could be declared and only be defined later. It sounds a little far fetched for the beginner, but the reason that is that pointers have a fix size of 4 bytes. Therefore, the compiler already knows how much memory to allocate for it and it assumes the pointer will be declared later on.
Hope I made it clearer

Related

static linked list in C that holds any data type but all of the same type

I'm trying to implement a static linked list in C that holds any data type. I know that the node struct should use a void* but I also want each list to hold the same data type. That is, lists can hold any data type but every item in the list must be of the same type. I know using void* allows nodes to have any data type but how do I make it so that a list only contains items of the same type?
You can use the macro system to handle non void * lists... if you do something like:
#define LIST_OF(_type) struct node_of_##_type { \
struct node_of_##_type *prev, *next; \
_type data; \
}
then, you can declare as many list types as you want, you have only to say something like:
typedef char *string;
LIST_OF(string) *my_list = NULL;
/* will expend to something similar to:
struct node_of_string {
struct node_of_string *prev, next;
string data;
} *my_list = NULL;
*/
This is an attempt (well, too far yet to be comparable) to emulate the templates of C++. You will not have a list capable of storing anything, but a list adapted only to one type (but any type that can be typedef'd, as the type parameter must be a typename, not a type specification. And, as in C++, once you have that you have to instantiate every function using that type, to the proper type, forcing you to name it, (as functions cannot be overloaded in C) and to rewrite (by means of more macro expansions) to the actual code. Things get complicate soon, making it necessary some help from the language to use OOP techniques in C.
The problem with C is that it is a weakly typed language, this means that you can cast a Banana to a Truck and the compiler will be totally fine with that. Programmers in C are conditioned to keep this in mind and be very wary of what they are doing, that is to say it is the programmers responsibility to "think ahead" and make no such mistakes (e.g. like putting a Banana in a list of Trucks). You could work around this by adding another layer between your datatypes and the list nodes. A trust could hold a void* to the actual type together with an enum or an integer value representing the id of the data type you are trying to store in the list, you could call this a tagged node or something. The issue now becomes how to retrieve that tag or enum value. This will sadly add some boilerplate to your program, however, this might be automated using macro's.
Note that the problem you are highlighting (weak typing) is just part of the quirkiness of C. what I usually do in these situations is naming the variable holding the list accordingly and think very carefully of what I am doing with this variable.
A solution may be to, instead of using a List, use an array, this will at least produce a segmentation fault in some scenario's, but that will also be the case if you cast a Truck to a Banana and try to access fields which are out of memory range...
Hope this helps!

Linked list node with pointer to struct in C

I am new to C programming. Familiarising muself with struct pointers and linekd lists. I came across concept of linked list node with pointer to struct.
typedef struct
{
string name, surname;
int matriculation_num;
}Student_typedef;
typedef struct
{
Tstudent* student;
Node_typedef* next;
} Node_typedef;
Can anyone tell me what exactly is the purpose of Node_typedef. Where are such implementations usefull ?
Any useful link is much appreciated.
The two shown struct type definitions separate the stored data from the storing mechanism.
You can see that Student_typedef has only members which relate to information to store, but none relating to storing. The goal is to have a mechanism which can store a multitude of this data structure.
On the other hand Node_typedef does not contain any of the information to store, only a single pointer to the complete data. If the structure of the inforamtion to store would change (though still be reflected by the same type identifier Student_typedef), then nothing about this storage mechanism would have to be changed.
Or to describe it from a different angle, two developers working on a student database would only have to agree that all the needed information for each student is inside Student_typedef. Then one developer could handle programming functions to enter or edit a given struct (based on a pointer to the struct provided by the storage), while the other developer could handle storage aspects, like adding a new struct to fill, deleting, optimising memory, etc.
Such methods of interface definition and abstraction of code parts are necessary for efficiently handling large projects.

Struct Pointers in C

typedef struct data * Data;
I have something like this that I don't understand. I have some function later on that returns Data. What I don't get is, data * Data seems to me like a "empty" struct .. It doesn't have anything in it.
So what do I create when I do something like Data d; and what do I returns from function if this struct is empty?
Thank you.
That line of code is creating a type alias. It means that Data is an alias for the type struct data *. So, whenever you see Data, it's as if you saw a pointer to struct data.
When you do something like Data d;, you're basically declaring a pointer to struct data. You're not initializing the pointer, so it doesn't point to a valid struct data. Dereferencing the pointer will thus be invalid.
When you have a variable of type Data, you need to point it to somewhere valid before trying to dereference it.
Perhaps a less confusing approach would have been to do it like this instead:
typedef struct data *Data_ptr;
Which at least would convey the idea that Data_ptr is a pointer type alias.
You are looking at an opaque pointer.
Which means that the structure details are hidden to you, but the library functions that are using it are aware of the true content of the struct.
This type of declaration is usually made in public header files, while more private implementation use a complete declaration of the struct.

Why do we need pointers in C implementation of a linked list?

Why is it important to use pointers in an implementation of linked lists in C?
For example:
typedef struct item
{
type data;
struct item *next;
} Item;
typedef struct list
Item *head;
} List;
What would happen if Ill use the same implementation just without the pointers?
Well you'll end up with something like this
typedef struct item
{
type data;
struct item next;
} Item;
and now the C compiler will go to try to figure out how large Item is. But since next is embedded right in Item, it'll end up with an equation like this
size-of-Item = size-of-type + size-of-Item
which is infinite. Hence we have a problem. Because of this, C requires pointers so you have
size-of-Item = size-of-type + size-of-pointer
which is closed. More interestingly, even when you do this in languages like Java, Python, or Haskell, you're really implicitly storing a pointer (they say reference) to break the cycle. They just hide the fact from you.
You do not actually need to use pointers to implement a data structure that exposes the interface of a linked list, but you do need them in order to provide the performance characteristics of a linked list.
What would the alternatives to pointers be? Well, item needs to have some way to refer to the next item. It cannot aggregate the next item for various reasons, one of them being that this would make the struct "recursive" and therefore not realizable:
// does not compile -- an item has an item has an item has an item has...
typedef struct item
{
type data;
struct item next;
} Item;
What you could do is have an array of items and implement the linked list on top of that:
Item *storage[100];
typedef struct item
{
type data;
int next; // points to the index inside storage of the next item
} Item;
This looks like it would work; you can have a function that adds items to the list and another that removes them:
void add_after(Item *new, Item *existing);
void remove(Item *existing);
These functions would either remove existing from the array (taking care to update the next "pointer" of the previous item) creating an empty slot, or find the existing item and insert new in an empty slot in storage (updating next to point there).
The problem with this is that this makes the add_after and remove operations not realizable in constant time because you now need to search into the array and reallocate it whenever you are out of space.
Since constant time add/remove is the reason people use a linked list for, this makes the non-pointer approach only useful as an intellectual exercise. For a real list, using pointers means you can perform these operations in constant time.
Pointers are used for dynamic allocation of memory. You can implement a list as a simple array but that means that you allocate a continuous memory area, which for a large list is not efficient. Also, arrays are more difficult cu extend (you have to reallocate it if you reach its maximum size).
Therefore, dynamic allocation is preferred for large lists, and for each element it can allocate it into memory in any place, continuously or not, and you can extend it easily.
Also, you cannot store in an struct item another struct item because the structure is not defined yet and it cannot establish the size of the structure:
This cannot be done:
typedef struct item
{
type data;
struct item next;
} Item;
Therefore pointers are used because the size of a pointer can be determined (the size of an integer on that platform) when the structure is compiled.
Without a pointer, each list item contains another list item (next) which contains another list item. Which in turn contains another list item. And so on.
You end up with an infinitely large data structure that would use an infinite amount of memory, and that of course can't work.
You don't need a pointer to create a list in C. If a pointer list is preferable depends on your application. People used linked lists before they had a concept of pointers implemented in languages. It's only sometimes simpler to comprehend for some people (with pointers). You don't need a structure with data either.
A simple array will do fine. You need:
one integer array to hold indices (this resembles the pointer). Array content is either -1 (means nil or NULL in pointer terminology), or 0 .. N-1, means: the array index of the next element linked. The index-array's index represents the item 's index in the data array.
one array for any data to be 'connected' within the 'list' above.
That's all you need.
An array instead of a pointer list may have
advantages, if the amount of your data doesn't change (doesn't grow). In this case, the advantages can be huge. If you know the maximum number of data you'll encounter and can allocate data beforehand, an array implementation will be much faster than any pointer-linked list. Especially, if you only insert, but don't need to remove.
disadvantages otherwise. In this case, the disadvantages can be huge.
Please read up here.
Your example would, therefore, look like:
type data[N]; // or: type *data = new type [N];
int links[N]; // or: int *links = new int [N];
That should be all you need to start with a simple test case.
Important of pointer in c
advantages:-
Execution speed will be high.
pointers allow us to access the variable which is outside of a function.
reduce the size of our code.
without pointers:-
Code size will get increase.
We cannot maintain the data efficiently.
In list the pointer is used to point the next item from the list.If you are not declared the pointers means you cannot access more than one item from the list.
If you allocate some memory dynamically at run time that time really the pointers are much needed.
There's more than one kind of "list". The implementation you show is a "Linked List". Without pointers there would be no "links", so we'd need to look at other kinds of lists.
So, first up, what happens if you just remove the * from the struct definition: it won't compile. You can include a struct inside of another struct, but if there's recursion then the structure will have infinite size that isn't going to happen!
How about an array as a list:
struct item list[100];
Yep, that'll work, but now your list is a fixed size.
Ok, so let's dynamically allocate the list:
struct item *list = malloc(sizeof(struct item));
Then, everytime you add to the list you'd have to do this:
list = realloc(list, newcount * sizeof(struct item));
list[newitem] = blah;
OK, that works, but now we're reallocating memory frequently, and that leads to lots of memory copies, and inefficiency.
On the other hand, if the list is updated very infrequently, this is more space-efficient, and that might be a good thing.
Another disadvantage of using an array is that operations such as push, pop, sort, reverse, etc. become much more expensive; they all mean multiple memory copies.
There are other kinds of "list", but they all involve pointers, so I think we can disregard them here.

Common datastructure library in C

Hello I have started writing common data structure library in C similar to STL.
Here is the link . http://code.google.com/p/cstl/
I struggled a lot of whether to go ahead with having void* as basic element for data structure. and End up with structure which has two elements
typedef struct __c_lib__object {
void* raw_data;
size_t size;
} clib_object, *clib_object_ptr;
This approach allow me to store each element, but it requires lot of memory allocation , during saving and returning back the element from the container.
Can anybody please review this , and let me know if there is any other approach.
Thanks
Avinash
Names starting with double-underscore are reserved to 'the implementation' and should be avoided in user code.
Personally, I dislike typedefs for pointers; I'd rather use clib_object *x; than clib_object_ptr x;.
Why do you need to record the size of the object?

Resources