Function Pointers for Callbacks
Function pointers allow you to pass functions as arguments to other functions, enabling flexible and generic code patterns like callbacks.
Open snippet →Read these Intermediate C snippets line by line — each one comes with a written breakdown of what the code does and why.
Function pointers allow you to pass functions as arguments to other functions, enabling flexible and generic code patterns like callbacks.
Open snippet →In C, array names decay into pointers. Adding an integer to a pointer (pointer arithmetic) moves the pointer by that many elements, not bytes.
Open snippet →Using malloc to allocate memory for structures on the heap is essential when the size or lifetime of the data isn't known at compile time.
Open snippet →Bitwise operators are used to store multiple boolean flags within a single integer, which is highly memory-efficient and fast.
A static local variable retains its value between function calls, initialized only once when the program starts.
Open snippet →The 'restrict' qualifier is a hint to the compiler that for the lifetime of the pointer, only the pointer itself or a value derived from it will be used to access the object it points to. This allo…
Open snippet →Variadic functions allow you to pass a variable number of arguments to a function. This is achieved using the macros defined in <stdarg.h>. You must provide at least one fixed argument (like 'count…
Open snippet →A union allows different data types to be stored in the same memory location. The size of the union is determined by its largest member. This is particularly useful in systems programming for overl…
Open snippet →While often discouraged, using 'goto' for centralized resource cleanup is a common pattern in intermediate C (e.g., in the Linux kernel). it prevents deep nested if-statements and ensures that all…
Open snippet →Wrapping a multi-statement macro in a 'do { ... } while (0)' block ensures it behaves as a single statement. This prevents logical errors when the macro is used inside 'if' statements without curly…
Open snippet →Designated initializers allow you to initialize structure members by name rather than by position. This makes code more robust against changes in the structure definition and improves readability b…
Open snippet →The 'volatile' keyword tells the compiler that a variable's value can change at any time without any action being taken by the code nearby. This prevents the compiler from applying optimizations th…
Open snippet →_Static_assert (introduced in C11) allows checking conditions during the compilation phase rather than at runtime. If the condition is false, the compiler generates an error and stops, preventing t…
Open snippet →The 'inline' keyword is a hint to the compiler to replace function calls with the actual function body. This eliminates function call overhead (stack manipulation, jumping) for small, frequently us…
Open snippet →In C, multidimensional arrays are stored in row-major order. To correctly calculate memory offsets, a function receiving a 2D array must know the size of the columns (the second dimension), while t…
Open snippet →The snprintf function is a safer alternative to sprintf because it requires a maximum buffer size. This prevents buffer overflows by ensuring that no more than 'n' characters are written, including…
Open snippet →The stdatomic.h header (C11) provides types and functions for atomic operations, which are essential for thread-safe programming without the overhead of heavy locks. These operations are guaranteed…
Open snippet →The strcspn function calculates the length of the initial segment of a string that consists entirely of characters NOT in a specified set. It is highly efficient for finding the first occurrence of…
Open snippet →The setvbuf function allows manual control over how a file stream (like stdout) is buffered. You can choose between fully buffered (_IOFBF), line buffered (_IOLBF), or unbuffered (_IONBF). Disablin…
Open snippet →Unlike the simpler atoi(), strtol() provides robust error checking and handles different number bases. It detects overflow, empty inputs, and tells you exactly where the numeric portion ends by upd…
Open snippet →Variadic functions allow a function to accept an indefinite number of arguments. The 'stdarg.h' header provides macros like 'va_start', 'va_arg', and 'va_end' to traverse the argument list safely b…
Open snippet →The '_Generic' keyword, introduced in C11, provides a way to perform compile-time type dispatch. It allows a macro to evaluate to different expressions based on the type of its controlling expressi…
Open snippet →The 'restrict' keyword is a hint to the compiler that the pointer is the only means to access the object it points to within that scope. This eliminates potential 'pointer aliasing', allowing the c…
Open snippet →Unions allow the same memory location to be interpreted as different types. This 'type punning' is often used at an intermediate level to inspect the raw binary representation of data types like fl…
Open snippet →Compilers insert 'padding' bytes between structure members to ensure they are aligned with memory boundaries for performance. The 'offsetof' macro from 'stddef.h' allows you to see the exact byte o…
Open snippet →Function pointers allow functions to be passed as arguments, enabling dynamic behavior at runtime (callbacks).
Open snippet →Bit fields allow defining structure members with a specific number of bits to save memory or map to hardware registers.
Open snippet →When using realloc, always use a temporary pointer. If realloc fails, it returns NULL but the original memory remains allocated.
Open snippet →The standard qsort function uses a comparison callback to determine the sort order of any data type.
Open snippet →In C, goto is often used to jump to a single cleanup block, ensuring resources are freed without duplicating code in multiple error checks.
Open snippet →