My very first own library. In this project I deepened the basic concepts of C, creating functions such as strlcpy, memset, substr, itoa, split among many more. In addition, I created several useful functions to work with linked lists such as lstaddback, lstclear, lstnew among many more.
In computer programming, a struct (short for structure) is a composite data type that groups together related data items of different data types under a single name. Structs allow us to create a new custom data type that represents a concept or entity in our program.
Here's an example of a struct in C programming language:
struct Person {
char name[50];
int age;
float height;
};
In this example, we have defined a new struct called "Person" that has three members: "name", "age", and "height". The "name" member is an array of characters that can hold up to 50 characters, while "age" and "height" are integers and floating-point numbers, respectively.
We can create instances of this struct by declaring variables of type "Person" and initializing their members:
struct Person john;
john.age = 30;
john.height = 1.8;
strcpy(john.name, "John Smith");
In computer science, a linked list is a data structure that consists of a sequence of elements, each of which contains two fields: a data field to store the actual data, and a link field to point to the next element in the sequence. The link field essentially creates a link between the elements, hence the name "linked list.”
Linked lists are often used to represent linear data structures that can grow or shrink dynamically, as opposed to arrays, which have a fixed size. Linked lists are also more flexible than arrays because they can be easily modified by inserting or deleting elements in the middle of the list.
There are several types of linked lists, including singly linked lists, doubly linked lists, and circular linked lists.
typedef struct s_list
struct s_list {
void *data;
struct s_list* next;
} t_list;
A doubly linked list is a type of linked list in which each node has two pointers: one to the previous node in the sequence and one to the next node in the sequence. In other words, a doubly linked list is a linked list in which each node points to both its predecessor and its successor in the list.
typedef struct s_list
struct s_list {
void *data;
struct s_list* next;
struct s_list* prev;
} t_list;
A circular linked list is a type of linked list in which the last node in the list points back to the first node, forming a loop. In other words, a circular linked list is a linked list in which the "next" pointer of the last node points to the first node instead of NULL.
In C, a pointer is a variable that stores the memory address of another variable. A pointer can be used to indirectly access or modify the value of the variable that it points to.
int x = 5;
int *ptr = &x;
This sets the value of ptr
to the memory address of x
, allowing us to indirectly access or modify the value of x
using the pointer.
Here's an example of a function increment()
that takes an integer variable x
as a parameter by value and returns the incremented value:
int increment(int x) {
return x + 1;
}
In this case, the x
parameter is passed by value, meaning that a copy of the variable's value is made and passed to the function. Therefore, any modifications made to x
within the function will not affect the original variable outside of the function.
Alternatively, you can pass the variable as a pointer and use the const
keyword to indicate that the variable should not be modified within the function:
int increment(const int *x) {
return (*x) + 1;
}
In this example, the x
parameter is a pointer to an integer value, but it is marked as const
, which means that the function cannot modify the value of x
. Instead, it dereferences the pointer using the *
operator to access the value and return the incremented value.
In both cases, the original variable is not modified within the function, and its value remains unchanged outside of the function call.
If you want to change the value of a variable outside of its scope, you can pass it as a pointer to the function and modify its value using the dereference operator *
.
Here's an example of a function increment()
that takes a pointer to an integer variable x
as a parameter and increments its value:
void increment(int *x) {
(*x)++;
}
In this case, the x
parameter is a pointer to an integer variable. By dereferencing the pointer using the *
operator, we can access the value of x
and modify it using the increment operator ++
. Since x
is a pointer to the original variable, any changes made to x
within the function will also be reflected in the original variable outside of the function.
A Makefile is a file that specifies the dependencies and rules for building a program or set of programs. It is used by the Make build automation tool to manage the building and rebuilding of the program or programs.
.PHONY: all clean
In a Makefile, a phony target is a target that does not correspond to an actual file or directory on disk. Instead, it is a target that performs a specific action or set of actions, such as compiling a program or cleaning up temporary files.
Using a phony target in a Makefile can have several benefits:
- Prevent accidental conflicts with existing files or directories: By declaring a target as phony, you avoid naming conflicts with existing files or directories. For example, if you have a target named
clean
that removes temporary files, you don't want to accidentally delete a file namedclean
that may be important. - Improve performance: By marking a target as phony, you tell Make that it does not depend on any files or directories, which can help to avoid unnecessary checks and improve performance.
- Increase clarity and maintainability: Using phony targets can make your Makefile more clear and maintainable, as it clearly separates the targets that correspond to actual files and directories from the targets that perform actions.