Important Details to Understand About C Language
multiple pointers can point on the same memory location
#include <stdlib.h> int main(){ int *pt1 = malloc(sizeof(int)); if(pt1 == NULL){ return(1); } *pt1 = 42; int *pt2 = pt1; // point pt2 to the same memory location as pt1 int *pt3 = pt2;// point pt3 to the same memory location as pt2 free(pt1); return(0); }
size_t
is used because lengths can't be negative and it handles large memory efficiently.
In General: For size-related tasks (like arrays and memory allocations),size_t
is better due to its flexibility and portability.size_t ft_strlen(const char *s)
C Language allows the char type to be either signed or unsigned, depending on the compailer and architecture that’s why should handle this case, that why we cast it to be unsigned char
if char is signed can hold negative values (from -128 to 127), while an unsigned char holds values (from 0 to 255)#include <stdio.h> int main() { char normalChar = -1; printf("Normal char (as signed): %d\n", normalChar); // print : -1 unsigned char unsignedChar = (unsigned char)normalChar; printf("Converted to unsigned char: %u\n", unsignedChar);// print : 255 return 0; }
the (char ) Cast is necessary because haystack is declared as const char (meaning a pointer to a constant character), But the fucntion returns a char (a pointer to a non-constant charactere), the Cast ensure the function returns the correct type (char *)
char *ft_return_haystack(const char *haystack) { return ((char *)(haystack)); }
char ft_strchr(const char *s, int c)
const char *s
This ensures that the function can read the string but cannot change it.This is important, especially when working with string literals, which are stored in read-only memory.//without const char *str = "Hello, World!"; // String literals are stored in read-only memory char *result = ft_strchr(str, 'W'); // Let's assume we mistakenly modify the string *result = 'Z'; // Changing 'W' to 'Z'
In this case, the program might crash or behave unpredictably because you're attempting to write to a part of memory that is supposed to be read-only.
the reason we use void *str is because the function is designed to work with any type of data.
void *ft_return(void *str)
unsigned char : converting the (void )pointer str to a pointer to unsigned char.
This tells the compiler that str should now be treated as a pointer to a series of bytes (unsigned char),
allowing you to manipulate the memory at the byte level.
void *ft_return(void *str) { unsigned char *ptr; ptr = (unsigned char *)str; return ptr; }
arrays in C are zero-indexed
\==>Use
+
when converting an integer digit to its corresponding character.result += s[i] '0';
\==>Use
-
when converting a character back to its integer valueresult += s[i] - '0';
When you allocate memory using
malloc
, you receive a pointer of typevoid *
, which is a generic pointer type that can point to any data type. To use this pointer effectively, especially when you know the intended data type, you often cast it to the appropriate pointer type, such aschar *
,int *
#include <stdlib.h> #include <stdio.h> int main() { char *s; // Allocate memory for 4 characters s = (char *)malloc(4 * sizeof(char)); // Use the allocated memory (Example: store "abc" in the allocated memory) s[0] = 'a'; s[1] = 'b'; s[2] = 'c'; s[3] = '\0'; // Null-terminating the string printf("The string is: %s\n", s); // Output the string // Free the allocated memory when done free(s); }
When you declare a variable like
char P1;
, you are creating a variable that holds a single character in stack memory. However, when you allocate memory usingmalloc
, the memory allocated on the heap is indeed a pointer of typevoid *
, which can be cast to any other pointer type.One of the key reasons to use
malloc
is dynamic memory allocation. By usingmalloc
, you don't need to declare a fixed-size buffer in advance, and you can allocate exactly the amount of memory you need at runtime based on the input.you cannot dynamically allocate memory for
char buffer[len];
like that in C unlesslen
is a constant. This is because in C, arrays declared with the syntaxchar buffer[len];
are allocated on the stack, and the size must be known at compile time.
Subscribe to my newsletter
Read articles from Zouhair Grir directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Zouhair Grir
Zouhair Grir
I'm GRIR Zouhair, a dedicated and experienced Full-Stack Developer from Morocco. With a strong passion for coding and a knack for solving complex problems, I excel in creating robust and scalable web applications. My expertise spans across both front-end and back-end technologies, allowing me to deliver comprehensive and seamless solutions.