C Glossary
Key terms from the C course, linked to the lesson that introduces each one.
3,202 terms.
#
- __attribute__((packed))
- The __attribute__((packed)) directive instructs the compiler to eliminate padding bytes, creating a smaller, dense structure at the cost of potential performance overhead.
- Lesson 577 — Using __attribute__((packed))Lesson 642 — The `__attribute__((packed))` directive
- __builtin_bswap
- The __builtin_bswap family of functions tells the CPU to use a specialized hardware instruction (like BSWAP on x86) to flip the bytes in a single clock cycle.
- Lesson 956 — The `__builtin_bswap` compiler intrinsics
- __builtin_popcount
- In this snippet, __builtin_popcount isn't a function you wrote or linked from a library.
- Lesson 964 — Compiler intrinsics as an alternative
- __FILE__
- Use __FILE__ and __LINE__ in your error messages to let the compiler tell you exactly where your program is failing.
- Lesson 1159 — Using `__FILE__` and `__LINE__` macros
- __HEADER_H
- Avoid Reserved Prefixes: Never start your guards with double underscores (e.g., __HEADER_H) or a single underscore followed by a capital letter.
- Lesson 1203 — Header guard best practices
- __LINE__
- Macros are perfect for this because they can capture the exact line number where a failure occurred using the built-in __LINE__ constant.
- Lesson 1159 — Using `__FILE__` and `__LINE__` macrosLesson 1174 — Building a minimal custom test harness
- __linux__
- For example, _WIN32 is typically defined on Windows, while __linux__ is defined on Linux.
- Lesson 783 — Testing for platform-specific code
- __thread
- When you mark a variable with __thread, the operating system and linker work together to create a new "copy" of that variable every time a new thread starts.
- Lesson 1122 — Thread-local storage basics
- __x86_64__
- If it sees __x86_64__, it ignores the ARM code entirely.
- Lesson 963 — Platform-specific assembly (x86 vs ARM)
- _Alignas
- Use _Alignof to discover a type's memory boundary requirements and _Alignas to strictly enforce custom memory positioning.
- Lesson 933 — The `_Alignof` and `_Alignas` keywords
- _Alignof
- What you'll learn: How to use the _Alignof operator to discover the memory alignment requirements of different data types.
- Lesson 453 — Determining variable alignment in memoryLesson 933 — The `_Alignof` and `_Alignas` keywords
- _Atomic
- Use volatile to prevent compiler optimizations on hardware-related memory, and use _Atomic to prevent data corruption in multi-threaded programs.
- Lesson 1141 — Introduction to <stdatomic.h>Lesson 1147 — Volatile vs Atomic
- _Bool
- If you wanted to make your code readable, you had to manually define constants or include <stdbool.h> (introduced in C99), which gave you bool as a macro for the slightly clunky _Bool type.
- Lesson 647 — Restrictions on bit-field typesLesson 969 — C23: The `bool`, `true`, and `false` keywords
- _Generic
- Unlike a C++ template, where code for a specific type is only generated if you use it, C requires every single expression inside a _Generic selector to be syntactically valid and type-correct—even the ones that aren't chosen.
- Lesson 973 — Introduction to the `_Generic` keywordLesson 974 — The syntax of a generic selectionLesson 975 — Implementing a generic 'Print' macroLesson 976 — Handling the `default` case in `_Generic`Lesson 977 — Type-based function overloading simulationLesson 978 — Comparing `_Generic` to C++ templatesLesson 979 — Mathematical macros using `_Generic`Lesson 980 — Limitations of C generics
- _IOFBF
- Alternatively, if you were writing a massive 1GB file, you might create a large char array of 64KB and pass it to setvbuf with _IOFBF to make the process much faster by reducing the number of hardware writes.
- Lesson 752 — Setting custom buffers with setvbuf
- _IOLBF
- _IOLBF (Line Buffering): It flushes the data whenever a newline (\n) is encountered.
- Lesson 752 — Setting custom buffers with setvbuf
- _IONBF
- _IONBF (No Buffering): Data goes straight to the disk immediately.
- Lesson 752 — Setting custom buffers with setvbuf
- _t
- Use a consistent naming style like PascalCase or a _t suffix for typedef names to clearly separate type definitions from variable names.
- Lesson 86 — Fixed-width types from `<stdint.h>`Lesson 612 — Naming conventions for typedef types
- _WIN32
- For example, _WIN32 is typically defined on Windows, while __linux__ is defined on Linux.
- Lesson 783 — Testing for platform-specific code
- --j
- To avoid these bugs, never pass expressions that change values (like i++, --j, or func()) into a macro.
- Lesson 775 — Side effects in macro arguments
- --x
- Prefix decrement (--x) subtracts one from a variable immediately and returns the updated value to the rest of the expression.
- Lesson 200 — Prefix decrement `--x`
- -based
- C23’s nullptr replaces the ambiguous 0-based NULL macro with a dedicated, type-safe constant specifically designed for pointers.
- Lesson 970 — C23: The `nullptr` constant
- -c
- The -c flag stops the build process early to create an object file (.o), allowing you to compile individual pieces of a program without linking them into a final executable.
- Lesson 804 — The `-c` flag for compilation
- -D
- The -D flag allows you to pass configuration settings from your terminal directly into your code, enabling "feature toggles" at compile time.
- Lesson 786 — Feature toggles via command line `-D`
- -DDEBUG
- By typing -DDEBUG in your terminal, you are telling the compiler, "For this specific build, act as if #define DEBUG is written at the top of every file."
- Lesson 786 — Feature toggles via command line `-D`
- -DNDEBUG
- If you are using a tool like GCC, you can add the flag -DNDEBUG to your build command.
- Lesson 902 — Disabling assertions with `NDEBUG`
- -DPREMIUM
- The compiler sees the -DPREMIUM flag, satisfies the #ifdef condition, and includes the premium message in the final executable.
- Lesson 786 — Feature toggles via command line `-D`
- -E
- What you'll learn: How to use the -E flag to peek behind the curtain and see exactly how the preprocessor modifies your source code before the compiler ever sees it.
- Lesson 767 — How `gcc -E` shows preprocessor output
- -fPIC
- The -fPIC flag ensures shared library code uses relative memory addresses rather than fixed ones, allowing multiple programs to share the same code regardless of where it is loaded in memory.
- Lesson 814 — Position Independent Code `-fPIC`
- -fsanitize=address
- Compile with -fsanitize=address to turn memory bugs into immediate, descriptive crashes that tell you exactly where you went wrong.
- Lesson 1171 — Using AddressSanitizer (`-fsanitize=address`)
- -fsanitize=undefined
- UBSan is a compiler flag (-fsanitize=undefined) that makes your program "scream" the moment it hits Undefined Behavior, turning invisible bugs into readable error reports.
- Lesson 941 — Tools to detect UB: UBSan
- -g
- If you compiled this with the -g flag (which is required for GDB to "see" your text), typing list inside GDB would show you exactly these lines, complete with their line numbers.
- Lesson 565 — Running a program under ValgrindLesson 821 — Using variables in MakefilesLesson 825 — Compiling with debug symbols `-g`Lesson 826 — Starting GDB with an executableLesson 827 — The `run` and `quit` commandsLesson 828 — Listing source code with `list`Lesson 837 — Debugging a Segfault from a core dumpLesson 1160 — Compiling with `-g` for debug symbolsLesson 1161 — Starting a program in `gdb` or `lldb`Lesson 1165 — Installing and running `valgrind`Lesson 1167 — Tracking down 'Use After Free' bugsLesson 1171 — Using AddressSanitizer (`-fsanitize=address`)Lesson 1186 — Using `perf` for hardware-level insights
- -I
- However, since the header is no longer in the same folder as the source code, you typically tell your compiler (like GCC) where the "spice rack" is located using the -I (include) flag.
- Lesson 63 — Header search pathsLesson 800 — Organizing /src and /include foldersLesson 1201 — Using `clang-format` for automationLesson 1208 — Adding command line flags (e.g., `-i` for case)
- -Iinclude
- The -Iinclude part tells the preprocessor: "If you can't find a header file in the current folder, check the /include directory next."
- Lesson 800 — Organizing /src and /include folders
- -L
- If you forget -L, the compiler will say "library not found." If you forget -l, the compiler will complain about "undefined references" because it saw the function calls in your code but didn't know which library provided the instructions to execute them.
- Lesson 812 — Linking with static librariesLesson 815 — Linking with shared libraries `-l` and `-L`
- -L./libs
- -L./libs: Adds the "libs" folder to the search path.
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- -lm
- On some systems (like Linux), when you use <math.h>, you need to tell the compiler to link the math library manually by adding -lm to the end of your compile command, like this: gcc main.c -lm.
- Lesson 861 — Basic power and square root: `pow` and `sqrt`Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`Lesson 863 — Trigonometric functions in radians
- -lmathhelper
- For example, to link a library file named libmathhelper.so, you simply write -lmathhelper.
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- -lmathutils
- -lmathutils tells it to link the library (the lib prefix and .a extension are assumed).
- Lesson 812 — Linking with static libraries
- -lphysics
- -lphysics: Searches for a file named libphysics.so (or .dylib) inside those paths and links it.
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- -o
- This is why, as you move toward professional development, you will eventually start using the -o (output) flag to give your programs unique names, like gcc hello.c -o hello.
- Lesson 57 — Basic `gcc` command flagsLesson 58 — Naming the output with `-o`Lesson 60 — Understanding the `a.out` defaultLesson 1188 — Compiler optimization levels (`-O1`, `-O2`, `-O3`)
- -O0
- By default, the compiler uses -O0 (no optimization).
- Lesson 1188 — Compiler optimization levels (`-O1`, `-O2`, `-O3`)
- -O2
- On a modern compiler with optimizations turned on (-O2 or -O3), the code above might print 1.000000 instead of the integer bit-pattern you expected.
- Lesson 936 — Strict aliasing rule violationsLesson 958 — The basic `volatile` asm blockLesson 1188 — Compiler optimization levels (`-O1`, `-O2`, `-O3`)Lesson 1190 — Loop unrolling explained
- -O3
- Only switch to -O3 if you are building something performance-heavy, like a game engine or a physics simulator, and you have tested to ensure the larger file size is worth the speed boost.
- Lesson 936 — Strict aliasing rule violationsLesson 958 — The basic `volatile` asm blockLesson 1188 — Compiler optimization levels (`-O1`, `-O2`, `-O3`)Lesson 1190 — Loop unrolling explained
- -pg
- The gprof profiler helps you find "hotspots" in your code by recording function execution times, provided you compile with the -pg flag.
- Lesson 1182 — Introduction to the `gprof` profiler
- -score
- If you hit a "penalty" zone, the game might calculate your new score as -score.
- Lesson 156 — Unary plus and minus
- -std=
- Use the -std= flag to ensure your compiler follows a specific version of the C standard, making your code predictable and portable across different systems.
- Lesson 972 — Specifying the standard with `-std=` flags
- -std=c11
- If you write code using -std=c11, you can be confident that another developer using a different compiler (like Clang instead of GCC) will be able to build your project as long as they also use the C11 flag.
- Lesson 972 — Specifying the standard with `-std=` flags
- -std=c99
- Specifying -std=c99 tells the compiler to allow it.
- Lesson 972 — Specifying the standard with `-std=` flags
- -Wall
- The -Wall flag stands for "Warnings: all." It tells the compiler to be extra chatty and warn you about potential mistakes, even if they aren't technical errors that stop the compilation.
- Lesson 57 — Basic `gcc` command flagsLesson 69 — Enabling all warnings with `-Wall`
- ." Since
- The inner loop starts and says, "Run until j reaches i." Since i is 1, it runs once and prints one star.
- Lesson 303 — Controlling the inner loop with outer loop variables
- ./hello
- If you compile this as hello, you can run it normally: ./hello.
- Lesson 761 — Standard stream redirection in shells
- ./hello < name.txt
- From a file: ./hello < name.txt (The program reads the name from the file instead of waiting for you to type).
- Lesson 761 — Standard stream redirection in shells
- ./hello < name.txt > output.txt
- Both: ./hello < name.txt > output.txt (A completely automated process).
- Lesson 761 — Standard stream redirection in shells
- ./hello > output.txt
- To a file: ./hello > output.txt (The screen stays blank; the greeting goes into the file).
- Lesson 761 — Standard stream redirection in shells
- ./my_program
- Up until now, you have likely tested your code by running ./my_program, typing in a value, and checking if the output looks right.
- Lesson 32 — Executing from the command lineLesson 1178 — Automating tests with a Shell script
- ./myprog > log.txt
- When you run ./myprog > log.txt, the shell forks a process, uses dup2() to swap the child's STDOUT with the file, and then executes your code.
- Lesson 1095 — Redirecting output with dup2()
- ./myprog hello world
- When you run a command like ./myprog hello world, the operating system gathers those words and hands them to your program.
- Lesson 506 — Command line arguments `char **argv`
- ./program
- When you run ./program, the tool will intercept the error and print:
- Lesson 941 — Tools to detect UB: UBSan
- ./test.sh
- To run this, you would give the script permission with chmod +x test.sh and then type ./test.sh.
- Lesson 1178 — Automating tests with a Shell script
- .a
- The ar tool creates static libraries by bundling .o object files into a single .a archive for easier distribution and linking.
- Lesson 810 — What is a static library `.a`Lesson 811 — Creating archives with the `ar` toolLesson 812 — Linking with static libraries
- .c
- By keeping the "bricks" (the actual memory and logic) in your .c files and only sharing the "blueprints" in your .h files, you ensure that every part of your program is looking at the same map without trying to build the same wall twice.
- Lesson 6 — C as a compiled languageLesson 9 — Role of the CompilerLesson 11 — Setting up MinGW on WindowsLesson 15 — The concept of a Source FileLesson 16 — Naming conventions for .c filesLesson 30 — Creating an executable binaryLesson 57 — Basic `gcc` command flagsLesson 59 — Compiling multiple source filesLesson 62 — Automating the build processLesson 63 — Header search pathsLesson 137 — Global variables and file scopeLesson 146 — The `extern` keyword for multi-file codeLesson 326 — Placement of functions in a fileLesson 368 — Inline functions in header filesLesson 377 — Role of the `.h` fileLesson 378 — Separating interface from implementationLesson 379 — Using `#include` with quotesLesson 381 — Compiling multiple `.c` filesLesson 673 — Opaque types with header filesLesson 788 — The purpose of header filesLesson 792 — Forward declarations in headersLesson 793 — What should NOT go in a headerLesson 795 — Standard header search pathsLesson 796 — Splitting code into `.c` and `.h`Lesson 797 — The `extern` keyword for variablesLesson 798 — Static functions for file scopingLesson 800 — Organizing /src and /include foldersLesson 801 — Naming conventions for large projectsLesson 803 — From source code to object filesLesson 805 — What is inside a `.o` fileLesson 806 — Linking multiple object filesLesson 807 — Understanding 'undefined reference' errorsLesson 809 — Symbol tables and visibilityLesson 817 — Why we need build toolsLesson 822 — Automatic variables like `$@` and `$<`Lesson 918 — Internal vs external linkage basicsLesson 919 — The `static` keyword in global scopeLesson 921 — Sharing variables across files with `extern`Lesson 925 — Common linkage errors and 'multiple definition'Lesson 1210 — Structuring the project into multiple `.c` filesLesson 1211 — Writing the Makefile for the project
- .clang-format
- Professional teams use a .clang-format configuration file in their project folders.
- Lesson 1201 — Using `clang-format` for automation
- .dat
- When the program starts, we want to open our .dat file and fill that array.
- Lesson 1218 — Loading data from a binary file
- .dll
- When you compile a program using a shared library (.so on Linux or .dll on Windows), the library code isn't actually inside your executable.
- Lesson 813 — What is a shared library `.so` / `.dll`Lesson 816 — Runtime library loading and `LD_LIBRARY_PATH`
- .dylib
- There is a small trick here: by convention, shared library files start with lib and end with .so (on Linux) or .dylib (on macOS).
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- .exe
- Portability: You can send your finished .exe to a friend, and it will run even if they don't have the library on their computer.
- Lesson 6 — C as a compiled languageLesson 9 — Role of the CompilerLesson 11 — Setting up MinGW on WindowsLesson 68 — Warnings vs Fatal errorsLesson 810 — What is a static library `.a`Lesson 813 — What is a shared library `.so` / `.dll`
- .gpa
- Identify the field: Use the dot operator (e.g., .gpa) to pick the variable inside that struct.
- Lesson 632 — Indexing into a struct array
- .grade
- Once that specific structure is "selected," we use .grade to drill down into the floating-point value stored there.
- Lesson 633 — Combining array indexing and member accessLesson 635 — Sorting an array of structs
- .h
- By keeping the "bricks" (the actual memory and logic) in your .c files and only sharing the "blueprints" in your .h files, you ensure that every part of your program is looking at the same map without trying to build the same wall twice.
- Lesson 18 — The `#include` directiveLesson 19 — What is a Header File?Lesson 41 — The `stdio.h` libraryLesson 63 — Header search pathsLesson 377 — Role of the `.h` fileLesson 378 — Separating interface from implementationLesson 380 — Header Guards: `#ifndef` and `#define`Lesson 382 — Sharing functions across modulesLesson 678 — The header file <stdio.h>Lesson 788 — The purpose of header filesLesson 790 — Creating basic include guardsLesson 791 — How `#pragma once` worksLesson 793 — What should NOT go in a headerLesson 796 — Splitting code into `.c` and `.h`Lesson 797 — The `extern` keyword for variablesLesson 800 — Organizing /src and /include foldersLesson 811 — Creating archives with the `ar` toolLesson 922 — Using `extern` with functionsLesson 925 — Common linkage errors and 'multiple definition'Lesson 1211 — Writing the Makefile for the project
- .jpg
- Because they treat everything as a raw byte, you can use the exact same code to copy a .txt file or a .jpg file.
- Lesson 1097 — Reading and writing raw bytes
- .lib
- In C programming, a static library (ending in .a for "archive" on Linux/macOS or .lib on Windows) is that toolbox.
- Lesson 810 — What is a static library `.a`Lesson 812 — Linking with static libraries
- .member = value
- Designated initializers use the .member = value syntax to make structure initialization more readable, flexible, and resistant to changes in the struct's definition.
- Lesson 603 — Designated initializers in C99
- .member_name
- By default, a union initialization targets the first member, but you can target any specific member using the .member_name syntax.
- Lesson 660 — Initializing a union
- .member_name = value
- This uses the dot notation (.member_name = value) inside the curly braces.
- Lesson 660 — Initializing a union
- .o
- When you type make clean to sweep away your old .o files, make will look at that file and say: "clean is up to date." It won't run your cleanup commands because it thinks the "job" of creating a file named clean is already finished.
- Lesson 27 — Phase 3: Assembly to Object CodeLesson 28 — Phase 4: The LinkerLesson 29 — Understanding `.o` and `.obj` filesLesson 803 — From source code to object filesLesson 804 — The `-c` flag for compilationLesson 805 — What is inside a `.o` fileLesson 806 — Linking multiple object filesLesson 809 — Symbol tables and visibilityLesson 810 — What is a static library `.a`Lesson 811 — Creating archives with the `ar` toolLesson 822 — Automatic variables like `$@` and `$<`Lesson 823 — Phony targets like `clean` and `all`
- .obj
- However, at the end of that process, you don't have a house; you just have a pile of parts sitting in separate boxes (these are your .obj or .o files).
- Lesson 27 — Phase 3: Assembly to Object CodeLesson 28 — Phase 4: The LinkerLesson 29 — Understanding `.o` and `.obj` filesLesson 803 — From source code to object filesLesson 805 — What is inside a `.o` fileLesson 806 — Linking multiple object files
- .PHONY
- What you'll learn: How to use the .PHONY attribute to ensure Makefile commands like clean run correctly even if files with those names exist.
- Lesson 823 — Phony targets like `clean` and `all`
- .s
- Once this phase is finished, you have an Assembly file (usually ending in .s).
- Lesson 26 — Phase 2: Compilation to Assembly
- .sh
- A Shell script (usually ending in .sh) is just a list of commands your computer executes in order.
- Lesson 1178 — Automating tests with a Shell script
- .size
- .size: Look inside myApp for a member named size.
- Lesson 624 — Accessing members of nested structs
- .so
- When you compile a program using a shared library (.so on Linux or .dll on Windows), the library code isn't actually inside your executable.
- Lesson 813 — What is a shared library `.so` / `.dll`Lesson 815 — Linking with shared libraries `-l` and `-L`Lesson 816 — Runtime library loading and `LD_LIBRARY_PATH`
- .supp
- Valgrind allows you to create a "hush list" called a suppression file (usually ending in .supp).
- Lesson 570 — Suppressing known tool warnings
- .txt
- Because they treat everything as a raw byte, you can use the exact same code to copy a .txt file or a .jpg file.
- Lesson 1097 — Reading and writing raw bytes
- .width
- .width: Look inside that size object for a member named width.
- Lesson 624 — Accessing members of nested structs
- ( *name )
- A function pointer is declared by wrapping the pointer name in parentheses, like ( *name ), and it must strictly match the return type and parameter list of the functions it points to.
- Lesson 928 — Declaring pointers to functions
- ((a++) * (a++))
- However, the preprocessor expands SQUARE(a++) into ((a++) * (a++)).
- Lesson 775 — Side effects in macro arguments
- ((x) * (x))
- You might notice the heavy use of parentheses in ((x) * (x)).
- Lesson 772 — Defining function-like macros
- (*action)()
- While older versions of C sometimes required you to write (*action)();, modern C allows you to use the pointer name directly.
- Lesson 516 — Calling a function via a pointer
- (*array_ptr)
- By adding parentheses (*array_ptr), we force the compiler to treat array_ptr as a pointer first.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- (*name(args))
- To return a function pointer, wrap the function's name and its parameters in a pointer declaration (*name(args)) surrounded by the return type and parameters of the target function.
- Lesson 929 — Returning pointers to functions from functions
- (*ptr)
- By wrapping (*ptr) in parentheses, you are telling the compiler: "This variable itself is the pointer." Think of it as a protective bubble that ensures the "pointer-ness" attaches to the name before the function arguments do.
- Lesson 514 — Syntax of function pointers
- (*ptr).age
- You would normally have to "dereference" the pointer first ((*ptr).age), which is clunky to type.
- Lesson 239 — Member access `.` and `->`
- (*ptr).health
- To change the health through a pointer, you could write (*ptr).health.
- Lesson 617 — Arrow operator vs dot operator
- (*ptr).member
- Use ptr->member as a readable shortcut for (*ptr).member when working with pointers to structures.
- Lesson 616 — The arrow operator `->` syntaxLesson 618 — Passing struct pointers to functionsLesson 619 — Modifying struct members via pointers
- (*ptr).speed
- Because of how C handles math priority, you would have to write something clunky like (*ptr).speed.
- Lesson 616 — The arrow operator `->` syntax
- (A && B)
- In an expression like (A && B), C evaluates the conditions from left to right.
- Lesson 253 — Short-circuit evaluation in logical AND
- (A && B) || C
- When you see (A && B) || C, read it as a story: "The result is true if both A and B happen, OR if C happens on its own." By nesting these logical bricks, you can teach your program to navigate any real-world situation, no matter how many rules are involved.
- Lesson 172 — Building complex logical expressions
- (A || B)
- In the expression (A || B), the computer evaluates A first.
- Lesson 254 — Short-circuit evaluation in logical OR
- (address-of) operator when using
- Always use the %d or %f specifiers to match your variable type, and never forget the & (address-of) operator when using scanf.
- Lesson 693 — Scanning integers and floats
- (ch = getchar()) != EOF
- Notice the line (ch = getchar()) != EOF.
- Lesson 682 — Using while loops with getchar
- (char)myInt
- Use (int)myChar to find a character's numeric code, or (char)myInt to turn a number back into its symbolic character.
- Lesson 131 — Casting between char and int
- (condition)
- However, the do-while loop ends with the condition (condition);.
- Lesson 274 — The do-while syntax and the trailing semicolon
- (connected) or
- When using a 2D array (matrix) to represent our graph, an edge is usually represented by the number 1 (connected) or 0 (not connected).
- Lesson 1043 — Adding edges in undirected graphs
- (cookies / people)
- In the code above, if C evaluated (cookies / people) when people was 0, the program would crash.
- Lesson 170 — Short-circuit evaluation of `&&`
- (double *)
- By using (int ) or (double ), we tell C, "Trust me, for this moment, treat this generic address as this specific type." This flexibility is the foundation for advanced C features like generic lists and sorting functions.
- Lesson 507 — The `void *` generic type
- (double)(end - start) / CLOCKS_PER_SEC
- Use (double)(end - start) / CLOCKS_PER_SEC to turn processor ticks into measurable seconds for performance testing.
- Lesson 1180 — Measuring execution time with `clock()`
- (double)my_integer
- When you write (double)my_integer, you aren't permanently changing the variable; you are just telling the compiler to treat its value as a double for that specific expression.
- Lesson 230 — The `(type)` cast operator
- (double)total_points
- In the code above, (double)total_points converts the 15 into 15.0.
- Lesson 230 — The `(type)` cast operator
- (double)totalItems
- In the example above, (double)totalItems signals your intent.
- Lesson 135 — Readability and intent in casting
- (e.g
- Instead of using an integer index like i (e.g., str[i]), we can use a pointer to point directly to the current character.
- Lesson 481 — Iterating strings until `\0` with pointers
- (false)
- In the first example, because engine_running is 0 (false), !engine_running becomes 1 (true).
- Lesson 167 — Logical NOT `!`
- (false) and is "raised" to
- It typically starts at 0 (false) and is "raised" to 1 (true) when a specific condition is met.
- Lesson 315 — The Flag Variable pattern
- (float)
- Place (float) before an integer variable during division to prevent C from discarding the decimal remainder.
- Lesson 130 — Forcing floating-point division
- (float)sum
- By using (float)sum, we tell C to treat the math as a decimal calculation so we don't lose accuracy.
- Lesson 403 — Calculating the sum and average
- (float)total_points
- In the example above, (float)total_points tells C to treat that 15 as 15.0 just for this specific calculation.
- Lesson 129 — The cast operator `(type)`Lesson 130 — Forcing floating-point division
- (float)totalPoints
- In the second example, (float)totalPoints temporarily turns the 5 into 5.0.
- Lesson 234 — Safety with explicit casts
- (for
- Inside this frame, it stores the value 5 (for n) and space for the result.
- Lesson 347 — What is a Stack Frame?
- (gdb)
- Once you have started GDB in your terminal (usually by typing gdb ./my_program), you will see a prompt that looks like (gdb).
- Lesson 826 — Starting GDB with an executableLesson 827 — The `run` and `quit` commands
- (greater than) and
- Toward the bottom are comparison operators like > (greater than) and == (equal to), and at the very bottom is the assignment operator =.
- Lesson 212 — Operator precedence table
- (greater than) or
- When you use a relational operator—like > (greater than) or == (equal to)—the computer performs the math and then spits out a 1 if the statement is a fact, or a 0 if it is a lie.
- Lesson 164 — Boolean result of comparisons
- (hash << 5) + hash
- By adding the original hash to it ((hash << 5) + hash), we effectively multiply by 33.
- Lesson 1038 — String hashing with DJB2
- (i - 1) / 2
- Their own boss (parent) is at index (i - 1) / 2.
- Lesson 1058 — Heap Sort: Binary heap concept
- (index + 1) % SIZE
- By using (index + 1) % SIZE, we create a circular loop.
- Lesson 1019 — Modulo operator for circular wrap
- (int *)
- To "cast away" constness, you tell the compiler: "I know this was marked as constant, but treat it as a regular, modifiable variable for just a moment." We do this by placing the desired pointer type in parentheses, like (int *).
- Lesson 499 — Casting away `const` volatilityLesson 507 — The `void *` generic typeLesson 509 — Casting `void *` to specific types
- (int)5.5
- You aren't converting the number (like casting (int)5.5 to get 5); you are peering at the raw binary 1s and 0s that make up that float.
- Lesson 657 — Using unions for type punning
- (int)myChar
- While C sometimes performs this conversion automatically (implicit casting), writing (int)myChar tells the world that you are intentionally looking for the numeric "under-the-hood" value.
- Lesson 131 — Casting between char and int
- (int)myFloat
- You are telling the compiler, "I know what I'm doing; change this data type right now." You perform a cast by placing the desired type in parentheses directly before the value, like (int)myFloat.
- Lesson 133 — Truncation during float-to-int castsLesson 135 — Readability and intent in castingLesson 234 — Safety with explicit casts
- (int*)
- In C++, this "cast" (the (int*) part) is mandatory because C++ is much stricter about types.
- Lesson 540 — Casting malloc return in C vs C++
- (multiplication) and
- In C, math operators like * (multiplication) and / (division) are "First Class." They have higher precedence than + and -.
- Lesson 212 — Operator precedence table
- (n - 1)
- In the line return n + sum(n - 1);, the (n - 1) is the magic ingredient.
- Lesson 355 — The Recursive Step
- (Not a Number) or
- If you try to pass 0 or -1.0 into log(), your program will return a special value called NaN (Not a Number) or -HUGE_VAL, representing negative infinity.
- Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- (or
- In C, the letter e (or E) stands for "times ten to the power of." It acts like a shortcut for moving the decimal point.
- Lesson 100 — Scientific notation in CLesson 827 — The `run` and `quit` commands
- (or any non-zero number) represents
- 1 (or any non-zero number) represents True.
- Lesson 164 — Boolean result of comparisons
- (PI / 180.0)
- C's trigonometric functions require angles in radians, so always multiply degrees by (PI / 180.0) before passing them to sin(), cos(), or tan().
- Lesson 863 — Trigonometric functions in radians
- (rand() % range) + min_value
- To get a random number within a specific range, use (rand() % range) + min_value.
- Lesson 887 — Scaling `rand` results to a specific range
- (total / count)
- It never attempts to calculate (total / count).
- Lesson 253 — Short-circuit evaluation in logical AND
- (True) if they match and
- It looks at the left side and the right side and asks, "Are these currently balanced?" It returns 1 (True) if they match and 0 (False) if they don't.
- Lesson 165 — Common pitfall: `=` vs `==`
- (True) or
- In C, these operators compare two values and return a result of either 1 (True) or 0 (False).
- Lesson 160 — Greater or equal `>=` and less or equal `<=`
- (type *)
- To cast a pointer, you put the desired pointer type in parentheses—(type *)—immediately before the pointer variable.
- Lesson 134 — Casting pointers (Introductory look)
- (type)
- Use (type) to manually convert data, especially to prevent integer division or to acknowledge that you are intentionally narrowing a large value into a smaller type.
- Lesson 129 — The cast operator `(type)`Lesson 230 — The `(type)` cast operatorLesson 234 — Safety with explicit casts
- (unsigned char)
- Always cast your argument to (unsigned char) when calling <ctype.h> functions to avoid undefined behavior caused by negative signed values.
- Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- (void*)
- Note: The (void) in the code above is a small technical requirement to tell printf to treat the address as a generic location.*
- Lesson 450 — Printing addresses with `%p`
- (which C interprets as
- If the two sides are equal, the expression evaluates to 1 (which C interprets as True).
- Lesson 161 — The equality operator `==`
- (which is what
- When you use the * operator, you are telling the CPU: "Go to this specific coordinate in memory." If that coordinate is 0 (which is what NULL usually represents), the CPU hits a hardware wall.
- Lesson 525 — Dereferencing the NULL pointer
- (x + 1) = 5
- For example, if you try to write (x + 1) = 5;, the computer complains because x + 1 is just a temporary result (a letter), not a permanent mailbox where the 5 can live.
- Lesson 191 — L-values vs R-values
- (x > y) + z
- Using parentheses—(x > y) + z—tells the compiler (and other humans) exactly what you intended.
- Lesson 219 — Common precedence errors
- (x)
- Think of these parentheses as "safety bubbles." By wrapping (x), you ensure that no matter what complex math the user plugs in—whether it’s a + b or 10 - 2—it stays grouped together as a single unit during the substitution process.
- Lesson 773 — Why parenthesize macro argumentsLesson 974 — The syntax of a generic selectionLesson 977 — Type-based function overloading simulationLesson 979 — Mathematical macros using `_Generic`
- * const
- A constant pointer (* const) is a fixed arrow: it can change the data it points to, but it can never be reassigned to point to a different memory location.
- Lesson 494 — Constant pointer to a value (`int * const p`)
- *(a + i)
- In C, a[i] and *(a + i) are functionally identical; the brackets are just "syntactic sugar" to make pointer arithmetic easier to read.
- Lesson 473 — The equivalence of `a[i]` and `*(a + i)`
- *(numbers + 0)
- numbers[0] is the same as *(numbers + 0)
- Lesson 472 — Accessing arrays with pointer notation
- *(numbers + 1)
- numbers[1] is the same as *(numbers + 1)
- Lesson 472 — Accessing arrays with pointer notation
- *(numbers + 2)
- numbers[2] is the same as *(numbers + 2)
- Lesson 472 — Accessing arrays with pointer notation
- *(prices + 1)
- You might wonder why we would use *(prices + 1) when prices[1] is easier to read.
- Lesson 472 — Accessing arrays with pointer notation
- *box
- If you change where *box points, you are effectively swapping the map inside the box.
- Lesson 502 — Visualizing pointer chains
- *endPtr
- If *endPtr is not a null terminator (\0) or a newline, you know there’s "garbage" left over in the string, allowing you to reject the input instead of proceeding with a broken value.
- Lesson 872 — Robust string-to-number conversion with `strtol`
- *f
- The compiler "remembered" that *f was 1.0 and decided it didn't need to look at the memory again after the integer assignment.
- Lesson 936 — Strict aliasing rule violations
- *numbers
- Writing *numbers is exactly the same as writing numbers[0].
- Lesson 472 — Accessing arrays with pointer notation
- *p
- int p creates a pointer variable that stores an address, while p follows that address to access or modify the actual value.
- Lesson 456 — The difference between `int *p` and `*p`
- *paper
- If you only used one asterisk (*paper), you would be looking at the memory address of the box, not the gold itself.
- Lesson 505 — Accessing data through double dereference
- *pointer_name = new_value
- When you want to assign a new value to a variable through a pointer, you follow a specific syntax: *pointer_name = new_value;.
- Lesson 458 — Assigning values via pointers
- *ptr
- To let a function modify a variable from the caller, pass the variable's address (&var) and use the dereference operator (*ptr) inside the function to update it.
- Lesson 457 — The Dereference operator `*`Lesson 462 — Checking for NULL before dereferencingLesson 481 — Iterating strings until `\0` with pointersLesson 488 — Modifying caller variablesLesson 502 — Visualizing pointer chainsLesson 558 — Returning addresses of local variables
- *ptr = 100
- If you compile this with debugging symbols (-g) and it crashes, loading the core dump in GDB will point directly to the line *ptr = 100;.
- Lesson 837 — Debugging a Segfault from a core dump
- *ptr = 20
- In the example above, *ptr = 20 doesn't change the address stored in ptr.
- Lesson 457 — The Dereference operator `*`
- *ptr = 25
- In the example above, *ptr = 25 doesn't change the address stored in the pointer; it reaches through the pointer and changes the cookies variable to 25.
- Lesson 238 — The Indirection operator `*`
- *ptr = value
- Before you use a pointer to write data (*ptr = value), ensure the address it currently holds is still within the original array's starting and ending memory addresses.
- Lesson 524 — Buffer overflows via pointers
- *ptr.member
- You might wonder why we don't just use *ptr.member.
- Lesson 619 — Modifying struct members via pointers
- *ptrToPtr
- The Modification: Inside the function, ptrToPtr means "go to the box located at this address." The assignment ptrToPtr = secretMessage puts a new address inside that box.
- Lesson 500 — Concept of double indirectionLesson 503 — Modifying a pointer inside a function
- *ptrToPtr = secretMessage
- The Modification: Inside the function, ptrToPtr means "go to the box located at this address." The assignment ptrToPtr = secretMessage puts a new address inside that box.
- Lesson 503 — Modifying a pointer inside a function
- *result
- If you try to do *result, the compiler will complain because it doesn't know how many bytes to read.
- Lesson 881 — Handling the `void*` return of `bsearch`
- *src
- Dereferencing: *src looks at the actual character at the current memory address.
- Lesson 482 — Pointer-based `strcpy` implementation
- / fall-through /
- If you intentionally leave it out to group cases, it is a good habit to add a comment like / fall-through / so other programmers know it wasn't a mistake.
- Lesson 261 — Fall-through behavior: intentional and accidental
- / MYGAME_ENTITIES_PLAYER_STATS_H /
- Comment the End: Notice the comment / MYGAME_ENTITIES_PLAYER_STATS_H / after the #endif.
- Lesson 1203 — Header guard best practices
- // This prints Hello
- Writing // This prints Hello next to a print command is like putting a label on a toaster that says "Toaster." It’s redundant.
- Lesson 33 — Single-line comments `//`
- /include
- As your C programs grow from a single file into a collection of multiple .c and .h files, your project folder can quickly become a cluttered "junk drawer." To stay organized, professional C developers use a standardized folder structure: they put logic in a /src folder and definitions in an /include folder.
- Lesson 800 — Organizing /src and /include folders
- /libs
- Imagine you have a project where your library is stored in a folder named /libs and the file is named libphysics.so.
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- /src
- As your C programs grow from a single file into a collection of multiple .c and .h files, your project folder can quickly become a cluttered "junk drawer." To stay organized, professional C developers use a standardized folder structure: they put logic in a /src folder and definitions in an /include folder.
- Lesson 800 — Organizing /src and /include folders
- /src (source)
- The /src (source) folder is the stove area.
- Lesson 800 — Organizing /src and /include folders
- /tmp/fileA3bZ
- When you call tmpnam(filename), the function fills your character array with a string like /tmp/fileA3bZ.
- Lesson 759 — Generating temp filenames with tmpnam
- /tmp/my_data.txt
- If your program always creates a temporary file named /tmp/my_data.txt, a malicious user can create a "symbolic link" with that exact name before your program runs.
- Lesson 763 — Temporary file security risks
- /tmp/my_messenger
- Once you run this code, you will see a new file at /tmp/my_messenger.
- Lesson 1107 — Creating FIFOs with mkfifo()
- /usr/include
- The compiler looks exclusively in "System Folders"—pre-defined directories on your hard drive where C libraries are installed (like /usr/include on Linux).
- Lesson 795 — Standard header search paths
- /usr/lib
- If the spice is in a standard cupboard like /usr/lib, the chef finds it instantly.
- Lesson 815 — Linking with shared libraries `-l` and `-L`Lesson 816 — Runtime library loading and `LD_LIBRARY_PATH`
- \n
- Progress Bars or Prompts: If you print a message like "Loading..." without a \n because you want the percentage to appear on the same line, the user might see nothing but a blank screen for seconds because the text is stuck in the buffer.
- Lesson 44 — Newline character `\n`Lesson 45 — Horizontal tab `\t`Lesson 47 — Escaping the backslashLesson 108 — Escape sequences like `\n` and `\t`Lesson 300 — Using nested loops to print 2D gridsLesson 301 — Nested loops for multiplication tablesLesson 412 — Printing a 2D matrix to the consoleLesson 434 — Removing newlines from `fgets` resultsLesson 691 — The return value of printfLesson 694 — Reading characters with ' %c' spacingLesson 697 — How scanf leaves trailing newlinesLesson 698 — Using scansets with %[...]Lesson 700 — Printing strings with putsLesson 701 — Reading safe strings with fgetsLesson 702 — Removing the newline from fgetsLesson 717 — String I/is with fgets and fputsLesson 724 — Text mode vs Binary mode (b flag)Lesson 739 — Risks of seeking in text modeLesson 748 — How C buffers I/O for speedLesson 749 — Full buffering vs Line bufferingLesson 751 — Forcing a write with fflushLesson 752 — Setting custom buffers with setvbufLesson 755 — When to use fflush(stdout)Lesson 842 — Identifying whitespace with `isspace`Lesson 946 — Handling line endings across OSsLesson 1153 — Using `fgets()` instead of `scanf()` for stringsLesson 1158 — Flushing `stdout` for accurate logsLesson 1206 — Opening and reading files line-by-line
- \n\n
- You can even use multiple \n\n in a row to create a blank line between your text, just like hitting the Enter key twice in a word processor.
- Lesson 44 — Newline character `\n`
- \r
- In C, "whitespace" isn't just the spacebar key; it is a category that includes horizontal tabs (\t), newlines (\n), carriage returns (\r), and vertical tabs.
- Lesson 842 — Identifying whitespace with `isspace`Lesson 946 — Handling line endings across OSs
- \r\n
- When writing: Even if you just write \n, the C library will automatically convert it to \r\n if it detects it is running on a Windows system.
- Lesson 739 — Risks of seeking in text modeLesson 946 — Handling line endings across OSs
- \t
- Instead of just printing a single space, \t tells the computer to jump the cursor forward to the next "tab stop." Think of it like a train that doesn't stop at every single house along the track, but only at specific stations spaced at equal intervals.
- Lesson 45 — Horizontal tab `\t`Lesson 108 — Escape sequences like `\n` and `\t`Lesson 820 — The importance of Tab charactersLesson 842 — Identifying whitespace with `isspace`
- \t- Milk\n
- In the example above, \t- Milk\n tells the computer: "Indent, print a dash and the word Milk, then jump to a new line." Without these sequences, all your output would be crammed together in one long, unreadable string.
- Lesson 108 — Escape sequences like `\n` and `\t`
- \W
- If you type printf("C:\Windows");, C will see the \W and wonder what secret command you are trying to trigger.
- Lesson 47 — Escaping the backslash
- &arrayName[i]
- To fill an array, use a for loop where the counter matches the array index, passing &arrayName[i] to scanf to store each input.
- Lesson 390 — Reading array values from user input
- &i
- If you pass the address of a loop counter (&i) and the loop continues to increment, the thread might read the "new" value of i before it even starts.
- Lesson 924 — The `register` keyword and its modern relevanceLesson 1118 — Passing arguments to threads
- &numbers
- When using the address-of operator: &numbers provides a pointer to the entire array, not just the first element.
- Lesson 475 — Array decay explained
- &p
- Just as you pass a variable's address (&x) to a function if you want to change its value, you must pass a pointer's address (&p) if you want to change which memory location that pointer is looking at.
- Lesson 501 — Declaring `int **pp`
- &ptr
- To change where a pointer points from inside a function, you must pass the address of that pointer (&ptr) and receive it as a double pointer (ptr).
- Lesson 503 — Modifying a pointer inside a function
- &sayHello
- Whether you use sayHello or the explicit "address of" operator &sayHello, C treats them as the same thing: a pointer to the code.
- Lesson 515 — Taking the address of a function
- &scores[i]
- Think of scores[i] as the box itself, while &scores[i] is the GPS coordinate of that box.
- Lesson 390 — Reading array values from user input
- &var
- To let a function modify a variable from the caller, pass the variable's address (&var) and use the dereference operator (*ptr) inside the function to update it.
- Lesson 488 — Modifying caller variables
- &variable
- By passing addresses (&variable) to a function, you allow that function to modify multiple variables in the caller's memory, effectively "returning" as many values as you need.
- Lesson 487 — Passing addresses to functionsLesson 489 — Returning multiple values via pointers
- &x
- Just as you pass a variable's address (&x) to a function if you want to change its value, you must pass a pointer's address (&p) if you want to change which memory location that pointer is looking at.
- Lesson 501 — Declaring `int **pp`
- #0000FF
- You could describe a deep blue as "red: 0, green: 0, blue: 255," but programmers often prefer the shorthand #0000FF.
- Lesson 689 — Printing hex and octal values
- #define
- Maintainability: If the tax rate changes to 0.085, you only have to change it in one place (the #define line) instead of hunting through thousands of lines of code to find every instance of that specific number.
- Lesson 115 — Defining constants with `#define`Lesson 116 — Macros vs. Const variablesLesson 370 — Macros vs. Inline functionsLesson 380 — Header Guards: `#ifndef` and `#define`Lesson 613 — Typedef vs. #define macrosLesson 768 — Defining constants with `#define`Lesson 769 — Removing definitions with `#undef`Lesson 770 — The danger of semicolon in `#define`Lesson 771 — Avoiding magic numbers with macrosLesson 772 — Defining function-like macrosLesson 776 — The stringizing operator `#`Lesson 779 — Multi-line macros with backslashesLesson 780 — Using `#ifdef` and `#ifndef`Lesson 786 — Feature toggles via command line `-D`Lesson 787 — Managing debug prints with macrosLesson 977 — Type-based function overloading simulation
- #define DEBUG
- By typing -DDEBUG in your terminal, you are telling the compiler, "For this specific build, act as if #define DEBUG is written at the top of every file."
- Lesson 786 — Feature toggles via command line `-D`
- #define GREETING
- Notice that #define GREETING is gone, and the word GREETING has been physically replaced by its value.
- Lesson 767 — How `gcc -E` shows preprocessor output
- #define NAME VALUE
- Use #define NAME VALUE at the top of your code to create easy-to-read, unchangeable labels for fixed numbers or text.
- Lesson 115 — Defining constants with `#define`
- #define NDEBUG
- In real-world projects, programmers rarely type #define NDEBUG directly into their C files.
- Lesson 902 — Disabling assertions with `NDEBUG`
- #define PI 3.14
- This works fine for simple shortcuts like #define PI 3.14, but what happens when you want a macro that performs a complex calculation or checks multiple conditions?
- Lesson 772 — Defining function-like macrosLesson 779 — Multi-line macros with backslashes
- #define SQUARE(x) (x * x)
- If you define #define SQUARE(x) (x * x), the preprocessor literally rewrites your code before the compiler even sees it.
- Lesson 778 — Macros vs inline functions
- #define SQUARE(x) x * x
- Because macros are just text substitution, they can be "tricky." If you defined it as #define SQUARE(x) x x and then wrote SQUARE(2 + 2), the preprocessor would give you 2 + 2 2 + 2.
- Lesson 772 — Defining function-like macros
- #define STRING char*
- If you write #define STRING char*, and then try to declare two strings on one line like this:
- Lesson 613 — Typedef vs. #define macros
- #elif
- The defined() operator is a more powerful tool that lives inside an #if or #elif statement.
- Lesson 782 — The `defined()` operator
- #else
- Conditional compilation uses #if and #else to physically include or exclude code from your program before the actual compilation begins.
- Lesson 781 — Basic logic with `#if` and `#else`
- #endif
- If that expression evaluates to zero (false), the preprocessor simply deletes everything between the #if and the closing #endif before the compiler even sees it.
- Lesson 380 — Header Guards: `#ifndef` and `#define`Lesson 780 — Using `#ifdef` and `#ifndef`Lesson 781 — Basic logic with `#if` and `#else`Lesson 783 — Testing for platform-specific codeLesson 785 — Temporary code disabling with `#if 0`Lesson 787 — Managing debug prints with macrosLesson 790 — Creating basic include guardsLesson 1203 — Header guard best practices
- #error
- It tells the preprocessor: "If you reach this line, stop everything, display a specific message, and fail the build." Unlike a standard printf which happens while your program is running, #error happens while your program is being created.
- Lesson 784 — Using `#error` to stop compilation
- #FF5733
- You will rarely use Octal in modern programming, but you will use Hex and Binary constantly when working with colors (like #FF5733), memory addresses, or hardware pins.
- Lesson 119 — Integer literals (Hex, Octal, Binary)
- #if
- Size: If you have a massive chunk of code meant only for testing, using #if ensures that code isn't shipped to your customers, making your final file smaller and more secure.
- Lesson 781 — Basic logic with `#if` and `#else`Lesson 782 — The `defined()` operatorLesson 784 — Using `#error` to stop compilationLesson 785 — Temporary code disabling with `#if 0`
- #if 0
- Use #if 0 and #endif to safely disable blocks of code that contain nested comments or complex logic.
- Lesson 785 — Temporary code disabling with `#if 0`
- #if defined
- Inline assembly is platform-locked; always use preprocessor guards (#if defined) to provide specific implementations for different CPU architectures.
- Lesson 963 — Platform-specific assembly (x86 vs ARM)
- #ifdef
- Use #ifdef and platform macros to ensure your code runs smoothly across different operating systems without writing multiple versions of the same program.
- Lesson 780 — Using `#ifdef` and `#ifndef`Lesson 782 — The `defined()` operatorLesson 783 — Testing for platform-specific codeLesson 786 — Feature toggles via command line `-D`Lesson 787 — Managing debug prints with macros
- #ifdef NAME
- Include the following code only if NAME has been defined.
- Lesson 780 — Using `#ifdef` and `#ifndef`
- #ifndef
- If the compiler encounters this file again in the same run, the #ifndef check fails (because the name now exists), and the compiler skips straight to the #endif, preventing any duplicate definitions.
- Lesson 380 — Header Guards: `#ifndef` and `#define`Lesson 780 — Using `#ifdef` and `#ifndef`Lesson 784 — Using `#error` to stop compilationLesson 791 — How `#pragma once` worksLesson 925 — Common linkage errors and 'multiple definition'
- #ifndef HEADER_H
- In professional code, a simple #ifndef HEADER_H isn't enough.
- Lesson 1203 — Header guard best practices
- #ifndef NAME
- Include the following code only if NAME has not been defined.
- Lesson 780 — Using `#ifdef` and `#ifndef`
- #ifndef PLAYER_H
- If the compiler encounters player.h again later in the same build process, it hits the #ifndef PLAYER_H line.
- Lesson 790 — Creating basic include guards
- #include
- The #include directive imports external files containing pre-written code, allowing you to use standard tools like printf without writing them from scratch.
- Lesson 17 — The 'Hello World' codeLesson 18 — The `#include` directiveLesson 330 — Function prototype syntaxLesson 377 — Role of the `.h` fileLesson 380 — Header Guards: `#ifndef` and `#define`Lesson 382 — Sharing functions across modulesLesson 678 — The header file <stdio.h>Lesson 765 — The `#include` directive for standard headersLesson 766 — The `#include` directive for local filesLesson 788 — The purpose of header filesLesson 791 — How `#pragma once` worksLesson 792 — Forward declarations in headersLesson 793 — What should NOT go in a headerLesson 794 — Circular dependency issuesLesson 799 — The role of the 'main' fileLesson 800 — Organizing /src and /include foldersLesson 802 — Dependency graphing in your headLesson 925 — Common linkage errors and 'multiple definition'
- #include "enemy.h"
- You only need to perform the actual #include "enemy.h" inside your .c source file, where you finally need to access the enemy's specific fields (like target->health).
- Lesson 792 — Forward declarations in headers
- #include "file_a.h"
- In C, a circular dependency happens when file_a.h contains #include "file_b.h", but file_b.h also contains #include "file_a.h".
- Lesson 794 — Circular dependency issues
- #include "file_b.h"
- In C, a circular dependency happens when file_a.h contains #include "file_b.h", but file_b.h also contains #include "file_a.h".
- Lesson 794 — Circular dependency issues
- #include "filename.h"
- Use #include "filename.h" for files you created in your project folder, and #include <filename.h> for standard built-in libraries.
- Lesson 379 — Using `#include` with quotesLesson 766 — The `#include` directive for local files
- #include "math_utils.h"
- To use this in your main program, you simply #include "math_utils.h".
- Lesson 378 — Separating interface from implementation
- #include "my_functions.h"
- To tell the compiler to look in your current folder first, you swap the angle brackets for double quotes: #include "my_functions.h".
- Lesson 379 — Using `#include` with quotes
- #include "my_header.h"
- This is like putting a .h file in the same folder as your .c file; you simply write #include "my_header.h" and the compiler finds it.
- Lesson 63 — Header search paths
- #include "my_settings.h"
- When it sees #include "my_settings.h", it pauses, opens your file named my_settings.h, copies everything inside it, and pastes it directly into your main file at that exact spot before the compiler even starts reading the code.
- Lesson 63 — Header search pathsLesson 766 — The `#include` directive for local files
- #include "player.h"
- When you use #include "player.h", the preprocessor literally copies and pastes the entire content of that file into your code.
- Lesson 789 — The 'duplicate definition' error
- #include "tools.h"
- When you include a header with #include "tools.h", you are telling the compiler: "I'm going to use a function defined elsewhere; trust me, it exists."
- Lesson 382 — Sharing functions across modules
- #include <ctype.h>
- Use isupper(c) to check for capital letters and islower(c) to check for small letters, ensuring you #include <ctype.h> first.
- Lesson 840 — Testing for alphabetic characters with `isalpha`Lesson 842 — Identifying whitespace with `isspace`Lesson 844 — Case testing with `isupper` and `islower`
- #include <filename.h>
- Use #include "filename.h" for files you created in your project folder, and #include <filename.h> for standard built-in libraries.
- Lesson 379 — Using `#include` with quotes
- #include <header.h>
- The #include <header.h> directive tells the preprocessor to copy-paste standard library definitions into your file so you can use built-in functions.
- Lesson 765 — The `#include` directive for standard headers
- #include <stdbool.h>
- You no longer need to remember #include <stdbool.h> at the top of every file just to perform simple logic.
- Lesson 969 — C23: The `bool`, `true`, and `false` keywords
- #include <stdio.h>
- When you write #include <stdio.h>, you are telling the Preprocessor: "Find the file named stdio.h on my computer, copy every single line of text inside it, and paste it right here."
- Lesson 17 — The 'Hello World' codeLesson 18 — The `#include` directiveLesson 25 — Phase 1: The PreprocessorLesson 41 — The `stdio.h` libraryLesson 63 — Header search pathsLesson 764 — What the preprocessor actually doesLesson 766 — The `#include` directive for local filesLesson 795 — Standard header search paths
- #include <stdlib.h>
- Always include #include <stdlib.h> at the top of your program to unlock the functions required for dynamic memory allocation and deallocation.
- Lesson 536 — Header file stdlib.h for allocation
- #pragma once
- Even if ten different files in your project include player.h, the #pragma once directive ensures the struct Player definition is only processed once.
- Lesson 791 — How `#pragma once` works
- #pragma pack
- Using #pragma pack is like vacuum-sealing your clothes: you remove all the air to make everything fit in a specific, tight order.
- Lesson 948 — The `#pragma pack` directive
- #pragma pack(1)
- Use #pragma pack(1) to remove invisible padding bytes when your struct must match a specific external data format or hardware register.
- Lesson 948 — The `#pragma pack` directive
- #undef
- If you only need a macro for a tiny section of code and want to prevent it from accidentally messing up other parts of your program, you "wrap" your code with a #define at the top and an #undef at the bottom.
- Lesson 769 — Removing definitions with `#undef`
- #x
- If you pass PRINT_INT(10 + 5), the #x will literally become the string "10 + 5".
- Lesson 776 — The stringizing operator `#`
- %-10s
- In the second block, the %-10s flag ensures "Apples" starts immediately after the pipe character, making the list much easier to read—just like a professionally printed receipt or a table in a book.
- Lesson 686 — Left-aligning with the minus flag
- %.0f
- %.0f means "show no decimal places" (rounding to the nearest whole number).
- Lesson 102 — Formatting decimals with `%.nf`Lesson 687 — Precision for floating-point numbers
- %.2f
- If you print 3.148 using %.2f, the screen will show 3.15, but the variable inside the computer's memory still holds the precise 3.148 for future calculations.
- Lesson 102 — Formatting decimals with `%.nf`Lesson 687 — Precision for floating-point numbers
- %.4f
- If you use %.4f, it sees the 9 and rounds the previous digit up, giving you 3.1416.
- Lesson 687 — Precision for floating-point numbers
- %.nf
- Use %.Nf (where N is a number) to round and limit floating-point output to a specific number of decimal places.
- Lesson 102 — Formatting decimals with `%.nf`Lesson 687 — Precision for floating-point numbers
- %[a-z]
- You can also use ranges, like %[a-z] to only accept lowercase letters, or %[0-9] for digits.
- Lesson 698 — Using scansets with %[...]
- %[abcd]
- For example, %[abcd] will only accept the letters a, b, c, or d.
- Lesson 698 — Using scansets with %[...]
- %#x
- Using %#x would turn ff into 0xff, which is the standard way programmers write hexadecimal in their code.
- Lesson 689 — Printing hex and octal values
- %02d
- It will never cut off your data; if you try to print 100 with %02d, C will still print all three digits because the data itself is always prioritized over the padding.
- Lesson 688 — Zero-padding numerical output
- %03d
- For example, %03d means "format this integer to be 3 digits wide, padding with zeros if necessary."
- Lesson 688 — Zero-padding numerical output
- %04d
- If you change a %d to a %04d, fprintf will even add leading zeros for you, making your file output look professional and consistent.
- Lesson 718 — Formatted file output with fprintf
- %0nd
- Use %0nd (where n is the width) to add leading zeros and keep your numerical output perfectly aligned.
- Lesson 688 — Zero-padding numerical output
- %10d
- By default, when you tell printf to reserve a specific amount of space for a value (like %10d), it acts like a shy person in an elevator.
- Lesson 686 — Left-aligning with the minus flag
- %19s
- While you can limit this by using %19s (telling it to stop after 19 characters to leave room for the null terminator), standard scanf is generally considered unsafe for professional applications where users might enter unpredictable text.
- Lesson 422 — Scanning strings with `%s` and `scanf` limitations
- %5d
- If the number you are printing is smaller than the width (like the number 42 in a %5d spot), C will pad the left side with empty spaces.
- Lesson 56 — Basic field width formattingLesson 685 — Specifying field width for alignment
- %9s
- Always use a width limit (like %9s) with scanf to ensure the input never exceeds the size of your character array.
- Lesson 438 — Handling the `scanf` buffer overflowLesson 695 — Limiting string length in scanf
- %c
- While functions like scanf("%d") are smart enough to skip over whitespace to find a number, the character formatter—%c—is different.
- Lesson 49 — Introduction to Format SpecifiersLesson 51 — Printing characters with `%c`Lesson 53 — The `%s` specifier for stringsLesson 55 — Argument-specifier matchingLesson 109 — The ASCII encoding schemeLesson 112 — Printing chars with `%c`Lesson 684 — Format specifiers recapLesson 694 — Reading characters with ' %c' spacing
- %d
- Printing just %d is confusing if you have five different variables; printing count: %d tells you exactly what you are looking at.
- Lesson 48 — The percent sign `%%` literalLesson 49 — Introduction to Format SpecifiersLesson 50 — Printing integers with `%d`Lesson 51 — Printing characters with `%c`Lesson 52 — Printing decimals with `%f`Lesson 53 — The `%s` specifier for stringsLesson 54 — Multiple specifiers in one lineLesson 55 — Argument-specifier matchingLesson 87 — Printing integers with `%d` and `%ld`Lesson 90 — The `unsigned` keywordLesson 94 — Format specifiers for unsigned intsLesson 96 — The `<limits.h>` header fileLesson 109 — The ASCII encoding schemeLesson 112 — Printing chars with `%c`Lesson 164 — Boolean result of comparisonsLesson 376 — How `printf` works internallyLesson 412 — Printing a 2D matrix to the consoleLesson 421 — Printing strings with `%s` and `printf`Lesson 422 — Scanning strings with `%s` and `scanf` limitationsLesson 450 — Printing addresses with `%p`Lesson 679 — Basic character output with putcharLesson 684 — Format specifiers recapLesson 688 — Zero-padding numerical outputLesson 689 — Printing hex and octal valuesLesson 690 — Escaping the percent sign %%Lesson 693 — Scanning integers and floatsLesson 700 — Printing strings with putsLesson 718 — Formatted file output with fprintfLesson 719 — Formatted file input with fscanfLesson 894 — Formatting time strings with `strftime`Lesson 975 — Implementing a generic 'Print' macroLesson 1163 — Inspecting variable values at runtime
- %e
- In the code above, %f prints the number in standard decimal format, while %e tells C to print the output back in scientific notation.
- Lesson 100 — Scientific notation in C
- %f
- If the user types letters instead of numbers, scanf will fail to read the data correctly, but for now, focus on the matching: %d for int and %f for float.
- Lesson 48 — The percent sign `%%` literalLesson 49 — Introduction to Format SpecifiersLesson 52 — Printing decimals with `%f`Lesson 55 — Argument-specifier matchingLesson 97 — Single precision `float`Lesson 98 — Double precision `double`Lesson 100 — Scientific notation in CLesson 102 — Formatting decimals with `%.nf`Lesson 684 — Format specifiers recapLesson 687 — Precision for floating-point numbersLesson 690 — Escaping the percent sign %%Lesson 693 — Scanning integers and floatsLesson 700 — Printing strings with putsLesson 718 — Formatted file output with fprintfLesson 719 — Formatted file input with fscanf
- %hd
- Notice that we use different "format specifiers" like %hd and %ld to tell the printf function which size we are using.
- Lesson 82 — Short vs. Long integers
- %ld
- Notice that we use different "format specifiers" like %hd and %ld to tell the printf function which size we are using.
- Lesson 82 — Short vs. Long integersLesson 87 — Printing integers with `%d` and `%ld`Lesson 735 — Getting current position with ftell
- %Lf
- Similarly, when printing the value using printf, you use the %Lf specifier (the capital 'L' is critical).
- Lesson 99 — The `long double` type
- %lld
- Use long long and the %lld specifier when your whole numbers exceed 2 billion.
- Lesson 83 — The `long long` type
- %o
- If you have the number 255, the %d filter shows you "255." The %x filter shows you "ff," and the %o filter shows you "377."
- Lesson 689 — Printing hex and octal values
- %p
- What you'll learn: How to use the address-of operator and the %p format specifier to see exactly where data lives in your computer's memory.
- Lesson 237 — The Address-of operator `&`Lesson 449 — The Address-of operator `&`Lesson 450 — Printing addresses with `%p`Lesson 451 — Hexadecimal notation for memoryLesson 515 — Taking the address of a function
- %s
- You provide a "format string" using placeholders like %s for words, %d for integers, and %f for decimals.
- Lesson 53 — The `%s` specifier for stringsLesson 421 — Printing strings with `%s` and `printf`Lesson 422 — Scanning strings with `%s` and `scanf` limitationsLesson 428 — Searching for substrings with `strstr`Lesson 679 — Basic character output with putcharLesson 684 — Format specifiers recapLesson 695 — Limiting string length in scanfLesson 698 — Using scansets with %[...]Lesson 719 — Formatted file input with fscanf
- %u
- To see these values, you simply include the header at the top of your file and print the constants using the %d (for signed) or %u (for unsigned) format specifiers.
- Lesson 90 — The `unsigned` keywordLesson 94 — Format specifiers for unsigned intsLesson 96 — The `<limits.h>` header file
- %x
- If you have the number 255, the %d filter shows you "255." The %x filter shows you "ff," and the %o filter shows you "377."
- Lesson 689 — Printing hex and octal values
- %zu
- You might notice the %zu formatter in the code above.
- Lesson 847 — Finding string length with `strlen`
- <angle brackets>
- We use quotes for files we created ourselves, while <angle brackets> are reserved for built-in system libraries like stdio.h.
- Lesson 382 — Sharing functions across modules
- <assert.h>
- Defining NDEBUG before including <assert.h> disables all assertions, allowing your final production code to run at maximum speed without safety checks.
- Lesson 901 — Using `assert` for internal debuggingLesson 902 — Disabling assertions with `NDEBUG`Lesson 1172 — Principles of Unit TestingLesson 1173 — Writing a simple `assert()` check
- <ctype.h>
- While you could check this by comparing ASCII values manually (like checking if a character is between 'A' and 'Z'), C provides a much safer and more readable way to do this via the <ctype.h> library.
- Lesson 443 — Counting vowels and consonantsLesson 840 — Testing for alphabetic characters with `isalpha`Lesson 841 — Checking for digits with `isdigit` and `isxdigit`Lesson 842 — Identifying whitespace with `isspace`Lesson 843 — Distinguishing `ispunct` and `isgraph`Lesson 844 — Case testing with `isupper` and `islower`Lesson 845 — Converting case with `toupper` and `tolower`Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- <errno.h>
- Most Standard Library functions use a simple return value (like -1 or NULL) to signal that something went wrong, while errno (a global variable found in <errno.h>) stores a specific code explaining what went wrong.
- Lesson 742 — The strerror functionLesson 745 — Handling 'Permission Denied' errorsLesson 897 — The global `errno` variableLesson 903 — When to use `errno` vs return codes
- <file>
- The difference between <file> and "file" tells the preprocessor where to look on your computer's "map":
- Lesson 766 — The `#include` directive for local files
- <float.h>
- The <float.h> header provides predefined constants that reveal the maximum values and decimal precision of your computer's floating-point hardware.
- Lesson 103 — The `<float.h>` header fileLesson 907 — Precision and epsilon in `float.h`Lesson 908 — Checking `FLT_DIG` and `DBL_DIG` for precision limits
- <limits.h>
- To help us handle these limits, C provides the <limits.h> header, which contains two vital constants: INT_MAX (the largest possible integer) and INT_MIN (the smallest possible negative integer).
- Lesson 88 — Minimum and maximum valuesLesson 96 — The `<limits.h>` header fileLesson 132 — Safe downcasting techniquesLesson 904 — Integer ranges in `limits.h`Lesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checksLesson 906 — Platform-specific character sizesLesson 909 — Managing large constants: `LONG_MAX` vs `LLONG_MAX`Lesson 942 — Limits of `limits.h` and `stdint.h`Lesson 1154 — Safe integer arithmetic and overflow checks
- <math.h>
- On some systems (like Linux), when you use <math.h>, you need to tell the compiler to link the math library manually by adding -lm to the end of your compile command, like this: gcc main.c -lm.
- Lesson 64 — Library linking basicsLesson 104 — Comparing floats for equalityLesson 765 — The `#include` directive for standard headersLesson 861 — Basic power and square root: `pow` and `sqrt`Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`Lesson 863 — Trigonometric functions in radiansLesson 864 — Rounding with `ceil`, `floor`, and `round`Lesson 865 — Truncation and remainder: `trunc` and `fmod`Lesson 866 — Absolute values for floats with `fabs`Lesson 867 — Handling `NAN` and `INFINITY` constants
- <my_file.h>
- If you try to include your own file with <my_file.h>, the compiler will skip your project folder entirely and search only the system libraries, failing to find your code.
- Lesson 795 — Standard header search paths
- <netinet/in.h>
- This structure is defined in the <netinet/in.h> header.
- Lesson 1109 — The sockaddr_in structure
- <signal.h>
- You tell the operating system to use your function instead of the default behavior by using the signal() function from the <signal.h> library.
- Lesson 1087 — Basic signal handling with signal()
- <stdalign.h>
- Note: While the keyword is _Alignof, including <stdalign.h> allows you to use the cleaner, lowercase alignof.
- Lesson 453 — Determining variable alignment in memoryLesson 572 — The alignof operator
- <stdarg.h>
- Use va_list, va_start, va_arg, and va_end from <stdarg.h> to process functions with a variable number of arguments indicated by the ... ellipsis.
- Lesson 371 — Functions with unknown argumentsLesson 372 — The `stdarg.h` libraryLesson 373 — Using `va_list` and `va_start`Lesson 376 — How `printf` works internally
- <stdatomic.h>
- Introduced in C11, the <stdatomic.h> library provides a way to make these operations atomic.
- Lesson 1141 — Introduction to <stdatomic.h>Lesson 1142 — Atomic types like atomic_intLesson 1143 — Atomic load and storeLesson 1144 — Atomic fetch and add
- <stdbool.h>
- If you wanted to make your code readable, you had to manually define constants or include <stdbool.h> (introduced in C99), which gave you bool as a macro for the slightly clunky _Bool type.
- Lesson 271 — Infinite loops: while(1) and while(true)Lesson 966 — C99: Variable declarations and `bool`Lesson 969 — C23: The `bool`, `true`, and `false` keywords
- <stddef.h>
- Instead, use the headers provided by the C standard, like <stdint.h> and <stddef.h>.
- Lesson 949 — Writing code for 32-bit vs 64-bit
- <stdint.h>
- If you absolutely need a variable that is exactly 32 bits regardless of the computer it runs on, advanced C programmers use specific headers like <stdint.h>, but understanding the fluid nature of the basic int is the first step toward writing software that works everywhere.
- Lesson 86 — Fixed-width types from `<stdint.h>`Lesson 942 — Limits of `limits.h` and `stdint.h`Lesson 944 — Sizes of `int` across different architecturesLesson 945 — The significance of `char` signnessLesson 949 — Writing code for 32-bit vs 64-bit
- <stdio.h>
- The <stdio.h> header file is a mandatory toolkit that provides the standard functions required for your program to perform input and output operations.
- Lesson 379 — Using `#include` with quotesLesson 678 — The header file <stdio.h>Lesson 681 — EOF (End Of File) explainedLesson 715 — The maximum number of open filesLesson 737 — Resetting with rewindLesson 756 — Renaming files with renameLesson 757 — Deleting files with removeLesson 758 — Creating temporary files with tmpfileLesson 759 — Generating temp filenames with tmpnam
- <stdlib.h>
- Writing a QuickSort algorithm from scratch is a great academic exercise, but in the real world, C provides a highly optimized version via the <stdlib.h> header called qsort.
- Lesson 313 — Exiting the program with exit()Lesson 540 — Casting malloc return in C vs C++Lesson 541 — The free function signatureLesson 871 — Converting strings to integers with `atoi` and `atol`Lesson 874 — Communicating with the OS using `system`Lesson 875 — Cleaning up at exit with `atexit`Lesson 883 — Generating pseudo-random numbers with `rand`Lesson 884 — The importance of the `RAND_MAX` constantLesson 1059 — Using C library 'qsort' functionLesson 1066 — Using C library 'bsearch' functionLesson 1071 — Environment variables in C
- <string.h>
- When searching for strings instead of integers, remember to use strcmp() from the <string.h> library rather than ==, but the logic of looping through the array remains identical.
- Lesson 420 — Length vs Size of a string arrayLesson 423 — Getting length with `strlen`Lesson 424 — Copying strings with `strcpy`Lesson 425 — Concatenating strings with `strcat`Lesson 426 — Comparing strings with `strcmp`Lesson 427 — Searching for characters with `strchr`Lesson 428 — Searching for substrings with `strstr`Lesson 429 — Tokenizing strings with `strtok`Lesson 430 — Setting memory blocks with `memset`Lesson 434 — Removing newlines from `fgets` resultsLesson 512 — The `memcpy` function signatureLesson 513 — Implementing a generic swap functionLesson 636 — Searching through struct arraysLesson 702 — Removing the newline from fgetsLesson 742 — The strerror functionLesson 847 — Finding string length with `strlen`Lesson 850 — Lexicographical comparison with `strcmp`Lesson 852 — Finding substrings with `strstr`Lesson 853 — Tokenizing strings with `strtok`Lesson 855 — Setting memory blocks with `memset`Lesson 856 — Copying memory with `memcpy`Lesson 899 — Getting error strings with `strerror`Lesson 1207 — Implementing string pattern matchingLesson 1208 — Adding command line flags (e.g., `-i` for case)Lesson 1215 — Writing the Search function
- <sys/socket.h>
- To create one, we use the socket() function from the <sys/socket.h> library:
- Lesson 1110 — Creating a socket with socket()
- <threads.h>
- C11 introduced <threads.h>, providing a standardized way to write concurrent code.
- Lesson 967 — C11: Multi-threading and Anonymous structures
- <time.h>
- In C, we use clock() from the <time.h> library to measure "CPU time." Think of this as a specialized stopwatch that only ticks when the processor is actually working on your specific instructions.
- Lesson 885 — Seeding the generator with `srand`Lesson 888 — Getting a unique seed with `time(NULL)`Lesson 889 — Getting system time with `time_t`Lesson 890 — Measuring intervals with `difftime`Lesson 891 — Breaking down time with `struct tm`Lesson 892 — Converting `time_t` to local time with `localtime`Lesson 896 — Measuring CPU ticks with `clock`Lesson 1180 — Measuring execution time with `clock()`
- <unistd.h>
- The access() function lives in the <unistd.h> library.
- Lesson 762 — Checking if a file existsLesson 1067 — What is a process ID (PID)
- 0 to (Size - 1)
- Because C won't stop you from crossing the boundary, you must build your own "fence." Before you ever access an array using a variable as an index, you must verify that the index is within the valid range: 0 to (Size - 1).
- Lesson 437 — Checking bounds before array access
- 0.7 or 0.75
- To keep operations lightning-fast, we set a threshold—usually a load factor of 0.7 or 0.75.
- Lesson 1037 — Load factor and rehashing
- 0b
- Use 0x for Hexadecimal, 0b for Binary, and a leading 0 for Octal to write numbers in the format that best fits your specific problem.
- Lesson 119 — Integer literals (Hex, Octal, Binary)
- 0b1010
- Using 0b1010 is much more intuitive for a "pattern" of switches than writing 10.
- Lesson 119 — Integer literals (Hex, Octal, Binary)
- 0x
- Hexadecimal (0x) is a shorthand that makes long binary memory addresses readable for humans while staying mathematically aligned with how hardware functions.
- Lesson 119 — Integer literals (Hex, Octal, Binary)Lesson 451 — Hexadecimal notation for memoryLesson 689 — Printing hex and octal values
- 0x0
- You’ll see it was 0x0, confirming why the crash happened.
- Lesson 837 — Debugging a Segfault from a core dump
- 0x00
- The three 0x00 bytes that follow are the rest of that 4-byte integer.
- Lesson 839 — Examining raw memory with `x`
- 0x00000001
- If the number is 0x00000001, where does that 1 go?
- Lesson 951 — Checking system endianness at runtime
- 0x0000FF00
- In this example, 0x0000FF00 is our "stained glass." It blocks out the Red, Blue, and Alpha values.
- Lesson 955 — Using masks for cross-platform bit logic
- 0x0001
- If a Little-Endian computer sends the integer 0x0001 to a Big-Endian computer without any changes, the receiver might interpret it as 0x0100.
- Lesson 952 — Network byte order and `htons`/`ntohs`
- 0x0100
- If a Little-Endian computer sends the integer 0x0001 to a Big-Endian computer without any changes, the receiver might interpret it as 0x0100.
- Lesson 952 — Network byte order and `htons`/`ntohs`
- 0x0A
- If the C library tries to "fix" line endings in a binary file, it will corrupt the data because the byte 0x0A might be part of a pixel color, not a new line.
- Lesson 946 — Handling line endings across OSs
- 0x0a 0x00 0x00 0x00
- You might see output like 0x0a 0x00 0x00 0x00.
- Lesson 839 — Examining raw memory with `x`
- 0x10
- In C, we prefix hexadecimal numbers with 0x to tell the compiler, "Hey, don't read this as a decimal!" For example, 0x10 isn't ten; it's sixteen.
- Lesson 451 — Hexadecimal notation for memory
- 0x1000
- If two libraries both demanded to live at memory address 0x1000, your system would crash.
- Lesson 814 — Position Independent Code `-fPIC`
- 0x12
- Big Endian: Stores the "most significant byte" (0x12) at the lowest memory address.
- Lesson 950 — Big Endian vs Little Endian explained
- 0x12345678
- If a Little Endian computer sends 0x12345678 to a Big Endian computer without converting it, the second computer will read the bytes in reverse and think the number is 0x78563412!
- Lesson 730 — Endianness and binary portabilityLesson 950 — Big Endian vs Little Endian explained
- 0x40021000
- Here is how we map a pointer to a specific hardware address (e.g., 0x40021000) and ensure the compiler treats it correctly.
- Lesson 913 — The `volatile` qualifier for hardware mapping
- 0x4005d1
- Without -g, if your program crashes, the computer can only tell you it crashed at a cryptic memory address like 0x4005d1.
- Lesson 1160 — Compiling with `-g` for debug symbols
- 0x56
- Because we used a logical mask rather than a memory pointer, this code will extract 0x56 correctly on every single computer in existence, regardless of its endianness.
- Lesson 955 — Using masks for cross-platform bit logic
- 0x78
- Little Endian: Stores the "least significant byte" (0x78) at the lowest memory address.
- Lesson 950 — Big Endian vs Little Endian explained
- 0x78563412
- If a Little Endian computer sends 0x12345678 to a Big Endian computer without converting it, the second computer will read the bytes in reverse and think the number is 0x78563412!
- Lesson 730 — Endianness and binary portabilityLesson 950 — Big Endian vs Little Endian explained
- 0x7ff
- Printing ptr shows you a messy memory address (like 0x7ff...).
- Lesson 238 — The Indirection operator `*`
- 0x7ff7bfeff4a8
- When you run this, you’ll see an output like 0x7ff7bfeff4a8.
- Lesson 451 — Hexadecimal notation for memory
- 0x7ffcc822
- Instead, it will look like a strange string of numbers and letters, such as 0x7ffcc822.
- Lesson 450 — Printing addresses with `%p`
- 0x7ffd5e32
- If you run this code, you will see a strange-looking code like 0x7ffd5e32.
- Lesson 80 — Variables in memory addresses
- 0x7ffe
- It tells the debugger: "Hey, this chunk of machine code at address 0x7ffe actually belongs to the variable userAge on line 12 of main.c."
- Lesson 825 — Compiling with debug symbols `-g`
- 0x7ffee45b8
- When you run this, you’ll see the number 12, followed by a complex code like 0x7ffee45b8.
- Lesson 449 — The Address-of operator `&`
- 0x7ffee495
- When you run this, you will see a hexadecimal number (like 0x7ffee495).
- Lesson 237 — The Address-of operator `&`
- 0x7ffeed
- The p stands for "pointer," and it tells C to print a memory address, which usually looks like a strange string of numbers and letters (hexadecimal), such as 0x7ffeed.
- Lesson 449 — The Address-of operator `&`
- 0x7ffeed3c
- When you run this, you will see a strange-looking code like 0x7ffeed3c.
- Lesson 448 — How variables are stored in RAM
- 0xff
- Imagine you have a data buffer and you need to find where a specific "header" byte (like 0xFF) starts so you can process the data following it.
- Lesson 689 — Printing hex and octal valuesLesson 859 — Searching memory bytes with `memchr`
- 0xFF000000
- In this code, 0xFF000000 acts like a spotlight, highlighting only the first 8 bits.
- Lesson 953 — Manual byte swapping techniques
- 1 << exponent
- While 1 << exponent is a clever trick, using it everywhere before you know if your program is actually slow makes your code a minefield for other developers.
- Lesson 1187 — The trap of premature optimization
- 1 | anything
- Because 1 | anything is always 1, we use this operator to "set" bits (turn them to 1).
- Lesson 182 — Setting bits with `|`
- 1.2e3
- Unlike simpler functions, strtod handles scientific notation (like 1.2e3) and tells you exactly where the "non-numeric" part of a string begins.
- Lesson 873 — Converting strings to doubles with `strtod`
- 10 * sizeof(int)
- Instead of asking for "40 bytes," we ask for 10 * sizeof(int).
- Lesson 538 — Calculating size with sizeof
- 100 / x
- C stops there and never performs the 100 / x calculation.
- Lesson 171 — Short-circuit evaluation of `||`
- 11 bytes of internal fragmentation
- If a user asks for 5 bytes, but your allocator only hands out 16-byte chunks, you have 11 bytes of internal fragmentation.
- Lesson 582 — Internal vs External fragmentation
- 12 bytes
- Even though you only defined 6 bytes of data (1 + 4 + 1), sizeof(struct FastFood) will likely return 12 bytes.
- Lesson 638 — Understanding memory alignmentLesson 640 — Structure holes and performance
- 12abc
- The result of a paste must be a valid C "token." If you try to glue 12 and abc to get 12abc, your compiler will complain because a variable name cannot start with a number.
- Lesson 777 — The token-pasting operator `##`
- 1player
- Start with a letter: You can use numbers inside the name, but never at the start (e.g., player1 is fine, but 1player will cause an error).
- Lesson 75 — The syntax of a declaration
- 2.0f
- In the code above, the computer stores 2.0f in memory.
- Lesson 657 — Using unions for type punning
- 20 steps
- For a sorted list of one million items, Binary Search will find your target (or prove it isn't there) in just about 20 steps.
- Lesson 1062 — Binary Search: Iterative approach
- 2D array
- Use a 2D array if you need to modify the characters frequently and you know all your strings will be roughly the same length.
- Lesson 414 — Introduction to 3D and higher arraysLesson 483 — Array of strings vs 2D char array
- 2D char array
- Think of a 2D char array as a structured parking lot.
- Lesson 483 — Array of strings vs 2D char array
- 2nd_Place
- While you might be tempted to name a variable Total $ Amount or 2nd_Place, the C compiler will throw an error.
- Lesson 74 — Naming rules and identifiers
- 2points
- For example, points2 is fine, but 2points is illegal.
- Lesson 74 — Naming rules and identifiers
- 3.14f
- When you assigned 3.14f to u.decimal, the program went to the union's memory address and wrote the binary pattern for that float.
- Lesson 655 — Accessing union members
- 3.4028e+38
- Instead of hard-coding a limit like 3.4028e+38, you use FLT_MAX, and your program will automatically adapt if it is ever moved to a different type of processor.
- Lesson 103 — The `<float.h>` header file
- 32-bit system
- On a 32-bit system, every pointer is typically 4 bytes.
- Lesson 452 — The size of a pointer variable
- 3D array
- A 3D array is the entire book—a collection of multiple pages.
- Lesson 414 — Introduction to 3D and higher arrays
- 3D arrays
- This is where 3D arrays (and beyond) come into play.
- Lesson 414 — Introduction to 3D and higher arrays
- 3x3
- When you work with a 2D array, like a 3x3 grid, it is helpful to think of it as a spreadsheet.
- Lesson 413 — Summing rows and columns individually
- 4 bytes
- On a 32-bit system, every pointer is typically 4 bytes.
- Lesson 452 — The size of a pointer variable
- 4096 bytes (4 KB)
- In most modern systems, a single page is 4096 bytes (4 KB).
- Lesson 597 — Virtual memory pages and offsets
- 4D array
- A 4D array could be thought of as a shelf of books.
- Lesson 414 — Introduction to 3D and higher arrays
- 5 + -10u
- This conversion happens automatically if you mix types in math (like 5 + -10u).
- Lesson 232 — Signed to unsigned conversion
- 5 cards
- If you have 5 cards, you can sort them in seconds.
- Lesson 1050 — Time complexity of O(n^2) sorts
- 50 cards
- If you have 50 cards, it takes significantly longer, but you can still do it at your desk.
- Lesson 1050 — Time complexity of O(n^2) sorts
- 5D array
- A 5D array could be a room full of shelves, and so on.
- Lesson 414 — Introduction to 3D and higher arrays
- 64-bit system
- On a 64-bit system, every pointer is typically 8 bytes.
- Lesson 452 — The size of a pointer variable
- 7e7
- Sometimes, looking at a raw hex number like 7e7 is confusing—is that a word or a number?
- Lesson 689 — Printing hex and octal values
- 8 bytes
- Even though a char is 1 byte and an int is 4 bytes, sizeof(Resource) will likely return 8 bytes, not 5.
- Lesson 452 — The size of a pointer variableLesson 573 — Struct padding for alignment
- 9 characters
- If you tell fgets the limit is 10, it will read at most 9 characters from the user, then add the \0 at the end to keep things tidy.
- Lesson 706 — The buffer size argument in fgets
A
- A && B
- When C evaluates A && B, it follows a two-step process:
- Lesson 223 — Sequence points in logic `&&` and `||`
- a + b
- Think of these parentheses as "safety bubbles." By wrapping (x), you ensure that no matter what complex math the user plugs in—whether it’s a + b or 10 - 2—it stays grouped together as a single unit during the substitution process.
- Lesson 773 — Why parenthesize macro argumentsLesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checks
- a + b * c
- In the expression a + b c, precedence tells the compiler: "Group b and c together for multiplication, then add the result to a." It defines the mathematical grouping, not the timing*.
- Lesson 227 — Order of evaluation vs Precedence
- a + b > MAX
- Instead of checking if a + b > MAX, which might overflow during the check itself, we check if a > MAX - b.
- Lesson 1154 — Safe integer arithmetic and overflow checks
- a <= b
- Is a smaller than b OR exactly the same as b?
- Lesson 160 — Greater or equal `>=` and less or equal `<=`
- a = b
- In C, when you work with basic variables like integers, copying is easy: a = b;.
- Lesson 604 — Copying structs with the assignment operator
- a = b = 5
- In the expression a = b = 5;, the computer doesn't look at a first.
- Lesson 196 — Chained assignments `a = b = c`
- a == b
- In the example above, a == b would be false because 0.1 + 0.2 results in a value slightly higher than 0.3 deep in the decimal places.
- Lesson 166 — Comparing floating-point numbers
- a > MAX - b
- Instead of checking if a + b > MAX, which might overflow during the check itself, we check if a > MAX - b.
- Lesson 1154 — Safe integer arithmetic and overflow checks
- a >= b
- Is a larger than b OR exactly the same as b?
- Lesson 160 — Greater or equal `>=` and less or equal `<=`
- A negative value
- string1 comes before string2 (e.g., "apple" vs "banana").
- Lesson 850 — Lexicographical comparison with `strcmp`
- A positive value
- string1 comes after string2 (e.g., "cherry" vs "banana").
- Lesson 850 — Lexicographical comparison with `strcmp`
- A->next
- A common mistake is updating A->next to point to B as your very first step.
- Lesson 1005 — Common pointer update pitfalls
- A->next = B
- If you set A->next = B, but forget to set B->prev = A, your list works fine when reading forward, but your program will crash or behave unpredictably the moment you try to traverse the list backward.
- Lesson 1005 — Common pointer update pitfalls
- a.exe
- By default, if you run gcc hello.c, the compiler creates a generic executable file named a.out (or a.exe on Windows).
- Lesson 57 — Basic `gcc` command flags
- a.out
- The name a.out stands for "assembler output." In the early days of Unix in the 1970s, programmers decided that if you were lazy and didn't provide a name, the computer would just use this generic placeholder.
- Lesson 28 — Phase 4: The LinkerLesson 31 — How the OS runs a programLesson 32 — Executing from the command lineLesson 57 — Basic `gcc` command flagsLesson 58 — Naming the output with `-o`Lesson 60 — Understanding the `a.out` defaultLesson 68 — Warnings vs Fatal errors
- a[3]
- If you want the mail in the 4th box, you might say a[3].
- Lesson 473 — The equivalence of `a[i]` and `*(a + i)`
- a[i]
- I better reload a[i] from memory every single loop iteration just in case the last write to result[i] changed it."* With restrict, the compiler can load values much more efficiently, knowing they won't change unexpectedly.
- Lesson 473 — The equivalence of `a[i]` and `*(a + i)`Lesson 915 — The `restrict` pointer qualifier
- AAA
- A good unit test follows a simple pattern often called AAA:
- Lesson 1172 — Principles of Unit Testing
- abc
- The result of a paste must be a valid C "token." If you try to glue 12 and abc to get 12abc, your compiler will complain because a variable name cannot start with a number.
- Lesson 777 — The token-pasting operator `##`
- abs
- By having a dedicated function for floating-point numbers (fabs) and another for integers (abs), the computer can process the math using the most efficient instructions for that specific data type.
- Lesson 866 — Absolute values for floats with `fabs`
- abs()
- If you try to use abs() on a number like -5.5, you might get an unexpected result or a compiler warning because abs() expects a whole number.
- Lesson 866 — Absolute values for floats with `fabs`
- abstract
- C was designed to be a "Hardware Abstraction Layer." To abstract something means to hide the messy, complex details and replace them with a simpler interface.
- Lesson 8 — Hardware abstraction in C
- accept()
- You can keep the client_fd in a list of active customers while your main loop goes back to accept() on the server_fd to wait for the next person in line.
- Lesson 1113 — Accepting client connections
- access()
- While you could simply try to open a file and check if it returns NULL, there is a more specialized tool for "peeking" at a file without actually touching its contents: the access() function.
- Lesson 762 — Checking if a file exists
- Account
- Whichever style you choose—whether it is Account_t or Account—the golden rule is to pick one and stick to it throughout your entire project.
- Lesson 612 — Naming conventions for typedef types
- Account_t
- Whichever style you choose—whether it is Account_t or Account—the golden rule is to pick one and stick to it throughout your entire project.
- Lesson 612 — Naming conventions for typedef types
- accountBalance
- Imagine changing a user's accountBalance just because you looped too far through a name string.
- Lesson 938 — Accessing out-of-bounds memory
- accumulator
- In the second example, the "work" is passed forward through the accumulator parameter.
- Lesson 362 — Tail call optimization basics
- Accumulator Pattern
- In programming, we call this the Accumulator Pattern.
- Lesson 316 — The Accumulator pattern (summing values)
- action
- In mathematics, the equals sign (=) usually means "these two things are the same." However, in C programming, the = symbol is an action.
- Lesson 22 — Semicolons as statement terminatorsLesson 78 — Assigning values with `=`Lesson 255 — Common mistake: assignment (=) vs equality (==)Lesson 516 — Calling a function via a pointer
- action()
- If you have a pointer named action, you call it by writing action();.
- Lesson 516 — Calling a function via a pointer
- active calls
- The downward slope represents the active calls being added to the stack.
- Lesson 363 — Visualizing recursive depth
- add
- If you forgot to include math_utils.c in the command, the linker would get confused and throw an "undefined reference" error because it couldn't find the instructions for add.
- Lesson 26 — Phase 2: Compilation to AssemblyLesson 27 — Phase 3: Assembly to Object CodeLesson 226 — Function call sequence pointsLesson 381 — Compiling multiple `.c` filesLesson 514 — Syntax of function pointersLesson 805 — What is inside a `.o` fileLesson 957 — The `asm` keyword syntaxLesson 959 — Input and Output operands in assemblyLesson 1174 — Building a minimal custom test harness
- add_and_print
- Instead of writing separate functions for add_and_print and multiply_and_print, we write one compute function that accepts a "math rule" as an argument.
- Lesson 518 — Passing functions as arguments
- add_numbers
- The resulting my_program now contains a copy of add_numbers.
- Lesson 812 — Linking with static libraries
- add()
- This allows your main.c to call the add() function while staying blissfully ignorant of the underlying code.
- Lesson 378 — Separating interface from implementationLesson 381 — Compiling multiple `.c` files
- addEdge
- Always ensure that every malloc used during your addEdge or createGraph functions has a corresponding free in your cleanup logic.
- Lesson 1046 — Graph memory management
- adder
- Suppose you have a program called adder that adds two numbers.
- Lesson 1178 — Automating tests with a Shell script
- addFive(num)
- When addFive(num) is called, the value 10 is copied into a new local variable also called num that belongs exclusively to the function.
- Lesson 339 — Local scope of parameters
- address
- By nesting the Address inside the User, you tell the compiler (and other programmers) that this specific address format is intrinsically tied to the user.
- Lesson 448 — How variables are stored in RAMLesson 449 — The Address-of operator `&`Lesson 487 — Passing addresses to functionsLesson 488 — Modifying caller variablesLesson 492 — Side effects in pointer-based functionsLesson 623 — Defining a struct inside another structLesson 625 — Initializing nested structuresLesson 627 — Limitations of self-referential definitionsLesson 911 — Difference between `const int *` and `int * const`Lesson 1118 — Passing arguments to threads
- Address-of operator
- You can actually ask C to show you the "mailbox number" where a variable is living by using the Address-of Operator (&).
- Lesson 237 — The Address-of operator `&`Lesson 448 — How variables are stored in RAMLesson 449 — The Address-of operator `&`
- addresses
- Instead of the function trying to shove two items through the narrow "return" slot, the caller hands the function the addresses of two variables.
- Lesson 489 — Returning multiple values via pointers
- AddressSanitizer
- Modern compilers like GCC and Clang offer a faster, "built-in" alternative called AddressSanitizer (or ASan).
- Lesson 1171 — Using AddressSanitizer (`-fsanitize=address`)
- addScore
- The addScore function is only aware of its own bucket.
- Lesson 486 — Pass-by-value limitations
- addScore(myScore)
- When addScore(myScore) is called, C looks at the value inside myScore (which is 50) and copies that number into a brand new memory bucket named localScore.
- Lesson 486 — Pass-by-value limitations
- Adjacency List
- Think of an Adjacency List like a row of mailboxes at an apartment complex.
- Lesson 1041 — Adjacency List implementationLesson 1042 — Adding edges in directed graphs
- Adjacency Matrix
- In computer science, this grid is called an Adjacency Matrix.
- Lesson 1040 — Adjacency Matrix implementation
- advisory locking
- By default, fcntl() provides advisory locking.
- Lesson 1099 — File locking with fcntl()
- AF_INET
- By changing AF_INET to AF_UNIX or SOCK_STREAM to SOCK_DGRAM, you completely change how your program interacts with the world without changing the rest of your logic.
- Lesson 1108 — Socket domains and typesLesson 1109 — The sockaddr_in structureLesson 1110 — Creating a socket with socket()
- AF_UNIX
- Also called "Local" sockets. This is used for two programs running on the same physical machine. It’s faster because the data never actually hits the network hardware.
- Lesson 1108 — Socket domains and types
- after
- It is like a restaurant where you sit down and start eating, and the waiter only checks if you have enough money to stay for the next course after you've finished the first one.
- Lesson 199 — Postfix increment `x++`Lesson 278 — Converting a while loop to a do-whileLesson 721 — Detecting the end of a file with feofLesson 722 — Why feof inside a loop condition is badLesson 752 — Setting custom buffers with setvbuf
- after every lap
- The final part runs after every lap is finished.
- Lesson 282 — The three parts of a for loop header
- age
- In the example above, if you accidentally wrote %f for the age variable, the program wouldn't print "25.000000." It would likely print a massive, random-looking number because it is trying to read "integer-shaped" data with a "float-shaped" lens.
- Lesson 55 — Argument-specifier matchingLesson 68 — Warnings vs Fatal errorsLesson 141 — Function parameters as local scopeLesson 168 — Logical AND `&&`Lesson 236 — The `sizeof` operator with variablesLesson 237 — The Address-of operator `&`Lesson 239 — Member access `.` and `->`Lesson 244 — The if statement syntaxLesson 245 — The else clause for alternative pathsLesson 277 — Using do-while for input re-promptingLesson 447 — Memory as a linear sequence of bytesLesson 560 — Reading from uninitialized memoryLesson 603 — Designated initializers in C99Lesson 975 — Implementing a generic 'Print' macro
- age < 18
- You could technically write two separate if statements (one for age >= 18 and one for age < 18), but using else is much cleaner and safer.
- Lesson 245 — The else clause for alternative paths
- age >= 18
- You could technically write two separate if statements (one for age >= 18 and one for age < 18), but using else is much cleaner and safer.
- Lesson 245 — The else clause for alternative paths
- ages
- You can use ages to find the start of your data, but you cannot reassign ages to point to a different array later on.
- Lesson 476 — Pointer to the start of an array
- alarm()
- What you'll learn: How to use the alarm() function to schedule a "wake-up call" that interrupts your program after a specific amount of time.
- Lesson 1091 — Handling alarms with alarm()
- alarm(0)
- Canceling: If you want to turn the timer off before it rings, you call alarm(0).
- Lesson 1091 — Handling alarms with alarm()
- alarm(10)
- If you call alarm(10) and then call alarm(5) two seconds later, the first alarm is canceled and replaced by the new 5-second timer.
- Lesson 1091 — Handling alarms with alarm()
- alarm(5)
- When you call alarm(5), you are telling the Operating System: "Hey, let me go back to my work, but please poke me in exactly five seconds." When the time is up, the OS sends a SIGALRM signal to your process.
- Lesson 1091 — Handling alarms with alarm()
- Alert.Red
- You can have a Color.Red and a Alert.Red without any issues.
- Lesson 666 — Scoped enum limitations in C
- alias
- In C, the typedef keyword stands for "type definition." Despite the name, it doesn’t actually create a new type of data; instead, it creates an alias or a nickname for a type that already exists.
- Lesson 608 — Using typedef with primitive types
- aligned_alloc
- While malloc provides memory aligned for any standard data type, aligned_alloc gives you the power to specify a custom boundary.
- Lesson 576 — The aligned_alloc function
- alignment
- Use aligned_alloc to place memory at specific address boundaries, ensuring the size is a multiple of the alignment.
- Lesson 453 — Determining variable alignment in memoryLesson 576 — The aligned_alloc functionLesson 948 — The `#pragma pack` directive
- alignof
- The alignof operator reveals the byte-boundary requirements of a type, helping you understand how the CPU organizes data for maximum speed.
- Lesson 453 — Determining variable alignment in memoryLesson 572 — The alignof operator
- alignof(int)
- By passing the alignment requirement (like alignof(int)) to your allocator, you ensure the pointer returned is always "legal" for the data type you intend to store there.
- Lesson 572 — The alignof operatorLesson 589 — Handling alignment within an arena
- all
- While a struct allocates enough memory to hold all its members simultaneously, a union only allocates enough memory to hold its largest member.
- Lesson 653 — Defining a union with the union keywordLesson 823 — Phony targets like `clean` and `all`Lesson 1103 — Closing unused pipe ends
- ALL_CAPS
- By convention, we write these names in ALL_CAPS to signal to other programmers that this isn't a regular variable—it’s a constant defined by the preprocessor.
- Lesson 771 — Avoiding magic numbers with macros
- ALL_CAPS_WITH_UNDERSCORES
- Use ALL_CAPS_WITH_UNDERSCORES for constants to clearly signal that their values are permanent and should not be modified.
- Lesson 117 — Naming conventions for constants
- Allman
- In C, two "dialects" rule the landscape: K&R and Allman.
- Lesson 1196 — Consistency: K&R vs. Allman style
- allocated
- A "definitely lost" report points to the line where memory was allocated, reminding you that you failed to provide a corresponding free for that specific pointer.
- Lesson 566 — Reading 'definitely lost' reports
- already locked
- If the mutex is already locked, the function does not wait.
- Lesson 1129 — Using pthread_mutex_trylock
- also has a
- Because the input has a 1 in the third position and the mask also has a 1 there, the result becomes 4 (00000100).
- Lesson 180 — Masking bits with `&`
- Alt + Tab
- Think of the Alt + Tab switcher on your computer.
- Lesson 1004 — Circular doubly linked lists
- always prefer inline functions
- In modern C, always prefer inline functions. They provide the same performance benefits as macros but include the "safety net" of the compiler’s type-checking and predictable logic.
- Lesson 370 — Macros vs. Inline functions
- Always verify before you dereference
- Safe C programming relies on a simple rule: Always verify before you dereference. Since functions like malloc() or custom search functions might return NULL if they fail, you should wrap your pointer logic in an if statement.
- Lesson 525 — Dereferencing the NULL pointer
- Amortized Time Complexity
- This "averaged-out" cost is what we call Amortized Time Complexity.
- Lesson 985 — Amortized time complexity
- amount
- If a float and an int are both 4 bytes, the amount section only takes up 4 bytes total.
- Lesson 670 — Combining structs and unions
- analysis.txt
- Inside analysis.txt, you will see a table.
- Lesson 1182 — Introduction to the `gprof` profiler
- and a false one to
- In C, a true comparison evaluates to 1 and a false one to 0.
- Lesson 1189 — Reducing branching in tight loops
- and a very large constant called
- The rand() function returns an integer between 0 and a very large constant called RAND_MAX (usually at least 32,767).
- Lesson 883 — Generating pseudo-random numbers with `rand`
- and any false value (0) to
- The ! operator flips a true value to 0 and any false value (0) to 1.
- Lesson 167 — Logical NOT `!`
- and change it to
- If you add two more numbers to your array later, you have to find every place you wrote 7 and change it to 9.
- Lesson 388 — Calculating array size with `sizeof`
- and ends at index
- Because C arrays are zero-indexed, a 10-element array starts at index 0 and ends at index 9.
- Lesson 405 — Avoiding off-by-one errors in loops
- and falsehood to
- The ! operator flips truth to 0 and falsehood to 1, while !! scales any non-zero value down to a clean 1.
- Lesson 174 — Operator `!` and boolean normalization
- and increment
- In i = i++, you are asking the computer to assign a value to i and increment i at the same time.
- Lesson 937 — Sequence point violations
- and it calls
- If main() has a variable named x and it calls calculate(), which also has a variable named x, they do not clash.
- Lesson 349 — Storage of local variables
- and once for
- If this were an undirected graph, you would have to call the logic twice (once for 0 to 1 and once for 1 to 0).
- Lesson 1042 — Adding edges in directed graphs
- and only catches the
- While isgraph() catches everything from A to &, ispunct() ignores the A and only catches the &.
- Lesson 843 — Distinguishing `ispunct` and `isgraph`
- and the
- By adding a 0 followed by a number between the % and the d, you tell C: "I want this number to be at least this many characters wide, and if it isn't, fill the empty space with zeros."
- Lesson 43 — Printing literal stringsLesson 102 — Formatting decimals with `%.nf`Lesson 438 — Handling the `scanf` buffer overflowLesson 688 — Zero-padding numerical outputLesson 695 — Limiting string length in scanf
- and the number
- Computers see the number 5 as 0101 and the number 6 as 0110.
- Lesson 176 — Bitwise OR `|`
- and the second
- In the code above, the compiler looks at the first pair {0, 0} and knows that 0 goes to x and the second 0 goes to y because that is the order defined in the struct Point.
- Lesson 631 — Initializing arrays of structs
- Angle Brackets <filename.h>
- Angle Brackets <filename.h>: These are for Standard Headers.
- Lesson 795 — Standard header search paths
- anonymous
- While typedef allows us to create a nickname for an existing struct, we can actually go one step further: creating a "nameless" or anonymous struct that exists only through its alias.
- Lesson 611 — Anonymous structs with typedef
- Anonymous mapping
- Anonymous mapping is like renting an empty unit just to have the open floor space to build something new from scratch.
- Lesson 594 — Anonymous memory mappings
- anonymous union
- An anonymous union allows you to skip that middle name.
- Lesson 671 — Anonymous unions inside structs
- Any non-zero value
- Any non-zero value (1 to 255) means Failure.
- Lesson 1072 — Process termination and exit codes
- any non-zero value is considered true
- Instead, any non-zero value is considered true.
- Lesson 163 — Truthiness: 0 vs non-zero
- Any other number
- Any other number (like 1, 2, or -1) usually indicates that an error occurred.
- Lesson 24 — The `return 0;` statement
- Anything else (non-zero)
- Anything else (non-zero) is considered True.
- Lesson 243 — Truthiness: 0 is false, non-zero is true
- app
- When you run make, Make sees $@ and thinks, "The target is app, so I'll put that there." It sees $< and thinks, "The first dependency is main.c, so I'll put that there." The actual command executed remains gcc main.c -o app.
- Lesson 819 — Targets, dependencies, and recipesLesson 822 — Automatic variables like `$@` and `$<`
- Apple
- Identifiers must start with a letter or underscore and contain only alphanumeric characters, remembering that Apple and apple are two different variables.
- Lesson 23 — Case sensitivity in CLesson 25 — Phase 1: The PreprocessorLesson 74 — Naming rules and identifiers
- Apple clang version
- If you see a wall of text that includes a version number (like gcc 11.4.0 or Apple clang version...), you are successful!
- Lesson 10 — Installing GCC on Linux/macOS
- apples
- After the addition, your apples bucket still technically has "12" in it; you’ve simply used a copy of that value to create a new sum.
- Lesson 150 — The addition operator `+`
- applesInBasket
- You can also do both steps at once, as shown with applesInBasket.
- Lesson 81 — The `int` keyword
- ar
- The ar tool creates static libraries by bundling .o object files into a single .a archive for easier distribution and linking.
- Lesson 810 — What is a static library `.a`Lesson 811 — Creating archives with the `ar` tool
- ar rcs libutils.a
- In the command ar rcs libutils.a ..., the flags mean:
- Lesson 811 — Creating archives with the `ar` tool
- archive/old.txt
- Moving Files: You can use rename to move a file across directories on the same disk drive (e.g., from data/old.txt to archive/old.txt).
- Lesson 756 — Renaming files with rename
- archiver
- With a static library, you use a tool called an archiver (ar) to glue those .o files together.
- Lesson 810 — What is a static library `.a`
- area_calc
- You want the final, runnable file to be named area_calc so you know exactly what it does when you look at your files later.
- Lesson 58 — Naming the output with `-o`
- Arena
- Use an Arena when objects share the same "lifetime" (they all die at the same time).
- Lesson 591 — Trade-offs of arena vs malloc
- arena_reset
- Because you only call arena_reset, it is impossible to have a memory leak within your loop.
- Lesson 587 — Resetting an arena in one stepLesson 588 — Arena allocation for frame-based tasks
- arena_reset()
- If you are writing a game or a web request handler, you can allocate everything you need for one frame or one request, then call arena_reset() at the end.
- Lesson 586 — Linear or Bump allocators
- argc
- By narrowing our scope to just these three steps, we can focus on mastering file I/O (fopen), string searching (strstr), and command-line arguments (argc and argv).
- Lesson 1204 — Project scope: A custom `grep` cloneLesson 1205 — Handling `argc` and `argv` robustly
- args
- If you forget to put NULL at the end of your args array, execv() will keep reading past your variables into random parts of your computer's memory.
- Lesson 1082 — Passing arguments to execv()
- Argument
- Think of the Parameter as a parking spot and the Argument as the car.
- Lesson 335 — Parameters vs. Arguments
- argv
- Once execv() is called successfully, the current process is wiped clean, and the new program starts fresh using the strings you provided in your array as its own argv.
- Lesson 506 — Command line arguments `char **argv`Lesson 1082 — Passing arguments to execv()Lesson 1204 — Project scope: A custom `grep` cloneLesson 1205 — Handling `argc` and `argv` robustlyLesson 1208 — Adding command line flags (e.g., `-i` for case)
- argv[0]
- Since argv[0] is always the name of the program itself, a program expecting one additional argument (like a filename) needs argc to be exactly 2.
- Lesson 1205 — Handling `argc` and `argv` robustly
- arithmetic operator
- It is an arithmetic operator used to add two values together.
- Lesson 150 — The addition operator `+`
- arithmetic shift
- To prevent this, C often uses an arithmetic shift for signed integers.
- Lesson 185 — Logical vs Arithmetic shifts
- ARM
- The two main titans you will encounter are x86 (Complex Instruction Set) and ARM (Reduced Instruction Set).
- Lesson 963 — Platform-specific assembly (x86 vs ARM)
- arr[index]
- Without this sequence point, the compiler might try to evaluate arr[index] at the same time it is trying to increment index.
- Lesson 223 — Sequence points in logic `&&` and `||`
- array of function pointers
- In C, an array of function pointers is that row of buttons.
- Lesson 517 — Arrays of function pointers
- array of pointers
- Use an array of pointers when your strings have very different lengths (like a dictionary) or when you want to easily "swap" the order of strings.
- Lesson 483 — Array of strings vs 2D char arrayLesson 927 — Arrays of pointers vs Pointers to arrays
- array of structures
- An array of structures is the entire spreadsheet.
- Lesson 632 — Indexing into a struct array
- array_ptr
- By adding parentheses (*array_ptr), we force the compiler to treat array_ptr as a pointer first.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- array_ptr++
- If you increment this pointer (array_ptr++), it jumps forward by the size of five integers at once, rather than just one.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- array[0]
- If you write array[0] = array[1], the original value in array[0] is overwritten and lost forever.
- Lesson 439 — Swapping elements in an array
- array[0] = array[1]
- If you write array[0] = array[1], the original value in array[0] is overwritten and lost forever.
- Lesson 439 — Swapping elements in an array
- array[0][0]
- When you access array[0][0] and then array[0][1], the CPU likely already loaded the second value into the cache because they are neighbors.
- Lesson 1191 — The impact of Cache Locality
- array[0][1]
- When you access array[0][0] and then array[0][1], the CPU likely already loaded the second value into the cache because they are neighbors.
- Lesson 1191 — The impact of Cache Locality
- array[1][0]
- If you jump from array[0][0] to array[1][0], you are jumping over an entire row, potentially missing the cache entirely.
- Lesson 1191 — The impact of Cache Locality
- array[49]
- Instead of remembering that "Employee 50" is stored at array[49], we can create a relationship where the ID string "EMP50" directly maps to a struct containing the employee's name and salary.
- Lesson 1031 — Key-Value pair concept
- array[i]
- Even though your array is technically a pointer, C treats array[i] as shorthand for "start at the pointer address and move i steps forward."
- Lesson 986 — Accessing elements by index
- array[index]
- Access dynamic array elements using the array[index] syntax just like static arrays, as the compiler automatically calculates the memory offset for you.
- Lesson 386 — Accessing elements with the `[]` operatorLesson 986 — Accessing elements by index
- array[j + 1]
- The outer loop tracks how many passes we need to make, while the inner loop performs the actual comparisons and swaps between adjacent elements (array[j] and array[j + 1]).
- Lesson 445 — Sorting an array using Bubble Sort
- array[j]
- The outer loop tracks how many passes we need to make, while the inner loop performs the actual comparisons and swaps between adjacent elements (array[j] and array[j + 1]).
- Lesson 445 — Sorting an array using Bubble Sort
- array[last_index]
- Unlike an array where you can jump to array[last_index], a linked list requires a "walk." The while (last->next != NULL) loop is the heartbeat of this process.
- Lesson 994 — Appending nodes to the tail
- array[row][col]
- To traverse a 2D array, use an outer loop for the rows and an inner loop for the columns to access each element at array[row][col].
- Lesson 410 — Accessing elements using `[row][col]`Lesson 411 — Nested `for` loops for 2D traversal
- arrayName[i]
- Inside the loop, you access the current element using the syntax arrayName[i].
- Lesson 399 — Using `for` loops for array traversal
- arrayName[index] = newValue
- To modify an array element, use the syntax arrayName[index] = newValue;, making sure your index is within the array's bounds.
- Lesson 387 — Modifying individual array elements
- arrayName[index].member
- Use arrayName[index].member to reach inside a specific structure within an array.
- Lesson 632 — Indexing into a struct array
- arrayName[index].memberName
- Access a specific member within an array of structures by using the format arrayName[index].memberName.
- Lesson 633 — Combining array indexing and member access
- arrayName[rowIndex][columnIndex]
- It looks like this: arrayName[rowIndex][columnIndex].
- Lesson 410 — Accessing elements using `[row][col]`
- arrow
- Use the arrow (->) when you are holding a map (the pointer) that tells you where the box is.
- Lesson 165 — Common pitfall: `=` vs `==`Lesson 239 — Member access `.` and `->`Lesson 616 — The arrow operator `->` syntax
- arrow operator
- In C, when you have a pointer to a struct, you use the arrow operator (->) to reach inside.
- Lesson 616 — The arrow operator `->` syntaxLesson 617 — Arrow operator vs dot operatorLesson 618 — Passing struct pointers to functionsLesson 619 — Modifying struct members via pointers
- arrow operator (->)
- C provides the arrow operator (->) as a shortcut.
- Lesson 617 — Arrow operator vs dot operator
- as
- It realizes that a double is more precise, so it treats the 5 as 5.0.
- Lesson 176 — Bitwise OR `|`Lesson 229 — Usual arithmetic conversions
- as "gets" and
- To keep them straight, try reading = as "gets" and == as "is equal to."
- Lesson 165 — Common pitfall: `=` vs `==`
- ASCII
- To solve this, computer scientists created a secret codebook called ASCII (American Standard Code for Information Interchange).
- Lesson 106 — Characters as small integersLesson 109 — The ASCII encoding scheme
- ASCII table
- To represent text, C uses a standard "translation manual" called the ASCII table.
- Lesson 105 — The `char` type
- asm
- Since the compiler doesn't always understand what your assembly code is doing, it might mistakenly think your asm block is useless.
- Lesson 957 — The `asm` keyword syntaxLesson 958 — The basic `volatile` asm blockLesson 959 — Input and Output operands in assemblyLesson 960 — The 'Clobber' list explainedLesson 961 — Direct register accessLesson 963 — Platform-specific assembly (x86 vs ARM)
- asm volatile
- What you'll learn: How to use the asm volatile syntax to prevent the C compiler from optimizing away or moving your manual assembly instructions.
- Lesson 957 — The `asm` keyword syntaxLesson 958 — The basic `volatile` asm block
- asm volatile ("instruction")
- Use asm volatile ("instruction") to force the compiler to respect and execute your assembly code exactly where you placed it.
- Lesson 958 — The basic `volatile` asm block
- asm()
- When you inject assembly using asm(), the compiler doesn't actually read your assembly string to see what you're doing.
- Lesson 960 — The 'Clobber' list explained
- Assembler
- Phase 3 is handled by a tool called the Assembler.
- Lesson 27 — Phase 3: Assembly to Object Code
- Assembly
- This is the "brain" of the operation, where your logic is translated from a language humans like (C) into a language that hardware understands, but can’t quite run yet: Assembly.
- Lesson 26 — Phase 2: Compilation to AssemblyLesson 27 — Phase 3: Assembly to Object Code
- assert
- You use assert to check for things that should never happen if your logic is correct.
- Lesson 901 — Using `assert` for internal debuggingLesson 1174 — Building a minimal custom test harness
- assert()
- Instead of manually deleting every assert() line from your source code—which would be a nightmare to put back later if you found a bug—the C Standard Library provides a "kill switch" called NDEBUG (which stands for "No Debug").
- Lesson 901 — Using `assert` for internal debuggingLesson 902 — Disabling assertions with `NDEBUG`Lesson 1173 — Writing a simple `assert()` check
- assert(expression)
- The syntax is straightforward: assert(expression);.
- Lesson 1173 — Writing a simple `assert()` check
- assign
- A single equals sign (=) is used to assign a value (e.g., "put the number 5 into this box").
- Lesson 71 — Common beginner typos
- assignment
- You have already used the single equals sign (=) for assignment, which acts like a bucket loader, dumping a value into a variable.
- Lesson 161 — The equality operator `==`Lesson 220 — Definition of a side effect
- assignment operator
- However, a specific group of operators—most notably the assignment operator (=)—prefers to drive on the other side of the road.
- Lesson 214 — Right-to-left associativity
- async-signal-safe
- To stay safe, signal handlers should only call functions explicitly labeled as async-signal-safe.
- Lesson 1089 — Signal safety and reentrant functions
- at
- If you ever find a 1 at [2][4] but a 0 at [4][2], your undirected graph is broken!
- Lesson 1043 — Adding edges in undirected graphs
- at least one
- In C, if you provide at least one value during initialization, the compiler steps in to help.
- Lesson 172 — Building complex logical expressionsLesson 392 — Partial initialization and default zeros
- at the root
- Imagine a tree with 5 at the root, 3 on the left, and 7 on the right.
- Lesson 1025 — In-order traversal (Sorted output)
- at the very end of the
- Notice the semicolon ; at the very end of the while statement.
- Lesson 277 — Using do-while for input re-prompting
- atexit
- Instead of trying to catch every possible return statement or exit point in your code, C provides a convenient "automatic reminder" system called atexit.
- Lesson 875 — Cleaning up at exit with `atexit`
- atexit()
- The atexit() function, found in <stdlib.h>, allows you to register a specific function to be called automatically when your program terminates normally.
- Lesson 875 — Cleaning up at exit with `atexit`
- atof
- While you might have heard of atof, it is often considered dangerous because it doesn't tell you if the conversion failed.
- Lesson 873 — Converting strings to doubles with `strtod`
- atoi
- What you'll learn: How to reliably convert strings to integers while detecting errors that simpler functions like atoi ignore.
- Lesson 871 — Converting strings to integers with `atoi` and `atol`Lesson 872 — Robust string-to-number conversion with `strtol`
- atoi("hello")
- If you try to convert a string that doesn't start with a number (like atoi("hello")), the function will simply return 0.
- Lesson 871 — Converting strings to integers with `atoi` and `atol`
- atol
- The <stdlib.h> library provides two simple functions for this: atoi (ASCII to integer) and atol (ASCII to long integer).
- Lesson 871 — Converting strings to integers with `atoi` and `atol`
- atol("2147483648")
- atol("2147483648") returns a long integer, which is necessary for numbers too large for a standard int.
- Lesson 871 — Converting strings to integers with `atoi` and `atol`
- atomic
- In computer science, atomic means "indivisible." When you perform an atomic load or store, the CPU guarantees the operation happens as a single, uninterruptible step.
- Lesson 1141 — Introduction to <stdatomic.h>Lesson 1142 — Atomic types like atomic_intLesson 1143 — Atomic load and storeLesson 1147 — Volatile vs Atomic
- Atomic Fetch and Add
- To fix this without the "heavy lifting" of a mutex (which is like putting the notebook in a locked safe), we use Atomic Fetch and Add.
- Lesson 1144 — Atomic fetch and add
- atomic_compare_exchange_strong
- In C11, we use atomic_compare_exchange_strong.
- Lesson 1145 — Compare and swap (CAS) basics
- atomic_fetch_add
- atomic_fetch_add allows multiple threads to update a shared counter simultaneously and safely without the performance overhead of traditional locks.
- Lesson 1144 — Atomic fetch and add
- atomic_int
- Atomic types like atomic_int ensure that simple operations are thread-safe at the hardware level, preventing data races without the overhead of Mutexes.
- Lesson 1141 — Introduction to <stdatomic.h>Lesson 1142 — Atomic types like atomic_int
- attackPower
- You need to take the current attackPower, multiply it by 2, and then save that new total back into attackPower.
- Lesson 194 — Compound multiplication and division
- attributes
- The C23 standard officially introduced a standardized way to give the compiler "sticky notes" called attributes.
- Lesson 971 — C23: Attributes like `[[maybe_unused]]`
- auto
- The auto keyword represents the default storage behavior where variables are created at the start of a block and automatically destroyed at the end.
- Lesson 140 — Automatic duration variablesLesson 143 — The `auto` keywordLesson 923 — Storage class specifier precedenceLesson 924 — The `register` keyword and its modern relevance
- auto int score = 0
- In the early days of C, programmers could explicitly write auto int score = 0; to tell the compiler that this variable should be created when the function starts and destroyed when the function ends.
- Lesson 143 — The `auto` keyword
- auto int x = 5
- While you can still write auto int x = 5;, nobody does because C assumes any variable declared inside a function is automatic by default.
- Lesson 140 — Automatic duration variables
- automatic duration variables
- They are known as automatic duration variables (often just called "local variables").
- Lesson 140 — Automatic duration variables
- Automatic memory
- Think of Automatic memory (The Stack) like a small, organized desk.
- Lesson 533 — Manual vs automatic memory management
- automatic storage duration
- Normally, when you declare a variable inside a function, it has automatic storage duration.
- Lesson 529 — Automatic storage duration on the stackLesson 920 — The `static` keyword inside functions
- automatic variables
- This is why local variables are called automatic variables—their lifecycle is managed for you.
- Lesson 530 — Stack frame lifecycle and local variablesLesson 822 — Automatic variables like `$@` and `$<`
- automatically re-locks the mutex
- Re-acquire: Once another thread signals that things are ready, your thread wakes up and automatically re-locks the mutex before the function returns.
- Lesson 1133 — Waiting with pthread_cond_wait
B
- b = 5
- So, the expression b = 5 actually "results" in the value 5.
- Lesson 196 — Chained assignments `a = b = c`
- B->next
- If you haven't already pointed B->next to C, node C (and everything following it) is now floating away in memory.
- Lesson 1005 — Common pointer update pitfalls
- B->prev = A
- If you set A->next = B, but forget to set B->prev = A, your list works fine when reading forward, but your program will crash or behave unpredictably the moment you try to traverse the list backward.
- Lesson 1005 — Common pointer update pitfalls
- back into a
- The second ! flips that 0 back into a 1.
- Lesson 174 — Operator `!` and boolean normalization
- backlog
- When you call listen(), you provide two arguments: the socket file descriptor and a backlog.
- Lesson 1112 — Listening for connections
- backtrace
- What you'll learn: How to use the backtrace command to see the sequence of function calls that led to a specific point or a crash in your program.
- Lesson 833 — Inspecting the call stack with `backtrace`Lesson 837 — Debugging a Segfault from a core dump
- backward
- To understand what is actually being protected, the best trick is to read the declaration backward (from right to left).
- Lesson 911 — Difference between `const int *` and `int * const`
- bake_cake
- When bake_cake finishes, the memory it used for temperature is instantly freed up for the next function call.
- Lesson 349 — Storage of local variables
- bake_cake()
- Readability: It is much easier to read bake_cake(); than to read fifty lines of code about flour, eggs, and oven temperatures.
- Lesson 322 — What is a function?
- Baker
- You have a Baker (the Producer) and a Cashier (the Consumer).
- Lesson 1136 — The producer-consumer problem
- balance
- By inserting printf() statements, you leave "breadcrumbs." If you expect a variable named balance to be 100, but the console shows it is -500, you have successfully narrowed down exactly where the logic failed.
- Lesson 1163 — Inspecting variable values at runtime
- balance -= 10
- Adjusting by a specific amount: balance -= 10;
- Lesson 268 — Updating the loop variable to avoid infinite loops
- balance = balance + 50
- Standard addition looks like this: balance = balance + 50;.
- Lesson 192 — Compound addition `+=`
- base
- By reserving a large chunk of virtual address space (e.g., 1GB) upfront, the base pointer never changes.
- Lesson 590 — Growing an arena with virtual memory
- base case
- To fix this, you must ensure every recursive function has a base case: a conditional statement that allows the function to return without making another call, finally allowing the stack of trays to be cleared.
- Lesson 352 — Identifying a Stack OverflowLesson 353 — Concept of self-calling functionsLesson 354 — Importance of the Base CaseLesson 355 — The Recursive StepLesson 357 — Factorial as a recursive exampleLesson 360 — Infinite recursion hazards
- batching
- High-performance C code often uses a technique called batching.
- Lesson 1185 — Profiling memory allocation frequency
- becomeRich(mySavings)
- When becomeRich(mySavings) is called, the value 50 is copied into the parameter money.
- Lesson 343 — Why changing a parameter doesn't affect the caller
- becomes
- Because the input has a 1 in the third position and the mask also has a 1 there, the result becomes 4 (00000100).
- Lesson 167 — Logical NOT `!`Lesson 174 — Operator `!` and boolean normalizationLesson 180 — Masking bits with `&`
- before
- If C worked from left to right here, the code would break because a would try to grab a value from b before b had anything inside it!
- Lesson 214 — Right-to-left associativityLesson 269 — Using while for indeterminate iterationsLesson 275 — Guaranteed execution: why do-while is differentLesson 277 — Using do-while for input re-promptingLesson 278 — Converting a while loop to a do-whileLesson 292 — Continue in while vs for loopsLesson 752 — Setting custom buffers with setvbufLesson 902 — Disabling assertions with `NDEBUG`
- before every lap
- The middle part is a true/false question asked before every lap.
- Lesson 282 — The three parts of a for loop header
- before it even touches
- In many cases, the compiler can decide to evaluate a before it even touches b or c.
- Lesson 227 — Order of evaluation vs Precedence
- Best-fit
- The Best-fit strategy, however, looks at all available gaps and realizes the 10-inch gap is the "tightest" fit.
- Lesson 584 — Allocation strategies: Best-fit
- between nodes
- Imagine you are inserting a new node B between nodes A and C.
- Lesson 1005 — Common pointer update pitfalls
- Big Endian
- Big Endian is like writing naturally: you put "CO" in the first box, "FF" in the second, and "EE" in the third.
- Lesson 950 — Big Endian vs Little Endian explained
- Big-Endian
- A Big-Endian system acts like we read English; it puts the "big end" (the 00) in the first mailbox and saves the 01 for the very last one.
- Lesson 951 — Checking system endianness at runtimeLesson 952 — Network byte order and `htons`/`ntohs`Lesson 953 — Manual byte swapping techniques
- billing.c
- If another programmer working on billing.c also creates a function named calculate_total(), the compiler will throw a "duplicate symbol" error when it tries to link the files together.
- Lesson 798 — Static functions for file scoping
- billsToPay
- C looks at billsToPay, sees a 0, and immediately skips the block.
- Lesson 243 — Truthiness: 0 is false, non-zero is true
- Binary
- You will rarely use Octal in modern programming, but you will use Hex and Binary constantly when working with colors (like #FF5733), memory addresses, or hardware pins.
- Lesson 119 — Integer literals (Hex, Octal, Binary)Lesson 156 — Unary plus and minus
- binary format
- Because we saved our data in binary format, we don't need to parse text or convert strings back into numbers.
- Lesson 1218 — Loading data from a binary file
- Binary Heap
- Before we can sort data using Heap Sort, we need to understand the Binary Heap.
- Lesson 1058 — Heap Sort: Binary heap concept
- Binary mode
- While we could use text (like a .txt file), saving in binary mode is faster and more efficient because it writes the data exactly as it looks in your computer's memory.
- Lesson 724 — Text mode vs Binary mode (b flag)Lesson 1217 — Saving the data store to a binary file
- Binary Search
- When data is sorted, we can use much smarter algorithms, like Binary Search.
- Lesson 1064 — Importance of sorted dataLesson 1065 — Time complexity: O(n) vs O(log n)
- Binary Writing
- Think of Binary Writing like taking a snapshot of a drawer in your desk.
- Lesson 725 — Writing raw bytes with fwrite
- bind()
- bind() assigns a specific identity (IP address and port) to your socket, transforming it from a generic communication tool into a reachable destination.
- Lesson 1109 — The sockaddr_in structureLesson 1111 — Binding to a port with bind()Lesson 1113 — Accepting client connectionsLesson 1114 — Client-side connect()
- bit-field
- C allows you to specify exactly how many bits a structure member should occupy using a bit-field.
- Lesson 648 — The colon operator and bit width
- bit-fields
- C allows you to define bit-fields within a struct.
- Lesson 954 — Bit-fields in structures and portability
- Bitwise AND (&)
- Bitwise AND (&): To isolate a specific byte (masking).
- Lesson 953 — Manual byte swapping techniques
- bitwise operators
- Use bitwise operators when you are doing low-level programming, like setting specific flags in hardware or compressing data.
- Lesson 173 — Logical vs Bitwise distinction
- Bitwise OR (|)
- Bitwise OR (|): To combine the moved bytes into a new result.
- Lesson 953 — Manual byte swapping techniques
- Bitwise XOR
- In C, the ^ symbol represents the Bitwise XOR (Exclusive OR) operator.
- Lesson 181 — Toggling bits with `^`
- block
- Instead, you request a block of five rooms in a single row on the same floor.
- Lesson 21 — Curly braces `{}` and blocksLesson 136 — Local variables and block scopeLesson 384 — Visualizing memory layout of arrays
- blueprint
- Imagine a header file as a blueprint for a house.
- Lesson 793 — What should NOT go in a header
- body
- A function definition consists of a header and a body.
- Lesson 323 — Anatomy of a function definition
- book
- If you have a Book struct, you might have one compartment for the price and another for the page count.
- Lesson 414 — Introduction to 3D and higher arraysLesson 602 — Initializing structs with brace notationLesson 623 — Defining a struct inside another struct
- Book Number
- To find a specific piece of information, you need two numbers: the Book Number and the Page Number within that book.
- Lesson 597 — Virtual memory pages and offsets
- bool
- If you wanted to make your code readable, you had to manually define constants or include <stdbool.h> (introduced in C99), which gave you bool as a macro for the slightly clunky _Bool type.
- Lesson 163 — Truthiness: 0 vs non-zeroLesson 189 — Using bitwise operators for flagsLesson 966 — C99: Variable declarations and `bool`Lesson 969 — C23: The `bool`, `true`, and `false` keywords
- bool is_running = true
- In older versions of C, if you typed bool is_running = true; without including a header file, the compiler would throw a tantrum, claiming it had no idea what a "bool" was.
- Lesson 969 — C23: The `bool`, `true`, and `false` keywords
- boolean normalization
- Sometimes you don't care that a variable equals 42; you just want a clean 1 to represent that the variable "has a value." This is where boolean normalization comes in.
- Lesson 174 — Operator `!` and boolean normalization
- Boolean values
- When you ask a question in English like "Is 5 greater than 3?", the answer is a simple "Yes." In programming, we call these Yes/No answers Boolean values (True or False).
- Lesson 164 — Boolean result of comparisons
- boots
- If you put a pair of boots in the locker, the locker contains boots.
- Lesson 659 — The danger of reading the wrong union member
- both
- If both sides are true, the entire expression results in 1 (true).
- Lesson 168 — Logical AND `&&`Lesson 247 — Logical AND (&&) for combined conditions
- bottles
- Once bottles hits 0, the loop "breaks," the program "exits" the curly braces, and moves on to the final print statement.
- Lesson 268 — Updating the loop variable to avoid infinite loops
- bottles > 0
- By changing bottles inside the loop, we are actively working toward the moment when bottles > 0 becomes false.
- Lesson 268 — Updating the loop variable to avoid infinite loops
- box
- If you change box, you are reaching all the way through the chain to modify the original treasure.
- Lesson 502 — Visualizing pointer chainsLesson 505 — Accessing data through double dereferenceLesson 616 — The arrow operator `->` syntax
- box containing a marble
- Think of a string literal (using double quotes) as a box containing a marble.
- Lesson 418 — Difference between `'a'` and `"a"`
- Brace notation
- Brace notation allows you to "stock the shelves" all at once, the very moment you declare the variable.
- Lesson 602 — Initializing structs with brace notation
- brand new socket
- Instead, it creates a brand new socket specifically for that one client.
- Lesson 1113 — Accepting client connections
- break
- In C programming, the break statement acts as that "early exit." While loops usually run until their main condition becomes false, break allows you to jump out of the loop instantly, regardless of how many iterations were originally planned.
- Lesson 258 — Basic switch syntax and casesLesson 259 — The role of the break statement in switchLesson 261 — Fall-through behavior: intentional and accidentalLesson 263 — Grouping multiple cases into one blockLesson 265 — Switch statement best practicesLesson 271 — Infinite loops: while(1) and while(true)Lesson 289 — Optional components: the for(;;) infinite loopLesson 290 — The break statement: exiting a loop earlyLesson 291 — The continue statement: skipping to the next iterationLesson 293 — Using break to exit infinite loops on conditionLesson 294 — Using continue to skip invalid data entriesLesson 295 — The performance impact of loop controlsLesson 296 — Readability: when to avoid excessive breaksLesson 297 — Alternative patterns to avoid break and continueLesson 305 — Breaking out of nested loops: the limitation of breakLesson 308 — Why goto is generally discouragedLesson 309 — Legitimate use case: breaking out of nested loopsLesson 404 — Linear search for a specific valueLesson 829 — Setting breakpoints with `break`
- break [function name]
- Use break [line number] or break [function name] to pause your program's execution at a specific spot for inspection.
- Lesson 829 — Setting breakpoints with `break`
- break [line number]
- Use break [line number] or break [function name] to pause your program's execution at a specific spot for inspection.
- Lesson 829 — Setting breakpoints with `break`
- break [location] if [condition]
- Use break [location] if [condition] to ignore irrelevant iterations and jump straight to the moment a bug occurs.
- Lesson 835 — Setting conditional breakpoints
- breakpoints
- When you are debugging a program in GDB, you often use breakpoints to freeze time.
- Lesson 829 — Setting breakpoints with `break`Lesson 831 — Continuing execution with `continue`
- brk
- The program break is the boundary of your heap, and brk/sbrk are the system-level tools used to push that boundary forward to claim more memory.
- Lesson 592 — Introduction to brk and sbrk
- brk(addr)
- This sets the "fence" to a specific, absolute address.
- Lesson 592 — Introduction to brk and sbrk
- broadcast
- But if the driver shouts "The bus is here, everyone get in line!", that’s a broadcast.
- Lesson 1135 — Broadcasting to all threads
- bsearch
- By providing a pointer to the key and a comparison rule, bsearch handles the logic of jumping through the memory, making your search lightning-fast without you having to write the complex "divide and conquer" logic yourself.
- Lesson 880 — Using `bsearch` on sorted arraysLesson 881 — Handling the `void*` return of `bsearch`Lesson 882 — Common pitfalls in comparison function logicLesson 1066 — Using C library 'bsearch' function
- bsearch()
- When you use bsearch() to find an item in an array, the function doesn't know what kind of data you are searching through.
- Lesson 881 — Handling the `void*` return of `bsearch`
- BSWAP
- The __builtin_bswap family of functions tells the CPU to use a specialized hardware instruction (like BSWAP on x86) to flip the bytes in a single clock cycle.
- Lesson 956 — The `__builtin_bswap` compiler intrinsics
- bt
- Use backtrace (or bt) in GDB to view the list of active function calls and trace the path your program took to reach its current state.
- Lesson 833 — Inspecting the call stack with `backtrace`Lesson 837 — Debugging a Segfault from a core dump
- Bubble Sort
- While algorithms like Bubble Sort and Insertion Sort are typically stable, Quick Sort is often unstable because it swaps elements over long distances.
- Lesson 1051 — In-place sorting vs extra memoryLesson 1052 — Stability in sorting algorithms
- bucket
- Instead of making the mailbox a tiny slot that only fits one envelope, we turn each mailbox into a bucket.
- Lesson 1034 — Implementing the bucket array
- buffer
- Both functions require three main ingredients: the socket file descriptor (the ID of your connection), a buffer (the actual data), and the length of that data.
- Lesson 749 — Full buffering vs Line bufferingLesson 750 — Unbuffered output (stderr)Lesson 751 — Forcing a write with fflushLesson 752 — Setting custom buffers with setvbufLesson 1092 — File descriptors vs FILE pointersLesson 1115 — Sending and receiving over sockets
- buffer overflow
- A buffer overflow happens when a pointer moves past the end of its assigned "buffer" (like an array) and starts writing data into memory it doesn't own.
- Lesson 422 — Scanning strings with `%s` and `scanf` limitationsLesson 431 — The danger of Buffer OverflowLesson 432 — Why `gets` is dangerous and deprecatedLesson 433 — Safe input reading with `fgets`Lesson 436 — Using `strncat` for safer concatenationLesson 437 — Checking bounds before array accessLesson 524 — Buffer overflows via pointersLesson 695 — Limiting string length in scanfLesson 699 — Why gets is dangerous and deprecatedLesson 704 — Safe string formatting with snprintfLesson 706 — The buffer size argument in fgetsLesson 848 — Copying strings safely with `strncpy`
- buffer[-1]
- Without the semaphores, the Consumer might try to access buffer[-1] because it didn't know the rack was empty, causing a segmentation fault.
- Lesson 1136 — The producer-consumer problem
- buffered
- By default, stdout (standard output) is buffered.
- Lesson 1158 — Flushing `stdout` for accurate logs
- BUFSIZ
- To use a custom buffer: Pass an array of a specific size (BUFSIZ).
- Lesson 753 — The setbuf shorthand
- Bump Allocator
- A Linear Allocator (also called a Bump Allocator) is like a tall stack of clean trays.
- Lesson 586 — Linear or Bump allocators
- busy-waiting
- In programming, this is called busy-waiting.
- Lesson 1132 — Introduction to condition variables
- but a
- If you ever find a 1 at [2][4] but a 0 at [4][2], your undirected graph is broken!
- Lesson 1043 — Adding edges in undirected graphs
- by
- If you divide 5 by 2, C gives you 2, throwing the .5 in the trash.
- Lesson 234 — Safety with explicit casts
- byte
- In standard C programming, the smallest unit of memory we can address is a byte.
- Lesson 448 — How variables are stored in RAMLesson 647 — Restrictions on bit-field typesLesson 652 — Limitations of bit-field addresses
- byte by byte
- It is vital to remember that memset works byte by byte.
- Lesson 855 — Setting memory blocks with `memset`
- bytes
- When you ask the computer for memory using functions like malloc, you can’t just say "give me enough room for an integer." The computer speaks in bytes.
- Lesson 84 — Using the `sizeof` operatorLesson 235 — The `sizeof` operator with typesLesson 388 — Calculating array size with `sizeof`Lesson 430 — Setting memory blocks with `memset`Lesson 538 — Calculating size with sizeofLesson 982 — Initial memory allocation with mallocLesson 1115 — Sending and receiving over sockets
C
- C _ A R T
- If you have the word "CHART" and want to remove the 'H', you can't just delete it; you would be left with C _ A R T.
- Lesson 444 — Removing a character from a string
- c = 10
- Instead of writing three separate lines, the "return value" of c = 10 is handed off to b, and so on.
- Lesson 197 — Assignment expression return value
- c = 50
- In the code above, the expression c = 50 happens first.
- Lesson 214 — Right-to-left associativity
- C:\msys64\ucrt64\bin
- Add the location where MinGW was installed (usually C:\msys64\ucrt64\bin).
- Lesson 11 — Setting up MinGW on Windows
- C:\Users\Bob\Documents
- Instead of hard-coding a folder path like C:\Users\Bob\Documents, you can ask the system for HOME.
- Lesson 1071 — Environment variables in C
- c11
- Common values include c89, c99, c11, and c17.
- Lesson 972 — Specifying the standard with `-std=` flags
- c17
- Common values include c89, c99, c11, and c17.
- Lesson 972 — Specifying the standard with `-std=` flags
- c89
- Common values include c89, c99, c11, and c17.
- Lesson 972 — Specifying the standard with `-std=` flags
- c99
- Common values include c89, c99, c11, and c17.
- Lesson 972 — Specifying the standard with `-std=` flags
- Cache
- Because RAM is relatively slow, the CPU pulls "chunks" of nearby memory into a high-speed storage area called the Cache.
- Lesson 1191 — The impact of Cache Locality
- Cake -> Frosting -> Butter
- This is a dependency chain: Cake -> Frosting -> Butter.
- Lesson 802 — Dependency graphing in your head
- calculate
- When you compile this code, the compiler sees the declaration and says, "Okay, I'll leave a placeholder here for calculate." However, once the compiler finishes, the Linker steps in to connect the placeholder to the actual logic.
- Lesson 70 — The 'undefined reference' linker errorLesson 348 — Pushing and popping framesLesson 805 — What is inside a `.o` file
- calculate_cubes
- If calculate_cubes takes up 70% of the total time, gprof will tell you exactly that.
- Lesson 1182 — Introduction to the `gprof` profiler
- calculate_discount
- By extracting calculate_discount, you can now write a separate "test script"—another small C program—that calls that function with dozens of different numbers (like negative prices or 100% discounts) to see if it breaks.
- Lesson 1175 — Separating logic from `main()` for testability
- calculate_gravity
- It essentially says, "I don't know where the calculate_gravity function is yet, but I trust the linker to find it later."
- Lesson 806 — Linking multiple object files
- calculate_log
- In the example above, calculate_log is where the error happened, but process_data is the function that provided the data.
- Lesson 833 — Inspecting the call stack with `backtrace`
- calculate_physics()
- Instead, it leaves a "placeholder" or a note that says, "When this program starts, go find the code for calculate_physics() in physics_lib.so."
- Lesson 813 — What is a shared library `.so` / `.dll`
- calculate_squares
- You now know that even if you make calculate_squares twice as fast, it will barely impact the overall speed because the "bottleneck" is in the cubes function.
- Lesson 1182 — Introduction to the `gprof` profiler
- calculate_tax
- If calculate_tax shows up as 92%, you’ve found your hot spot.
- Lesson 1183 — Identifying 'Hot Spots' in your code
- calculate_tax()
- In older versions of C, if you called a function named calculate_tax() before defining it, the compiler would shrug and say, "I'll assume this function exists somewhere and that it returns an integer." This is an implicit declaration.
- Lesson 329 — Implicit vs. explicit declarationsLesson 1172 — Principles of Unit Testing
- calculate_total
- The Typo: You named the function calculate_total in your header but accidentally wrote calculate_totals (with an 's') in your .c file.
- Lesson 530 — Stack frame lifecycle and local variablesLesson 807 — Understanding 'undefined reference' errorsLesson 809 — Symbol tables and visibility
- calculate_total()
- If another programmer working on billing.c also creates a function named calculate_total(), the compiler will throw a "duplicate symbol" error when it tries to link the files together.
- Lesson 798 — Static functions for file scopingLesson 809 — Symbol tables and visibility
- calculate_total(const int *prices)
- If you write a function to calculate_total(const int *prices), you are telling the world that this function is a "pure" observer.
- Lesson 1198 — The role of `const` in documentation
- calculate_totals
- The Typo: You named the function calculate_total in your header but accidentally wrote calculate_totals (with an 's') in your .c file.
- Lesson 807 — Understanding 'undefined reference' errors
- Calculate()
- This allows you to create "Generic Macros." You can create a single macro called calculate() that calls a math function for integers or a completely different one for floats, all while keeping your main code clean and readable.
- Lesson 70 — The 'undefined reference' linker errorLesson 348 — Pushing and popping framesLesson 973 — Introduction to the `_Generic` keyword
- calculateTax
- Like variable names, these should be descriptive verbs, like calculateTax or printHello.
- Lesson 323 — Anatomy of a function definition
- calculateTotal()
- This is why a variable created inside main() cannot be seen by a variable inside calculateTotal()—they exist on different parts of the workbench at different times.
- Lesson 149 — Memory segments: Stack vs. Data
- Calculation.C
- Bad: Calculation.C (Some systems treat .C as C++, which is a different language!).
- Lesson 16 — Naming conventions for .c files
- calculator.c
- In this example, main.c doesn't know how to add numbers (that logic lives in calculator.c), but it knows when to ask for the result.
- Lesson 799 — The role of the 'main' file
- calculator.h
- If you had a file named calculator.h, it might look like this:
- Lesson 788 — The purpose of header files
- Calibration
- If you decide to change the Calibration struct later—perhaps adding a "last_serviced" date—you only have to change the functions that directly handle the sensor.
- Lesson 674 — Information hiding using void pointers
- call before returning to
- Typing step (or just s) will jump the debugger into the greet() function, allowing you to walk through the printf call before returning to main.
- Lesson 830 — Stepping through code with `next` and `step`
- Call Stack
- In C, this is exactly how recursion works: the computer uses the Call Stack to remember where each function left off.
- Lesson 348 — Pushing and popping framesLesson 349 — Storage of local variablesLesson 350 — Return addresses in memoryLesson 351 — Visualizing the stack during nested callsLesson 352 — Identifying a Stack OverflowLesson 359 — The call stack in recursion
- calloc
- However, calloc is a lifesaver when you need a "fresh start," such as when creating a counter array or a frequency map where you need everything to start at zero to avoid math errors caused by leftover garbage data.
- Lesson 536 — Header file stdlib.h for allocationLesson 543 — Contiguous allocation with callocLesson 544 — Difference between malloc and callocLesson 545 — Zero-initialization overheadLesson 869 — Contiguous allocation with `calloc`Lesson 988 — Freeing the dynamic arrayLesson 1185 — Profiling memory allocation frequency
- calloc()
- However, we often prefer calloc(), which guarantees every single bit is set to zero.
- Lesson 545 — Zero-initialization overhead
- camelCase
- In C, the two most common styles are snake_case (all lowercase with underscores) and camelCase (capitalizing the first letter of each word except the first).
- Lesson 1197 — Meaningful variable naming conventions
- can_
- Booleans should be questions: If a variable is true or false, prefix it with is_, has_, or can_.
- Lesson 1197 — Meaningful variable naming conventions
- CAN_FLY
- If you OR your status with CAN_FLY, that specific bit flips to 1, regardless of what else is there.
- Lesson 189 — Using bitwise operators for flags
- cannot
- The first character: A name cannot start with a digit.
- Lesson 74 — Naming rules and identifiers
- cannot create an array of bit-fields
- Because you cannot take the address of a bit-field, you also cannot create an array of bit-fields.
- Lesson 647 — Restrictions on bit-field types
- capacity
- To do this, we track two values: the size (how many items are currently inside) and the capacity (how many items the memory can actually hold).
- Lesson 981 — Structure for dynamic arraysLesson 983 — Pushing elements and capacity checksLesson 984 — Geometric resizing with reallocLesson 1214 — Implementing a dynamic array for storage
- Car
- When you see Car myRide;, your brain immediately understands that Car is a custom type, without the distracting struct keyword reminding you of the underlying implementation details.
- Lesson 610 — Combining struct definition and typedefLesson 624 — Accessing members of nested structs
- Car myRide
- When you see Car myRide;, your brain immediately understands that Car is a custom type, without the distracting struct keyword reminding you of the underlying implementation details.
- Lesson 610 — Combining struct definition and typedef
- case
- Without a break, your program doesn't care that the next case label doesn't match your variable; it simply treats all subsequent code as one long list of instructions.
- Lesson 258 — Basic switch syntax and casesLesson 259 — The role of the break statement in switchLesson 260 — The default case for unhandled valuesLesson 261 — Fall-through behavior: intentional and accidentalLesson 263 — Grouping multiple cases into one blockLesson 265 — Switch statement best practicesLesson 517 — Arrays of function pointersLesson 665 — Using enums in switch statementsLesson 1151 — Handling the 'Default' case in switch statements
- case 1
- Readability: case RUNNING is instantly understandable, whereas case 1 is not.
- Lesson 668 — Using enums for state machines
- case 2
- If you forgot the break after case 2, the console would print "Preparing a Medium coffee" AND "Preparing a Large coffee." By including break, you ensure that the program performs only the specific task you intended.
- Lesson 259 — The role of the break statement in switch
- case PAUSED
- Clarity: Anyone reading your code knows exactly what case PAUSED means.
- Lesson 665 — Using enums in switch statements
- case RUNNING
- Readability: case RUNNING is instantly understandable, whereas case 1 is not.
- Lesson 668 — Using enums for state machines
- case-sensitive
- One important note: strcmp is case-sensitive.
- Lesson 426 — Comparing strings with `strcmp`
- Cashier
- You have a Baker (the Producer) and a Cashier (the Consumer).
- Lesson 1136 — The producer-consumer problem
- cast
- Before you can use the data, you must cast it back to its original type.
- Lesson 507 — The `void *` generic typeLesson 509 — Casting `void *` to specific types
- cast operator
- The cast operator is a set of parentheses containing a data type name, placed directly before a value or variable.
- Lesson 230 — The `(type)` cast operator
- CC
- Here is a Makefile that uses variables for the compiler (CC), the compiler flags (CFLAGS), and the final executable name (TARGET).
- Lesson 821 — Using variables in Makefiles
- ceil
- Even if you have 5.01, ceil will push it up to 6.0.
- Lesson 864 — Rounding with `ceil`, `floor`, and `round`
- ceil()
- If a user buys 2.1 containers of flour, you can't ship a partial container, so you use ceil() to charge them for 3.
- Lesson 864 — Rounding with `ceil`, `floor`, and `round`
- CFLAGS
- Here is a Makefile that uses variables for the compiler (CC), the compiler flags (CFLAGS), and the final executable name (TARGET).
- Lesson 821 — Using variables in Makefiles
- ch
- First, it assigns the result of getchar() to our variable ch.
- Lesson 682 — Using while loops with getchar
- chained assignment
- However, C allows a shortcut called chained assignment.
- Lesson 196 — Chained assignments `a = b = c`
- Chaining
- Chaining solves this by turning every mailbox into a "hook" for a linked list.
- Lesson 1033 — Handling collisions with Chaining
- char
- If you add two char variables together, C doesn't perform "char math." Instead, it takes the value of the first char, converts it to an int, does the same for the second, and then adds the two int values together.
- Lesson 51 — Printing characters with `%c`Lesson 89 — The `signed` keywordLesson 105 — The `char` typeLesson 106 — Characters as small integersLesson 107 — Single quotes vs. double quotesLesson 109 — The ASCII encoding schemeLesson 110 — Arithmetic with charactersLesson 111 — Signed vs. Unsigned charsLesson 112 — Printing chars with `%c`Lesson 121 — What is type promotion?Lesson 122 — Integer promotion rulesLesson 126 — The 'Usual Arithmetic Conversions'Lesson 131 — Casting between char and intLesson 132 — Safe downcasting techniquesLesson 155 — The modulo operator `%` with integersLesson 157 — Basic arithmetic overflowLesson 178 — Bitwise NOT `~` (Complement)Lesson 179 — Understanding binary representationLesson 183 — Left shift `<<` mechanicsLesson 228 — Implicit promotion to `int`Lesson 229 — Usual arithmetic conversionsLesson 231 — Truncation during castingLesson 233 — Promotion of `char` and `short`Lesson 235 — The `sizeof` operator with typesLesson 262 — Switch restrictions: integral types onlyLesson 324 — The `void` return typeLesson 332 — Matching prototypes with definitionsLesson 383 — Declaring an array with `type name[size]`Lesson 415 — Declaring arrays of type `char`Lesson 418 — Difference between `'a'` and `"a"`Lesson 430 — Setting memory blocks with `memset`Lesson 447 — Memory as a linear sequence of bytesLesson 452 — The size of a pointer variableLesson 453 — Determining variable alignment in memoryLesson 455 — Declaring pointer variables with `*`Lesson 456 — The difference between `int *p` and `*p`Lesson 461 — Implicit vs explicit pointer typesLesson 463 — Incrementing pointers with `++`Lesson 468 — Scaling factor in pointer mathLesson 472 — Accessing arrays with pointer notationLesson 479 — String literals as `char` pointersLesson 512 — The `memcpy` function signatureLesson 573 — Struct padding for alignmentLesson 576 — The aligned_alloc functionLesson 577 — Using __attribute__((packed))Lesson 589 — Handling alignment within an arenaLesson 599 — Defining a struct with the struct keywordLesson 609 — Creating a shorthand for struct namesLesson 630 — Declaring an array of structsLesson 637 — The sizeof operator on structs
- char *
- In C, if you try to modify a string literal—for example, by writing message[0] = 'J';—your program will likely crash with a "Segmentation Fault." The compiler won't always warn you about this danger because char * looks like any other pointer that is allowed to change data.
- Lesson 461 — Implicit vs explicit pointer typesLesson 479 — String literals as `char` pointersLesson 480 — Mutable vs immutable string memoryLesson 485 — Using `const char *` for safetyLesson 506 — Command line arguments `char **argv`Lesson 507 — The `void *` generic typeLesson 510 — Implicit conversion to `void *`Lesson 878 — Writing a string comparison function for `qsort`
- char *message = "Hello"
- When you write a line like char *message = "Hello";, you are pointing a variable at a piece of text stored in a "read-only" section of your computer's memory.
- Lesson 479 — String literals as `char` pointersLesson 485 — Using `const char *` for safety
- char *myMessage
- The Setup: char *myMessage is a box that holds a memory address.
- Lesson 503 — Modifying a pointer inside a function
- char *myPtr
- When we declare a pointer like int myPtr or char myPtr, we are being explicit.
- Lesson 461 — Implicit vs explicit pointer types
- char *myPtr = "Alice"
- However, when you create a string pointer like char *myPtr = "Alice";, the behavior changes.
- Lesson 484 — Memory layout of string pointers
- char *myStr = "Hello"
- When you declare a string using a pointer, like char *myStr = "Hello";, something different happens.
- Lesson 480 — Mutable vs immutable string memory
- char *names[]
- The array of pointers (often called an "array of strings") is declared using char *names[].
- Lesson 483 — Array of strings vs 2D char array
- char a
- It leaves a 3-byte gap after char a so that b stays aligned.
- Lesson 571 — CPU word size and alignment
- char argv
- By using char argv, C gives you a flexible way to handle any number of words of any length without knowing how many there will be until the program actually starts.
- Lesson 506 — Command line arguments `char **argv`
- char buffer[100]
- By explicitly setting a size larger than your text (like char buffer[100]), you create a "safety zone." You can put a short word in a big box, but you can never put a big word in a small box.
- Lesson 419 — Initializing strings with sizes
- char buffer[1024]
- In previous lessons, we built arenas using a fixed-size array (like char buffer[1024]).
- Lesson 590 — Growing an arena with virtual memory
- char message[20]
- When you declare char message[20], the computer sets aside exactly 20 bytes of memory.
- Lesson 415 — Declaring arrays of type `char`
- char myName[] = "Alice"
- In C, when you create a string using an array like char myName[] = "Alice";, you are building a house.
- Lesson 484 — Memory layout of string pointers
- char myStr[] = "Hello"
- When you declare a string as an array, like char myStr[] = "Hello";, C treats it as a local variable.
- Lesson 480 — Mutable vs immutable string memory
- char myString[20]
- If you declare char myString[20];, the size is 20.
- Lesson 420 — Length vs Size of a string array
- char name[10]
- When you initialize a string with a specific size, like char name[10], you are essentially building a row of lockers.
- Lesson 419 — Initializing strings with sizes
- char name[20]
- Up until now, you have used variables like int x or char name[20].
- Lesson 868 — Allocating memory with `malloc` and `free`
- char name[50]
- You might wonder why we use char name[50] instead of a flexible pointer.
- Lesson 1213 — Defining the Record struct
- char names[5][20]
- In C, it looks like this: char names[5][20];.
- Lesson 483 — Array of strings vs 2D char array
- char str1[] = "Hello"
- If you have char str1[] = "Hello"; and char str2[10];, writing str2 = str1; will cause a compiler error.
- Lesson 424 — Copying strings with `strcpy`
- char str2[10]
- If you have char str1[] = "Hello"; and char str2[10];, writing str2 = str1; will cause a compiler error.
- Lesson 424 — Copying strings with `strcpy`
- char temp[size]
- By using char temp[size], we create a workspace just big enough for the data, regardless of whether it’s a tiny character or a massive structure.
- Lesson 511 — Generic functions in C
- CHAR_BIT
- Think of CHAR_BIT as a label on a container; instead of guessing how much the container holds, you simply read the label provided by the manufacturer (the compiler).
- Lesson 96 — The `<limits.h>` header fileLesson 906 — Platform-specific character sizesLesson 942 — Limits of `limits.h` and `stdint.h`
- CHAR_MIN
- Instead of wondering if a char is signed or unsigned by default, you can check CHAR_MIN.
- Lesson 904 — Integer ranges in `limits.h`
- char[]
- If you need to change the content of your string during the program, always use the array syntax (char[]).
- Lesson 480 — Mutable vs immutable string memory
- char[5]
- If you try to cram a 5-letter word into a char[5] array, there is no room left for the \0 terminator.
- Lesson 419 — Initializing strings with sizes
- char*
- If you truly need to look at the raw bits of a variable (for example, to send them over a network), the only safe way is to use a pointer to a character type (char or unsigned char) or the memcpy function.
- Lesson 527 — Pointer type-punning dangersLesson 951 — Checking system endianness at runtimeLesson 975 — Implementing a generic 'Print' macroLesson 976 — Handling the `default` case in `_Generic`Lesson 980 — Limitations of C generics
- characters
- strlen tells you how many characters are currently inside that space.
- Lesson 847 — Finding string length with `strlen`
- charactersPrinted
- Then, it hands the number 14 to the variable charactersPrinted.
- Lesson 691 — The return value of printf
- charPtr
- However, because charPtr is explicitly typed as a char, it only looks at a tiny slice of the data.
- Lesson 461 — Implicit vs explicit pointer types
- chars
- By putting the int first and the chars at the end, the compiler can often pack them more tightly.
- Lesson 640 — Structure holes and performance
- check_system_health()
- But if you are inside a function called check_system_health() (which is called by main()), a return would only take you back to main().
- Lesson 313 — Exiting the program with exit()
- chef in the kitchen
- The Source file (.c) is the chef in the kitchen.
- Lesson 796 — Splitting code into `.c` and `.h`
- child
- This new process (the child) gets a copy of the original process's (the parent) variables, file descriptors, and code.
- Lesson 1075 — Process duplication and copy-on-write
- chmod
- It requires two arguments: the path where the pipe should live and the file permissions (similar to chmod).
- Lesson 1107 — Creating FIFOs with mkfifo()
- chmod +x test.sh
- To run this, you would give the script permission with chmod +x test.sh and then type ./test.sh.
- Lesson 1178 — Automating tests with a Shell script
- choice
- In this example, using a regular while loop would be clunky because you’d have to initialize choice to a "dummy" value just to get past the first check.
- Lesson 275 — Guaranteed execution: why do-while is differentLesson 276 — Using do-while for menu-driven programsLesson 279 — Comparing while vs do-while use cases
- Cinnamon
- You might have one jar labeled Cinnamon and another labeled Salt.
- Lesson 667 — Type safety concerns with enums
- Circle
- We have a Point (x, y), and a Circle that uses a Point to define its center.
- Lesson 625 — Initializing nested structures
- circular dependency
- In C, a circular dependency happens when file_a.h contains #include "file_b.h", but file_b.h also contains #include "file_a.h".
- Lesson 794 — Circular dependency issues
- clang
- To bridge the gap between your text file and a running program, you use a tool called a compiler (like gcc or clang).
- Lesson 6 — C as a compiled languageLesson 30 — Creating an executable binaryLesson 821 — Using variables in Makefiles
- clang-format
- clang-format is a command-line tool that reads your C files and automatically reformats them according to a specific style guide (like Google, LLVM, or Microsoft).
- Lesson 1201 — Using `clang-format` for automation
- clang-format -i main.c
- By running a simple command like clang-format -i main.c, the tool automatically rewrites the file to look like this:
- Lesson 1201 — Using `clang-format` for automation
- classList[i].id
- When you access classList[i].id, you are telling C: "Go to the $i$-th folder in the cabinet, open it, and look at the ID written inside."
- Lesson 636 — Searching through struct arrays
- classroom
- You cannot write classroom.grade[1], because classroom is the name of the entire array, and the array itself doesn't have a member named "grade"—only the individual structures inside it do.
- Lesson 630 — Declaring an array of structsLesson 633 — Combining array indexing and member access
- classroom.grade[1]
- You cannot write classroom.grade[1], because classroom is the name of the entire array, and the array itself doesn't have a member named "grade"—only the individual structures inside it do.
- Lesson 633 — Combining array indexing and member access
- classroom[0]
- Each element in the array (classroom[0], classroom[1], etc.) is a complete structure with its own name, id, and gpa.
- Lesson 630 — Declaring an array of structs
- classroom[1]
- Each element in the array (classroom[0], classroom[1], etc.) is a complete structure with its own name, id, and gpa.
- Lesson 630 — Declaring an array of structsLesson 633 — Combining array indexing and member access
- clean
- When you type make clean to sweep away your old .o files, make will look at that file and say: "clean is up to date." It won't run your cleanup commands because it thinks the "job" of creating a file named clean is already finished.
- Lesson 823 — Phony targets like `clean` and `all`
- clean_up()
- Safety: You can reuse common names like setup() or clean_up() in every single file of your project without them ever bumping into each other.
- Lesson 798 — Static functions for file scoping
- cleanup
- Most C programmers only tolerate goto in one specific scenario: cleanup.
- Lesson 308 — Why goto is generally discouraged
- clearerr
- If you detect an error using ferror, handle the problem (like asking the user to plug a USB drive back in), you must call clearerr before the stream will let you work with it again.
- Lesson 744 — Clearing file error indicators with clearerr
- client_fd
- You can keep the client_fd in a list of active customers while your main loop goes back to accept() on the server_fd to wait for the next person in line.
- Lesson 1113 — Accepting client connections
- clock_gettime()
- What you'll learn: How to use the Linux-standard clock_gettime() function to measure code execution speed with nanosecond precision.
- Lesson 1181 — Precise timing with `clock_gettime()`
- CLOCK_MONOTONIC
- Use clock_gettime() with CLOCK_MONOTONIC to capture execution times down to the nanosecond for accurate performance profiling.
- Lesson 1181 — Precise timing with `clock_gettime()`
- CLOCK_REALTIME
- Unlike CLOCK_REALTIME (which tracks the actual time of day), a monotonic clock is a simple counter that never goes backward.
- Lesson 1181 — Precise timing with `clock_gettime()`
- clock_t
- The clock() function returns a value of type clock_t.
- Lesson 896 — Measuring CPU ticks with `clock`
- clock()
- In C, we use clock() from the <time.h> library to measure "CPU time." Think of this as a specialized stopwatch that only ticks when the processor is actually working on your specific instructions.
- Lesson 896 — Measuring CPU ticks with `clock`Lesson 1180 — Measuring execution time with `clock()`Lesson 1184 — Understanding CPU cycles vs. Wall time
- CLOCKS_PER_SEC
- However, because different computers process ticks at different speeds, we divide that number by a constant called CLOCKS_PER_SEC to convert those abstract ticks into human-readable seconds.
- Lesson 896 — Measuring CPU ticks with `clock`Lesson 1180 — Measuring execution time with `clock()`
- Clockwise/Spiral Rule
- To solve this, programmers use a mental trick called the Clockwise/Spiral Rule.
- Lesson 498 — The 'Clockwise/Spiral' rule for declarations
- Close-on-Exec
- Instead of manually closing every file before calling exec(), you can tag a file descriptor with the Close-on-Exec flag.
- Lesson 1096 — The close-on-exec flag
- coffee_cups > 0
- In the example above, the loop checks the condition coffee_cups > 0.
- Lesson 267 — The loop condition: when to stop
- col
- The break successfully stopped the col loop for row 2, but the row loop kept right on ticking.
- Lesson 305 — Breaking out of nested loops: the limitation of break
- collision
- This is called a collision, and while the modular function is a great start, handling those overlaps is the next step in mastering hash tables.
- Lesson 1032 — A simple modular hash functionLesson 1033 — Handling collisions with ChainingLesson 1035 — Hash table insertion
- color
- If you accidentally pass a Color enum into a function expecting a Direction enum, C will treat them both as integers and run the code.
- Lesson 337 — Positional matching of argumentsLesson 667 — Type safety concerns with enums
- Color.Red
- You can have a Color.Red and a Alert.Red without any issues.
- Lesson 666 — Scoped enum limitations in C
- colSum
- By declaring rowSum or colSum inside the outer loop, you ensure each line starts with a clean slate.
- Lesson 413 — Summing rows and columns individually
- column
- The first set of brackets selects the row, and the second set selects the column.
- Lesson 410 — Accessing elements using `[row][col]`
- Columns
- In programming terms, we call these Rows and Columns.
- Lesson 407 — Declaring 2D arrays: Rows and Columns
- comma operator
- Instead of cluttering the body of your loop with extra manual increments, C allows you to use the comma operator to pack multiple expressions into the initialization and increment sections of the loop header.
- Lesson 240 — The comma operator in `for` loopsLesson 288 — The comma operator in for loop headers
- command
- In the example above, if command is 'Q', the program enters at the first case.
- Lesson 261 — Fall-through behavior: intentional and accidental
- Command Line Interface (CLI)
- Programming in C, however, requires you to step into the pilot’s cockpit: the Command Line Interface (CLI).
- Lesson 12 — Introduction to the CLI
- Commands
- It uses a specific syntax of Targets, Dependencies, and Commands.
- Lesson 61 — Introduction to `make` and Makefiles
- commas
- When you declare multiple variables on one line, you state the data type once, followed by your chosen names separated by commas, and ending with a single semicolon.
- Lesson 76 — Multiple declarations in one line
- commenting out code
- In C programming, commenting out code is exactly like that.
- Lesson 38 — Commenting out code for testing
- commit
- When you finish with your first table and need more space, you ask the librarian to commit the next table by turning on the lights.
- Lesson 590 — Growing an arena with virtual memory
- company.department.employee.salary
- You can chain these as deeply as you need (e.g., company.department.employee.salary).
- Lesson 624 — Accessing members of nested structs
- compar
- compar: This is the "callback." Since qsort can't compare your data using < or >, you must provide a pointer to a function that takes two items and returns an integer indicating which is "larger."
- Lesson 876 — The generic signature of `qsort`
- Comparator
- To make it work, you must provide a Comparator.
- Lesson 1060 — Writing a custom comparator for qsort
- compare
- A double equals sign (==) is used to compare two values (e.g., "is the number in this box equal to 5?").
- Lesson 71 — Common beginner typosLesson 165 — Common pitfall: `=` vs `==`
- Compare and Swap (CAS)
- Compare and Swap (CAS) is a "lock-free" alternative built directly into the CPU hardware.
- Lesson 1145 — Compare and swap (CAS) basics
- compare_ints
- By changing just the logic inside compare_ints (for example, returning val2 - val1), you can flip the entire sorting order to descending without ever touching the complex sorting algorithm itself.
- Lesson 519 — The `qsort` callback mechanism
- Compare-and-Swap (CAS)
- The most common is Compare-and-Swap (CAS).
- Lesson 1146 — Lock-free programming concepts
- comparison and swap
- In C, we call this a comparison and swap.
- Lesson 1047 — Bubble Sort: The swap logic
- comparison function
- It handles the complex logic of sorting, but it requires you to provide a comparison function.
- Lesson 877 — Writing an integer comparison functionLesson 1059 — Using C library 'qsort' function
- Compilation
- There is a crucial middle step: Compilation.
- Lesson 803 — From source code to object files
- compilation speed
- Second, compilation speed: if you change the logic inside one .c file, the compiler usually only needs to reprocess that specific file, rather than your entire project.
- Lesson 796 — Splitting code into `.c` and `.h`
- compile-time
- The "static" part of the name means the connection happens at compile-time.
- Lesson 810 — What is a static library `.a`
- compiled file
- The timestamp of your compiled file (main.o or the final app).
- Lesson 824 — Incremental builds and file timestamps
- compiled language
- C is a compiled language, which means it acts as a bridge between these two worlds.
- Lesson 6 — C as a compiled language
- compiler
- The Compiler is like a factory that creates specific components: one factory makes the windows, another makes the doors, and a third makes the roof.
- Lesson 4 — Standards: ANSI C vs C99 vs C11Lesson 8 — Hardware abstraction in CLesson 10 — Installing GCC on Linux/macOSLesson 12 — Introduction to the CLILesson 14 — Verifying your installationLesson 28 — Phase 4: The LinkerLesson 30 — Creating an executable binaryLesson 807 — Understanding 'undefined reference' errors
- compiler intrinsics
- Think of compiler intrinsics as the "middle ground." They look and act like regular C functions, but the compiler treats them as special commands.
- Lesson 964 — Compiler intrinsics as an alternative
- compiling
- Building a C program is usually a two-step dance: compiling (translating code into machine language) and linking (stitching those translations into a final app).
- Lesson 804 — The `-c` flag for compilation
- complex_calculation
- If we had put complex_calculation inside the lock, every other thread would be forced to wait 100ms per turn, destroying the benefits of using threads in the first place.
- Lesson 1127 — Critical section best practices
- compound bitwise assignment operators
- Just like you can use += as a shortcut for addition, C provides compound bitwise assignment operators.
- Lesson 195 — Compound bitwise assignments
- compute
- Instead of writing separate functions for add_and_print and multiply_and_print, we write one compute function that accepts a "math rule" as an argument.
- Lesson 518 — Passing functions as arguments
- condition
- When a programmer looks at a while or for loop, the first place they look to understand the logic is the condition inside the parentheses.
- Lesson 268 — Updating the loop variable to avoid infinite loopsLesson 296 — Readability: when to avoid excessive breaksLesson 405 — Avoiding off-by-one errors in loops
- condition ? result_a : result_b
- When the compiler sees condition ? result_a : result_b, it decides the "shape" of the answer before the program even runs.
- Lesson 209 — Type consistency in ternary branches
- condition ? true : false
- In the previous lesson, we learned that a basic ternary operator (condition ? true : false) is like a simple fork in the road.
- Lesson 208 — Nesting ternary operators
- condition ? value_if_true : value_if_false
- condition ? value_if_true : value_if_false;
- Lesson 206 — Syntax of `? :`Lesson 252 — The ternary operator (?:) as a shortcut
- Condition Check (True/False)
- To trace a loop, draw three columns: Iteration Number, Variable Values, and Condition Check (True/False).
- Lesson 273 — Tracing while loop execution on paper
- Condition Variable (CV)
- A Condition Variable (CV) is the solution.
- Lesson 1132 — Introduction to condition variables
- Condition Variables
- Instead of a loop that constantly checks a variable, we use Condition Variables.
- Lesson 1133 — Waiting with pthread_cond_wait
- conditional breakpoint
- A conditional breakpoint allows you to stay hands-off until a specific logical condition is met, such as i == 500 or error_code != 0.
- Lesson 835 — Setting conditional breakpoints
- Conditional Compilation
- Instead of writing separate programs for every OS, you can use conditional compilation to tell the compiler: "If this is a Windows machine, use this code; otherwise, use that code."
- Lesson 780 — Using `#ifdef` and `#ifndef`Lesson 783 — Testing for platform-specific code
- configuration
- Variables separate the configuration of your build from the logic of your build.
- Lesson 821 — Using variables in Makefiles
- connect()
- In the networking world, this initiates the "TCP Three-Way Handshake." It’s a polite exchange where your computer says "Hello," the server says "Hello back, ready?", and your computer says "Great, let’s talk." Once connect() returns successfully, the virtual circuit is open.
- Lesson 1109 — The sockaddr_in structureLesson 1114 — Client-side connect()
- const
- Self-documenting code: When another programmer (or your future self) reads your function signature, the const keyword immediately tells them: "This function is safe to use; it won't mess with my original data."
- Lesson 113 — The `const` qualifierLesson 114 — Why use constants?Lesson 116 — Macros vs. Const variablesLesson 117 — Naming conventions for constantsLesson 118 — Literal vs. Symbolic constantsLesson 398 — Constant arrays with the `const` qualifierLesson 485 — Using `const char *` for safetyLesson 493 — Pointer to a constant (`const int *p`)Lesson 494 — Constant pointer to a value (`int * const p`)Lesson 495 — Constant pointer to a constantLesson 496 — When to use `const` with pointersLesson 497 — Read-only function parametersLesson 498 — The 'Clockwise/Spiral' rule for declarationsLesson 499 — Casting away `const` volatilityLesson 512 — The `memcpy` function signatureLesson 910 — The `const` qualifier on variablesLesson 911 — Difference between `const int *` and `int * const`Lesson 912 — Using `const` in function parametersLesson 917 — Combining `const` and `volatile`Lesson 1198 — The role of `const` in documentation
- const char *
- You should use const char * every time you point to a string literal (text inside double quotes) or when you write a function that needs to read a string without changing it.
- Lesson 485 — Using `const char *` for safety
- const int
- Unlike a collection of const int variables, an enum groups related constants together logically.
- Lesson 116 — Macros vs. Const variablesLesson 664 — Enums vs constant integers
- const int *
- Use const int * when passing a large array or structure to a function if you want to ensure the function doesn't accidentally modify your original data.
- Lesson 493 — Pointer to a constant (`const int *p`)Lesson 911 — Difference between `const int *` and `int * const`
- const int * const ptr
- Constant Pointer to Constant Data (const int const ptr)*
- Lesson 496 — When to use `const` with pointers
- const int *p
- A const int *p lets you read the value it points to, but prevents you from modifying that value through the pointer.
- Lesson 493 — Pointer to a constant (`const int *p`)
- const int *ptr
- Pointer to Constant Data (const int ptr)*
- Lesson 496 — When to use `const` with pointers
- const int RED = 0
- Even if you use const int RED = 0;, the compiler still views that variable as just another number.
- Lesson 664 — Enums vs constant integers
- const int x = 10
- If the variable was originally declared as const int x = 10;, the computer might store it in a read-only hardware segment.
- Lesson 499 — Casting away `const` volatility
- const type * const name
- A const type * const name declaration creates a dual-layer lock, ensuring neither the data nor the pointer's destination can ever be modified.
- Lesson 495 — Constant pointer to a constant
- const void *
- It takes two const void * pointers (which basically mean "pointers to something, I don't know what") and returns an integer:
- Lesson 519 — The `qsort` callback mechanism
- const void *a
- You'll notice the comparison function uses const void *a.
- Lesson 1059 — Using C library 'qsort' function
- const void *src
- const void src*: This is the source address.
- Lesson 512 — The `memcpy` function signature
- const volatile
- const volatile creates a read-only variable that the compiler is forced to re-examine every time it is accessed because an external source (like hardware) can change it.
- Lesson 917 — Combining `const` and `volatile`
- constant pointer
- However, there is one small catch: while a pointer is a variable that can be changed to point elsewhere, an array name is a constant pointer.
- Lesson 471 — Array names as constant pointersLesson 476 — Pointer to the start of an arrayLesson 494 — Constant pointer to a value (`int * const p`)
- constant pointer to a constant
- This is a constant pointer to a constant.
- Lesson 495 — Constant pointer to a constant
- constants
- It defines a list of constants (names that represent fixed numbers) that tell you the minimum and maximum values for every integer type.
- Lesson 96 — The `<limits.h>` header file
- constants.h
- If physics.c includes constants.h, and graphics.c includes constants.h, and then main.c includes both physics.h and graphics.h, the contents of constants.h will be pasted into your main file multiple times.
- Lesson 789 — The 'duplicate definition' errorLesson 802 — Dependency graphing in your head
- Contact Name
- Think of it like a Contact Name in your phone.
- Lesson 614 — Improving code readability with typedef
- container
- Think of it this way: you use a semicolon at the end of an action, but not at the end of a heading or a container.
- Lesson 22 — Semicolons as statement terminators
- content
- Each mailbox has two important parts: the content inside it (the mail) and a unique address painted on the outside (like 123 Main St).
- Lesson 449 — The Address-of operator `&`
- contiguous
- An array is a contiguous block of memory where elements are stored in a single, unbroken sequence.
- Lesson 384 — Visualizing memory layout of arraysLesson 389 — The relationship between array size and memoryLesson 582 — Internal vs External fragmentationLesson 672 — Flexible array members in C99
- contiguous allocation
- calloc (short for contiguous allocation) is the more polite sibling.
- Lesson 869 — Contiguous allocation with `calloc`
- continue
- Moving Between Breakpoints: If you have a bug at the start of your code and another at the end, you can fix your focus on the first, then continue to jump immediately to the second point of interest without manually navigating every line in between.
- Lesson 291 — The continue statement: skipping to the next iterationLesson 292 — Continue in while vs for loopsLesson 294 — Using continue to skip invalid data entriesLesson 295 — The performance impact of loop controlsLesson 297 — Alternative patterns to avoid break and continueLesson 308 — Why goto is generally discouragedLesson 831 — Continuing execution with `continue`Lesson 835 — Setting conditional breakpointsLesson 836 — Using `watch` for memory changes
- converts any non-zero number into
- The first ! converts any non-zero number into 0.
- Lesson 174 — Operator `!` and boolean normalization
- cookie_jar_locked
- Corruption: You accidentally change the value of other variables (like the cookie_jar_locked flag above).
- Lesson 431 — The danger of Buffer Overflow
- cookies
- In the example above, *ptr = 25 doesn't change the address stored in the pointer; it reaches through the pointer and changes the cookies variable to 25.
- Lesson 123 — Hierarchy of types in expressionsLesson 126 — The 'Usual Arithmetic Conversions'Lesson 198 — Prefix increment `++x`Lesson 201 — Postfix decrement `x--`Lesson 220 — Definition of a side effectLesson 222 — Sequence points at `;`Lesson 238 — The Indirection operator `*`
- cookies++
- In the example above, cookies++ has the side effect of adding one to the variable.
- Lesson 222 — Sequence points at `;`
- cookiesInJar
- If the condition is false right at the start (for example, if cookiesInJar was already 0), the code inside the loop will never execute at all.
- Lesson 269 — Using while for indeterminate iterations
- coordinate and a
- If you are building a game, you might need an x coordinate and a y coordinate.
- Lesson 76 — Multiple declarations in one line
- copies
- When you then call fork(), the child process inherits copies of both.
- Lesson 1103 — Closing unused pipe ends
- copy
- In C, when you pass a variable to a function, it is like walking over to a photocopy machine, making a copy of your paper, and handing your friend the copy.
- Lesson 344 — Visualizing the stack frame copyLesson 346 — Preparing for pass by referenceLesson 487 — Passing addresses to functionsLesson 488 — Modifying caller variables
- Copy-on-Write (COW)
- To solve this, Linux and Unix systems use a clever optimization called Copy-on-Write (COW).
- Lesson 1075 — Process duplication and copy-on-write
- copyOfNum
- Because parameters are allocated their own unique space in memory, the function’s internal logic is "sandboxed." Even if the function reassigns a value to copyOfNum, it is only flipping bits in its own temporary workspace.
- Lesson 342 — Memory allocation for parameters
- core
- This creates a file (often named core or something similar).
- Lesson 837 — Debugging a Segfault from a core dump
- Core Dump
- A Core Dump is like a high-resolution photo of the crime scene.
- Lesson 837 — Debugging a Segfault from a core dump
- cos
- What you'll learn: How to use the sin, cos, and tan functions from the math library and why you must convert degrees to radians first.
- Lesson 863 — Trigonometric functions in radians
- cos()
- C's trigonometric functions require angles in radians, so always multiply degrees by (PI / 180.0) before passing them to sin(), cos(), or tan().
- Lesson 863 — Trigonometric functions in radians
- count
- By passing the last known fixed argument (like count in the example above) to va_start, you are telling C: "Look at the memory address of this variable, skip over it, and start reading right after that." Without at least one fixed argument to act as a lighthouse, va_list would be lost at sea.
- Lesson 145 — Persisting data between function callsLesson 273 — Tracing while loop execution on paperLesson 274 — The do-while syntax and the trailing semicolonLesson 317 — The Counter pattern (counting occurrences)Lesson 371 — Functions with unknown argumentsLesson 373 — Using `va_list` and `va_start`Lesson 727 — The size and count parametersLesson 801 — Naming conventions for large projectsLesson 920 — The `static` keyword inside functionsLesson 1136 — The producer-consumer problemLesson 1140 — The need for atomic operations
- count != 0
- When the if statement runs, it checks the first part: count != 0.
- Lesson 253 — Short-circuit evaluation in logical AND
- count = count + 1
- If you accidentally wrote count = count + 1, your paper trace would quickly show the number getting larger and larger, alerting you to an "infinite loop" before you even touch your keyboard.
- Lesson 268 — Updating the loop variable to avoid infinite loopsLesson 273 — Tracing while loop execution on paper
- count == capacity
- When count == capacity, we are out of room.
- Lesson 1214 — Implementing a dynamic array for storage
- count: %d
- Printing just %d is confusing if you have five different variables; printing count: %d tells you exactly what you are looking at.
- Lesson 1163 — Inspecting variable values at runtime
- count(2)
- It hasn't finished yet; it's waiting for count(2) to finish.
- Lesson 359 — The call stack in recursion
- count(3)
- When count(3) is called, a frame for n=3 is pushed onto the stack.
- Lesson 359 — The call stack in recursion
- count++
- In C, a standard integer operation like count++ isn't actually one step; the CPU must read the value, modify it, and write it back.
- Lesson 268 — Updating the loop variable to avoid infinite loopsLesson 1140 — The need for atomic operationsLesson 1141 — Introduction to <stdatomic.h>Lesson 1147 — Volatile vs Atomic
- countDown
- Observe how this countDown function tracks its own progress:
- Lesson 363 — Visualizing recursive depth
- countdown = countdown - 1
- Decrementing: countdown = countdown - 1;
- Lesson 268 — Updating the loop variable to avoid infinite loops
- counter
- While the computer doesn’t care if you call a variable counter or q, your future self and your teammates definitely do.
- Lesson 148 — Default initialization of static variablesLesson 320 — Floating point precision issues in loop conditionsLesson 1197 — Meaningful variable naming conventions
- counter != 1.0
- Since the condition counter != 1.0 remains true, the loop never stops.
- Lesson 320 — Floating point precision issues in loop conditions
- Counter pattern
- In C programming, the Counter pattern works exactly like that handheld clicker.
- Lesson 317 — The Counter pattern (counting occurrences)
- counter variable
- A counter variable initialized to 0 (this is your clicker).
- Lesson 317 — The Counter pattern (counting occurrences)
- counter++
- In standard C, counter++ actually performs three steps: load the value, add one, and store it back.
- Lesson 1124 — Understanding race conditionsLesson 1144 — Atomic fetch and addLesson 1145 — Compare and swap (CAS) basics
- Countertop
- If you need a "Secret Sauce" you just made, you look on your Countertop (the Current Directory) first.
- Lesson 795 — Standard header search paths
- CPU time
- One thing to keep in mind: clock() measures CPU time.
- Lesson 1180 — Measuring execution time with `clock()`
- cpu_time_used
- If you put a sleep(5) command in the middle of that code, the Wall Time would increase by five seconds, but the cpu_time_used would remain almost exactly the same.
- Lesson 1184 — Understanding CPU cycles vs. Wall time
- createGraph
- Always ensure that every malloc used during your addEdge or createGraph functions has a corresponding free in your cleanup logic.
- Lesson 1046 — Graph memory management
- Critical Section
- The code between these two functions is called the Critical Section.
- Lesson 1126 — Locking and unlocking mutexes
- Ctrl + Z
- On Windows, press Ctrl + Z and then hit Enter.
- Lesson 270 — Reading input until EOF with while
- Ctrl+C
- They are short messages sent to a running program to tell it something happened—like the user pressing Ctrl+C to quit, or a hardware error occurring.
- Lesson 289 — Optional components: the for(;;) infinite loopLesson 831 — Continuing execution with `continue`Lesson 1084 — What are Unix signalsLesson 1085 — Common signals: SIGINT, SIGTERM, SIGKILLLesson 1087 — Basic signal handling with signal()
- Ctrl+D
- To leave the debugger and return to your normal terminal, type quit or press Ctrl+D.
- Lesson 826 — Starting GDB with an executable
- ctype
- Whenever you pass a character variable to a ctype function, always apply a cast.
- Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- current
- When you use x++ (Postfix), the current value is used for the math first, and the variable updates only after the expression is finished.
- Lesson 202 — Differences in expression resultsLesson 992 — Traversing the list with a while loop
- current = current->next
- To traverse a list, initialize a temporary pointer to the head and use current = current->next inside a while (current != NULL) loop to move from node to node.
- Lesson 992 — Traversing the list with a while loop
- current folder
- Double Quotes " ": These are for "Local Files." The preprocessor starts looking in the current folder where your source code lives.
- Lesson 766 — The `#include` directive for local files
- current_health = 100
- In the example above, the compiler sees current_health = 100;;.
- Lesson 770 — The danger of semicolon in `#define`
- current_stock
- If current_stock becomes -5, your program is in a "corrupt" state.
- Lesson 1173 — Writing a simple `assert()` check
- current->next
- If we called free(current) before assigning nextNode = current->next, we would be attempting to access current->next from memory that we no longer own.
- Lesson 994 — Appending nodes to the tailLesson 997 — Memory cleanup for linked lists
- currentTemp
- In this example, even though currentTemp isn't higher than maxLimit, the >= operator returns true because they are equal.
- Lesson 160 — Greater or equal `>=` and less or equal `<=`
- cycles
- However, your CPU doesn't think in seconds; it thinks in cycles.
- Lesson 1184 — Understanding CPU cycles vs. Wall time
D
- dangling pointer
- It still holds the address of that memory—it is now a dangling pointer.
- Lesson 557 — What is a dangling pointerLesson 558 — Returning addresses of local variablesLesson 562 — Use-after-free vulnerabilities
- dashboard_lights
- You have a variable called dashboard_lights where each bit represents a different light.
- Lesson 182 — Setting bits with `|`
- data
- In C, a variable consists of two main parts: the label (the name you choose) and the data (the value stored inside).
- Lesson 73 — What is a variable?Lesson 496 — When to use `const` with pointersLesson 547 — Handling realloc failure safelyLesson 617 — Arrow operator vs dot operatorLesson 705 — Parsing data from strings with sscanfLesson 1027 — Searching for a value in BST
- data loss
- In programming, this "mess" is called data loss or overflow.
- Lesson 132 — Safe downcasting techniques
- data race
- If both threads load the value before either has finished storing it, one increment is "lost." This is a classic data race.
- Lesson 1142 — Atomic types like atomic_int
- Data Segment
- The actual text "Alice" is stored in a special, read-only neighborhood of your computer's memory called the Data Segment.
- Lesson 149 — Memory segments: Stack vs. DataLesson 480 — Mutable vs immutable string memoryLesson 484 — Memory layout of string pointers
- data type
- When you declare multiple variables on one line, you state the data type once, followed by your chosen names separated by commas, and ending with a single semicolon.
- Lesson 75 — The syntax of a declarationLesson 76 — Multiple declarations in one lineLesson 235 — The `sizeof` operator with types
- data.bin
- If you try to open data.bin in a normal text editor like Notepad, it will look like gibberish.
- Lesson 725 — Writing raw bytes with fwrite
- data/old.txt
- Moving Files: You can use rename to move a file across directories on the same disk drive (e.g., from data/old.txt to archive/old.txt).
- Lesson 756 — Renaming files with rename
- database_save()
- In C, this means testing how different modules or files interact—for example, checking if your database_save() function correctly handles the data passed to it by your user_input() function.
- Lesson 1177 — Integration testing vs. Unit testing
- database.h
- If you ever find yourself wanting to include main.h inside database.h, stop!
- Lesson 802 — Dependency graphing in your head
- DataPacket
- In the example below, we want our DataPacket to be exactly 8 bytes.
- Lesson 575 — Manual padding in structures
- day
- Since that is true, it doesn't even bother checking if day is 7.
- Lesson 248 — Logical OR (||) for combined conditions
- days_until_expiration
- By using days_until_expiration instead of d, you eliminate the need for a comment explaining what the number 30 means.
- Lesson 1197 — Meaningful variable naming conventions
- daysUntilEvent
- If you are storing the number of days until an event, call it daysUntilEvent.
- Lesson 37 — Readability best practices
- daysUntilVacation
- Instead of remembering a cryptic memory address, you give that space a friendly name, like playerScore or daysUntilVacation.
- Lesson 73 — What is a variable?
- DBL_DIG
- Use FLT_DIG and DBL_DIG from <float.h> to know the maximum number of reliable decimal digits your variables can store before rounding errors occur.
- Lesson 908 — Checking `FLT_DIG` and `DBL_DIG` for precision limits
- deadlock
- Since you are the one holding the lock, you’re stuck in a permanent stalemate called a deadlock.
- Lesson 1130 — Recursive mutexes
- deadlocks
- It is also a powerful tool for avoiding deadlocks.
- Lesson 1129 — Using pthread_mutex_trylock
- Dear [NAME]
- If you have a template for a formal letter that says Dear [NAME], and you tell your editor that [NAME] is "Alice," the editor simply swaps the text.
- Lesson 772 — Defining function-like macros
- DEBUG
- Debug Modes: Running specific logs only when DEBUG is on and VERBOSE is also enabled.
- Lesson 782 — The `defined()` operator
- debug symbols
- The -g flag tells the compiler to create debug symbols.
- Lesson 825 — Compiling with debug symbols `-g`Lesson 1160 — Compiling with `-g` for debug symbols
- DEBUG_FULL
- Flexibility: You can create different "levels" of debugging (e.g., DEBUG_LOW, DEBUG_FULL) to control exactly how much information you see at any given time.
- Lesson 787 — Managing debug prints with macros
- DEBUG_LOW
- Flexibility: You can create different "levels" of debugging (e.g., DEBUG_LOW, DEBUG_FULL) to control exactly how much information you see at any given time.
- Lesson 787 — Managing debug prints with macros
- DEBUG_MODE
- Zero Overhead: When DEBUG_MODE is undefined, the printf isn't just hidden—it is physically removed from the compiled binary.
- Lesson 780 — Using `#ifdef` and `#ifndef`Lesson 787 — Managing debug prints with macros
- Decimal
- In our daily lives, we use the decimal system (base-10), likely because we have ten fingers.
- Lesson 119 — Integer literals (Hex, Octal, Binary)Lesson 179 — Understanding binary representation
- declaration
- However, if you want to use function A (defined in file_1.c) inside file_2.c, file_2.c needs a declaration so it knows the function's name, return type, and parameters.
- Lesson 70 — The 'undefined reference' linker errorLesson 79 — Declaration vs. InitializationLesson 922 — Using `extern` with functions
- declarations
- In C, header files are meant for declarations (blueprints), not definitions (the actual bricks).
- Lesson 377 — Role of the `.h` fileLesson 788 — The purpose of header filesLesson 793 — What should NOT go in a header
- declare
- You declare the variable in the header using extern (the "promise"), and you define it in exactly one .c file (the "reality").
- Lesson 146 — The `extern` keyword for multi-file codeLesson 789 — The 'duplicate definition' errorLesson 925 — Common linkage errors and 'multiple definition'
- declaring
- When you see the asterisk paired with a data type (like int, char, or float), you are declaring a pointer.
- Lesson 456 — The difference between `int *p` and `*p`
- default
- By including a default case that prints an error or logs a message, you turn a "silent ignore" into an "active notification." This makes debugging much faster because the code tells you exactly where it encountered an unexpected value.
- Lesson 258 — Basic switch syntax and casesLesson 260 — The default case for unhandled valuesLesson 265 — Switch statement best practicesLesson 976 — Handling the `default` case in `_Generic`Lesson 977 — Type-based function overloading simulationLesson 1151 — Handling the 'Default' case in switch statements
- Defensive Programming
- In C programming, Defensive Programming is the art of building that vending machine.
- Lesson 1148 — The philosophy of 'Trust No One'
- define
- Just remember: you can declare extern as many times as you want in different files, but you must define the variable (without extern) exactly once in only one file.
- Lesson 146 — The `extern` keyword for multi-file codeLesson 789 — The 'duplicate definition' errorLesson 925 — Common linkage errors and 'multiple definition'
- defined()
- The defined() operator allows you to combine multiple macro existence checks into a single #if statement using logical operators like AND, OR, and NOT.
- Lesson 782 — The `defined()` operator
- defines
- One file defines the variable (buys the book and puts it on the shelf).
- Lesson 146 — The `extern` keyword for multi-file code
- definitely lost
- In Valgrind terms, the suitcase is definitely lost because you lost the direct pointer to it.
- Lesson 566 — Reading 'definitely lost' reportsLesson 567 — Identifying 'indirectly lost' memory
- definition
- To understand this, you must know the difference between a declaration (a promise) and a definition (the delivery).
- Lesson 70 — The 'undefined reference' linker errorLesson 330 — Function prototype syntaxLesson 797 — The `extern` keyword for variables
- definitions
- The source file (ending in .c) is the kitchen; it contains the definitions, which is the actual logic and code that performs the work.
- Lesson 788 — The purpose of header filesLesson 793 — What should NOT go in a header
- Department
- For example, if you want to sort a list of employees by Department and then by Last Name, you would first sort by name, then perform a stable sort by department.
- Lesson 1052 — Stability in sorting algorithms
- Dependencies
- A Makefile rule uses targets (the goal), dependencies (the requirements), and recipes (the commands) to automate your build process efficiently.
- Lesson 61 — Introduction to `make` and MakefilesLesson 818 — Structure of a Makefile RuleLesson 819 — Targets, dependencies, and recipes
- dependency
- A Makefile consists of "rules." Each rule has a target (what you want to create), a dependency (what is needed to create it), and a recipe (the command to run).
- Lesson 1211 — Writing the Makefile for the project
- depth
- If your recursion is behaving strangely, adding a depth parameter is the fastest way to see if you are stuck in an infinite loop or if your base case is being triggered too late.
- Lesson 363 — Visualizing recursive depth
- Depth-First Search (DFS)
- In C, Depth-First Search (DFS) uses recursion to act as that string.
- Lesson 1045 — Depth-First Search (DFS) recursion
- Dequeue
- If you think of a Queue like a line of people waiting for coffee, the Dequeue operation represents the person at the very front finishing their order and leaving the shop.
- Lesson 1015 — Front and Rear pointersLesson 1017 — Dequeue operation logicLesson 1020 — Linked list queue implementationLesson 1044 — Breadth-First Search (BFS) logic
- dereference
- It represents "nowhere." If you try to dereference it (using the * operator to access the value at that address), your program doesn't just get confused—it crashes immediately with a "Segmentation Fault."
- Lesson 462 — Checking for NULL before dereferencing
- dereference operator
- However, when you see *ptr inside a regular line of code (an expression), it is the dereference operator acting as a "go to" command.
- Lesson 457 — The Dereference operator `*`Lesson 458 — Assigning values via pointers
- dereferencing
- In programming, this act of "following the map" to see what’s inside the house is called dereferencing, and we use the indirection operator (*) to do it.
- Lesson 238 — The Indirection operator `*`Lesson 456 — The difference between `int *p` and `*p`Lesson 457 — The Dereference operator `*`
- dereferencing a NULL pointer
- In C, trying to access or modify the value at a NULL address is called dereferencing a NULL pointer.
- Lesson 525 — Dereferencing the NULL pointer
- designated initializers
- C99 introduced designated initializers, which allow you to pick and choose which members to set using a period followed by the member name (the . operator).
- Lesson 394 — Designated initializers (C99)Lesson 603 — Designated initializers in C99Lesson 625 — Initializing nested structuresLesson 660 — Initializing a union
- dest = src
- Because the assignment expression dest = src actually evaluates to the character being copied, the loop naturally ends when the null terminator (0) is reached.
- Lesson 482 — Pointer-based `strcpy` implementation
- dest[i] = src[i]
- In earlier lessons, you likely copied strings using array indexing, like dest[i] = src[i].
- Lesson 482 — Pointer-based `strcpy` implementation
- destination
- The function takes two arguments: the destination (where the text is going) and the source (where the text is coming from).
- Lesson 424 — Copying strings with `strcpy`
- destination must be large enough
- The most important thing to remember is that the destination must be large enough to hold the incoming text.
- Lesson 424 — Copying strings with `strcpy`
- destroy
- If you allocated your mutex on the heap (using malloc) or as a local variable in a function, calling destroy is mandatory to keep your system's memory footprint clean and predictable.
- Lesson 1131 — Cleaning up mutex resources
- DeviceStatus
- In the example above, the entire DeviceStatus struct technically fits into just 8 bits (1 byte).
- Lesson 646 — Syntax for declaring bit-fields
- DFS
- When DFS calls itself, the computer puts the current node on the "Stack." It stays there, waiting, while the code explores the new branch.
- Lesson 1045 — Depth-First Search (DFS) recursion
- difftime
- By using difftime, your code becomes "portable." This means it will work correctly whether the underlying system counts time in seconds, milliseconds, or even something more exotic.
- Lesson 890 — Measuring intervals with `difftime`
- dir
- If you want to see what files are in your current folder, you don't look for icons; you type a command like ls (on Mac/Linux) or dir (on Windows).
- Lesson 12 — Introduction to the CLI
- directed
- Edges can be undirected (like a two-way street where both people are friends) or directed (like a one-way street or a "follower" relationship on Twitter).
- Lesson 1039 — Vertices and Edges definition
- Direction
- If you accidentally pass a Color enum into a function expecting a Direction enum, C will treat them both as integers and run the code.
- Lesson 667 — Type safety concerns with enums
- directives
- It looks for specific instructions called directives.
- Lesson 25 — Phase 1: The Preprocessor
- directly into
- When it comes time to build your final application, the linker looks inside this archive, finds the functions you actually used, and copies their binary code directly into your executable file.
- Lesson 810 — What is a static library `.a`
- directly into the
- You might wonder why we don't just type A directly into the printf statement.
- Lesson 51 — Printing characters with `%c`
- display_age
- The sequence point ensures that by the time display_age starts, my_age has officially become 26 in the computer's memory.
- Lesson 226 — Function call sequence points
- displayAddress
- In the example below, notice that we don't need to use parentheses to cast our pointers when calling the displayAddress function.
- Lesson 510 — Implicit conversion to `void *`
- displayStats
- In the code above, the variable names myLevel and myHealth don't actually matter to the displayStats function.
- Lesson 337 — Positional matching of arguments
- distance
- Instead of counting the number of doors you’ve passed, C thinks about the distance (or offset) from the very beginning of the hallway.
- Lesson 385 — Array indexing starting from zero
- Divide and Conquer
- The Divide and Conquer strategy suggests you shouldn't try to sort the whole pile at once.
- Lesson 1053 — Divide and Conquer strategy
- DJB2
- While there are many ways to do this, the DJB2 algorithm, created by Dan Bernstein, is a classic favorite because it is incredibly fast and does an excellent job of spreading different strings across the table to avoid "collisions."
- Lesson 1038 — String hashing with DJB2
- do
- If you try to use a variable inside the while parentheses that was birthed inside the do block, the compiler will panic and tell you the variable is undefined.
- Lesson 275 — Guaranteed execution: why do-while is differentLesson 276 — Using do-while for menu-driven programsLesson 277 — Using do-while for input re-promptingLesson 278 — Converting a while loop to a do-whileLesson 280 — Scope of variables declared inside do-while
- do-while
- If your code relies on a specific state (like a pointer not being null or a sensor reading being within range), a do-while loop can crash your program or corrupt data before the condition check even has a chance to stop it.
- Lesson 274 — The do-while syntax and the trailing semicolonLesson 275 — Guaranteed execution: why do-while is differentLesson 276 — Using do-while for menu-driven programsLesson 277 — Using do-while for input re-promptingLesson 278 — Converting a while loop to a do-whileLesson 279 — Comparing while vs do-while use casesLesson 280 — Scope of variables declared inside do-whileLesson 281 — Pitfall: condition check occurs after executionLesson 321 — Choosing the right loop for the task
- document it
- In C, the standard allows compiler creators (like GCC, Clang, or MSVC) to choose how certain operations work, provided they document it.
- Lesson 943 — Implementation-defined behavior vs UB
- Domains
- Before you can send data over a network, you have to decide two things: "Where is this going?" and "How should the data behave?" In C, we define these using Domains and Types.
- Lesson 1108 — Socket domains and types
- Don't optimize yet
- This impulse is what legendary computer scientist Donald Knuth warned against when he said, "Premature optimization is the root of all evil." In the practice of performance profiling, the first rule is actually a paradox: Don't optimize yet.
- Lesson 1187 — The trap of premature optimization
- door number
- You need to know which floor the unit is on and then which door number it is on that specific floor.
- Lesson 407 — Declaring 2D arrays: Rows and Columns
- dot
- Use the dot (.) when you are holding the actual box (the struct).
- Lesson 239 — Member access `.` and `->`Lesson 616 — The arrow operator `->` syntaxLesson 617 — Arrow operator vs dot operator
- dot operator
- To get something out of a backpack you are physically holding, you use the dot operator.
- Lesson 601 — The dot operator for member accessLesson 617 — Arrow operator vs dot operator
- double
- While a double usually occupies 8 bytes of memory, a long double often uses 12 or 16 bytes (depending on your computer’s architecture), allowing it to store many more digits after the decimal point with significantly less rounding error.
- Lesson 97 — Single precision `float`Lesson 98 — Double precision `double`Lesson 99 — The `long double` typeLesson 100 — Scientific notation in CLesson 101 — Precision loss and rounding errorsLesson 102 — Formatting decimals with `%.nf`Lesson 103 — The `<float.h>` header fileLesson 104 — Comparing floats for equalityLesson 120 — Floating-point suffixes (f, L)Lesson 123 — Hierarchy of types in expressionsLesson 125 — Risks of narrowing conversionsLesson 126 — The 'Usual Arithmetic Conversions'Lesson 128 — Common conversion pitfallsLesson 130 — Forcing floating-point divisionLesson 133 — Truncation during float-to-int castsLesson 150 — The addition operator `+`Lesson 151 — The subtraction operator `-`Lesson 153 — Integer division `/` truncationLesson 154 — Floating-point divisionLesson 155 — The modulo operator `%` with integersLesson 158 — Mixing int and float in arithmeticLesson 166 — Comparing floating-point numbersLesson 194 — Compound multiplication and divisionLesson 203 — Incrementing pointers (preview)Lesson 229 — Usual arithmetic conversionsLesson 230 — The `(type)` cast operatorLesson 231 — Truncation during castingLesson 234 — Safety with explicit castsLesson 235 — The `sizeof` operator with typesLesson 236 — The `sizeof` operator with variablesLesson 320 — Floating point precision issues in loop conditionsLesson 332 — Matching prototypes with definitionsLesson 334 — Common errors with missing prototypesLesson 338 — Type checking in function callsLesson 371 — Functions with unknown argumentsLesson 372 — The `stdarg.h` libraryLesson 374 — Extracting arguments with `va_arg`Lesson 452 — The size of a pointer variableLesson 463 — Incrementing pointers with `++`Lesson 509 — Casting `void *` to specific typesLesson 511 — Generic functions in CLesson 512 — The `memcpy` function signatureLesson 589 — Handling alignment within an arenaLesson 608 — Using typedef with primitive typesLesson 641 — Reordering members to reduce paddingLesson 643 — Alignment requirements for different typesLesson 647 — Restrictions on bit-field typesLesson 654 — Memory layout of a unionLesson 673 — Opaque types with header filesLesson 778 — Macros vs inline functions
- double calculate_tax(double price)
- If you changed the definition to double calculate_tax(double price), the compiler would throw a "conflicting types" error because the "Promise" at the top no longer matches the "Fulfillment" at the bottom.
- Lesson 332 — Matching prototypes with definitions
- double dereferencing
- This process is called double dereferencing.
- Lesson 505 — Accessing data through double dereference
- double get_precision()
- By adding double get_precision(); above the main function, you ensure the compiler knows exactly how much space to allocate for the return value.
- Lesson 334 — Common errors with missing prototypes
- Double indirection
- Double indirection (or a pointer-to-pointer) adds one more layer.
- Lesson 500 — Concept of double indirection
- double quotation marks
- To tell C, "This is just text, don't try to run it," you must wrap your words in double quotation marks (" ").
- Lesson 43 — Printing literal strings
- Double Quotes "filename.h"
- Double Quotes "filename.h": These are for User Headers.
- Lesson 795 — Standard header search paths
- doubleNumber
- When doubleNumber is called, C creates a new spot in the computer's memory specifically for the parameter x.
- Lesson 341 — Understanding 'Pass by Value'
- doubleNumber(myAmount)
- When doubleNumber(myAmount) is executed, the program jumps to the function, calculates 50, and then essentially "replaces" the function call in your code with that value.
- Lesson 328 — Returning values from functions
- doubles
- A crucial detail to remember is that pow() works with doubles (floating-point numbers).
- Lesson 861 — Basic power and square root: `pow` and `sqrt`
- Doubly Linked List
- A Doubly Linked List changes this by adding a second door.
- Lesson 999 — Updating the node struct
- Doubly Linked List (DLL)
- In a Doubly Linked List (DLL), every node has a prev pointer.
- Lesson 1003 — Deleting without head traversal
- down
- Use up to inspect the variables of the function that called your current position, and down to return toward the active line of code.
- Lesson 834 — Moving between frames with `up` and `down`
- downcasting
- In C, downcasting is the act of converting a larger data type (like a long) into a smaller one (like an int or char).
- Lesson 132 — Safe downcasting techniques
- Doxygen
- In professional C programming, Doxygen is the tool that turns your comments into that polished instruction booklet (usually as an HTML website or PDF).
- Lesson 1199 — Writing effective Doxygen comments
- draw_circle() + draw_square()
- If you write draw_circle() + draw_square(), precedence says you must add their results.
- Lesson 227 — Order of evaluation vs Precedence
- Drawer (the single pointer)
- The Key opens a Drawer (the single pointer).
- Lesson 500 — Concept of double indirection
- dup()
- The dup() system call creates a new file descriptor that points to the same open file as an existing one, sharing the same read/write position.
- Lesson 1094 — Duplicating descriptors with dup()
- dup2
- If we want to redirect output to a file, we first open that file to get its descriptor, then use dup2 to copy that descriptor onto slot 1.
- Lesson 1095 — Redirecting output with dup2()Lesson 1105 — Redirecting stdout to a pipe
- dup2()
- What you'll learn: How to use the dup2() system call to point a standard file descriptor toward a file, effectively "silencing" the terminal and sending data elsewhere.
- Lesson 1095 — Redirecting output with dup2()Lesson 1105 — Redirecting stdout to a pipe
- dynamic
- Calling a function via a pointer allows your code to be dynamic.
- Lesson 516 — Calling a function via a pointer
- dynamic linker
- The moment you launch the app, a specialized tool called the dynamic linker rushes to find those files and plug them into your program’s memory.
- Lesson 816 — Runtime library loading and `LD_LIBRARY_PATH`
- Dynamic Memory Allocation
- Think of Dynamic Memory Allocation like renting a hotel room.
- Lesson 868 — Allocating memory with `malloc` and `free`
E
- EACCES
- By specifically checking for EACCES, you can give your users helpful feedback—like "Please run this as an Administrator"—rather than leaving them staring at a generic "File not found" message or a sudden crash.
- Lesson 740 — Introduction to errnoLesson 745 — Handling 'Permission Denied' errorsLesson 903 — When to use `errno` vs return codes
- EAGAIN
- If it equals EAGAIN, it means the resource is temporarily unavailable.
- Lesson 1098 — Non-blocking I/O basics
- eax
- If you need to move data into a specific register (like the eax register on x86 processors) to talk to hardware, you use Inline Assembly.
- Lesson 960 — The 'Clobber' list explainedLesson 961 — Direct register access
- Edges
- A Graph is a collection of Vertices (the data points) connected by Edges (the relationships between them).
- Lesson 1039 — Vertices and Edges definition
- Edit
- Click Environment Variables, find the Path variable under "System variables," and click Edit.
- Lesson 11 — Setting up MinGW on Windows
- efficiency
- The main reason developers still reach for C is efficiency.
- Lesson 5 — Why C remains relevant today
- either
- The rule is simple: if either the first bit OR the second bit is a 1, the resulting bit is a 1.
- Lesson 176 — Bitwise OR `|`
- eject button
- Think of a return statement as an eject button.
- Lesson 312 — Function returns as a control flow mechanism
- elements
- Instead of giving you the raw number of bytes between two addresses, C tells you how many elements (lockers) fit between them.
- Lesson 466 — Subtracting two pointersLesson 470 — Navigating memory blocks manuallyLesson 731 — Verifying bytes read vs expected
- ELF
- On Linux and most Unix-like systems, this file uses the ELF format, which stands for Executable and Linkable Format.
- Lesson 808 — The executable ELF format
- else
- However, because the else is closest to if (is_sunny), it actually means: "If it is the weekend but NOT sunny, stay inside." If is_weekend were 0, nothing would print at all!
- Lesson 170 — Short-circuit evaluation of `&&`Lesson 245 — The else clause for alternative pathsLesson 246 — Else-if ladders for multiple conditionsLesson 251 — Variable scope inside if-else blocksLesson 256 — Nested if statements and dangling else logicLesson 258 — Basic switch syntax and casesLesson 312 — Function returns as a control flow mechanismLesson 770 — The danger of semicolon in `#define`
- else if
- If you find yourself writing more than three else if statements to check the value of the same integer or character, it is usually time to switch to a switch.
- Lesson 246 — Else-if ladders for multiple conditionsLesson 264 — Comparing switch-case vs else-if ladders
- else if (temp > 10)
- If we had put else if (temp > 10) at the very top, a temperature of 25 would have triggered that block immediately, and the computer would have never checked if it was also over 20 or 30.
- Lesson 246 — Else-if ladders for multiple conditions
- else-if ladder
- An else-if ladder is like walking down the hall and knocking on every single door: "Is this Room 1?
- Lesson 264 — Comparing switch-case vs else-if ladders
- emergency_system()
- In the example above, if emergency_system() runs, every other function using speed is suddenly affected.
- Lesson 142 — The dangers of global variables
- emory
- But for dynamic allocation, we use a function called malloc (short for memory allocation).
- Lesson 537 — The malloc function signature
- employee.homeAddress.city
- It also makes your code "self-documenting." When you type employee.homeAddress.city, the path to the data is perfectly clear, following a logical flow from the container to the specific detail.
- Lesson 623 — Defining a struct inside another struct
- Empty
- You might also use Peek (to look at the top item without removing it) or check if the stack is Empty.
- Lesson 1006 — Stack abstract data type concept
- encapsulation
- This is a core pattern for encapsulation, ensuring that the "internals" of a module stay private.
- Lesson 674 — Information hiding using void pointersLesson 918 — Internal vs external linkage basicsLesson 919 — The `static` keyword in global scope
- end
- We swap the characters at these positions using a temporary variable, increment start, decrement end, and repeat until they cross paths.
- Lesson 283 — Initialization, condition, and increment flowLesson 440 — Reversing an array in placeLesson 441 — Reversing a string in place
- End-of-File (EOF)
- The most critical reason to close unused ends is to trigger the End-of-File (EOF) condition.
- Lesson 1103 — Closing unused pipe ends
- Endianness
- When you move into advanced C, you’ll encounter Endianness: the order in which a CPU stores a multi-byte number in memory.
- Lesson 952 — Network byte order and `htons`/`ntohs`Lesson 955 — Using masks for cross-platform bit logicLesson 956 — The `__builtin_bswap` compiler intrinsics
- endPtr
- The endPtr now points to the space right before "samples." If the string was "abc," input would equal endPtr, signaling that no conversion happened.
- Lesson 873 — Converting strings to doubles with `strtod`
- Enemy
- A forward declaration is a way of saying to the compiler: "Hey, there is a struct named Enemy coming later.
- Lesson 792 — Forward declarations in headers
- enemy.c
- If global_score is defined in game.h, and both player.c and enemy.c include it, they both end up trying to create their own version of that variable.
- Lesson 925 — Common linkage errors and 'multiple definition'
- enemy.h
- However, in C, if you include a header file twice—perhaps because player.h and enemy.h both need physics.h—the compiler sees two identical sets of instructions.
- Lesson 792 — Forward declarations in headersLesson 1203 — Header guard best practices
- energy
- When it subtracts 10, it is only changing that local "copy." The global energy at the top of the file remains 100.
- Lesson 340 — Shadowing variables in functions
- Engine
- If you have a Car struct, and inside that Car is an Engine struct, and inside that Engine is a FuelPump struct, you can’t jump straight to the pump.
- Lesson 624 — Accessing members of nested structs
- engine_running
- In the first example, because engine_running is 0 (false), !engine_running becomes 1 (true).
- Lesson 167 — Logical NOT `!`
- engine_temp
- If you try to access engine_temp or call log_internal_state() from a different file like main.c, the compiler will act as if they don't exist.
- Lesson 919 — The `static` keyword in global scope
- engine.c
- Imagine you have a file called engine.c that handles internal calculations.
- Lesson 919 — The `static` keyword in global scope
- ENOENT
- For example, if you try to open a file and it fails, errno tells you if the file is missing (ENOENT) or if you simply don't have permission to see it (EACCES).
- Lesson 740 — Introduction to errnoLesson 903 — When to use `errno` vs return codes
- Enqueue
- When a new piece of data arrives (called Enqueue), we move the rear forward and place the data there.
- Lesson 1015 — Front and Rear pointersLesson 1016 — Enqueue operation logicLesson 1020 — Linked list queue implementation
- Enter
- When you type a number into a C program and hit Enter, two things are sent to your computer's memory (the buffer): the number itself and a "newline" character (\n) created by that Enter key.
- Lesson 12 — Introduction to the CLILesson 32 — Executing from the command lineLesson 108 — Escape sequences like `\n` and `\t`Lesson 270 — Reading input until EOF with whileLesson 680 — Basic character input with getcharLesson 694 — Reading characters with ' %c' spacingLesson 697 — How scanf leaves trailing newlines
- entire structure
- If you need to get the address of the data, you must point to the entire structure itself, rather than the tiny bit-fields hidden inside it.
- Lesson 652 — Limitations of bit-field addresses
- entry
- We assume the hash table is an array of Entry structs.
- Lesson 20 — The `main()` function entry pointLesson 1036 — Hash table lookup
- Entry Point
- The Header: This is the "shipping label." It tells the OS which processor the file was built for (like x86 or ARM) and the Entry Point, which is the memory address where the code actually starts.
- Lesson 808 — The executable ELF format
- enum
- You can override C's default zero-based indexing in an enum by using the = operator, and any unassigned items will simply follow the previous value by incrementing by one.
- Lesson 262 — Switch restrictions: integral types onlyLesson 661 — Defining an enum typeLesson 662 — Default integer values in enumsLesson 663 — Explicitly assigning enum valuesLesson 664 — Enums vs constant integersLesson 665 — Using enums in switch statementsLesson 666 — Scoped enum limitations in CLesson 668 — Using enums for state machinesLesson 669 — Tagged unions for type safety
- enumeration
- An enumeration (or enum) is a user-defined type that allows you to assign names to numbers.
- Lesson 661 — Defining an enum type
- envelopes
- Instead, the box contains a row of envelopes.
- Lesson 506 — Command line arguments `char **argv`
- Environment Variables
- Click Environment Variables, find the Path variable under "System variables," and click Edit.
- Lesson 11 — Setting up MinGW on WindowsLesson 1071 — Environment variables in C
- EOF
- There is a historical trap here: these functions are only defined to handle values that can be represented as an unsigned char (0 to 255), plus one special value: EOF (usually -1).
- Lesson 270 — Reading input until EOF with whileLesson 680 — Basic character input with getcharLesson 681 — EOF (End Of File) explainedLesson 682 — Using while loops with getcharLesson 683 — Relationship between char and int in I/OLesson 716 — Character I/O with fgetc and fputcLesson 743 — Distinguishing EOF from errors with ferrorLesson 746 — Handling 'Disk Full' scenariosLesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- Epsilon
- We do this by defining a very small threshold called epsilon.
- Lesson 104 — Comparing floats for equalityLesson 166 — Comparing floating-point numbers
- equality operator
- The double equals sign (==), however, is the equality operator.
- Lesson 161 — The equality operator `==`
- erases everything
- Behavior: If the file already exists, C erases everything inside it the moment you open it.
- Lesson 710 — Understanding file modes: r, w, a
- errno
- Most Standard Library functions use a simple return value (like -1 or NULL) to signal that something went wrong, while errno (a global variable found in <errno.h>) stores a specific code explaining what went wrong.
- Lesson 740 — Introduction to errnoLesson 741 — Using perror for descriptive errorsLesson 742 — The strerror functionLesson 745 — Handling 'Permission Denied' errorsLesson 897 — The global `errno` variableLesson 898 — Interpreting errors with `perror`Lesson 899 — Getting error strings with `strerror`Lesson 900 — Resetting `errno` before library callsLesson 903 — When to use `errno` vs return codesLesson 1086 — Sending signals with kill()Lesson 1122 — Thread-local storage basics
- errno = 0
- By setting errno = 0 right before strtol, you guarantee that if errno is non-zero afterward, it was definitely caused by that specific line of code.
- Lesson 900 — Resetting `errno` before library calls
- error cleanup block
- While goto is often discouraged because it can create "spaghetti code," the C community widely accepts one specific pattern: the error cleanup block.
- Lesson 310 — Legitimate use case: error cleanup blocks
- error_code != 0
- A conditional breakpoint allows you to stay hands-off until a specific logical condition is met, such as i == 500 or error_code != 0.
- Lesson 835 — Setting conditional breakpoints
- error: expected ';' before 'return'
- The compiler will likely say: error: expected ';' before 'return'.
- Lesson 66 — Reading compiler error messages
- escape character
- To solve this, we use a "magic wand" called the escape character: the backslash (\).
- Lesson 46 — Escaping double quotes
- every
- Condition: Before every lap, the computer asks: "Is this true?" If yes, it runs the code inside the curly braces.
- Lesson 172 — Building complex logical expressionsLesson 283 — Initialization, condition, and increment flow
- every time
- In the example above, if count were a normal variable, it would be reset to 0 every time incrementCounter was called, and the program would just print "1" three times.
- Lesson 920 — The `static` keyword inside functions
- exact same spot
- Using the == operator checks if two pointers are pointing at the exact same spot in memory.
- Lesson 467 — Pointer comparison with `==` and `<`
- exactly once
- You should call srand() exactly once at the very beginning of your main() function.
- Lesson 885 — Seeding the generator with `srand`Lesson 886 — Why you should only seed once
- eXamine
- The x command (short for eXamine) allows you to look at a specific memory address and see exactly what bits are sitting there, regardless of what the variable type claims to be.
- Lesson 839 — Examining raw memory with `x`
- example.c:5
- The first "by" line is the "smoking gun." It points to example.c:5.
- Lesson 566 — Reading 'definitely lost' reports
- exec
- The FD_CLOEXEC flag ensures that a file descriptor is automatically closed when a process calls exec, preventing sensitive data leaks to child programs.
- Lesson 1081 — Replacing process images with execl()Lesson 1096 — The close-on-exec flag
- exec()
- In systems programming, we rarely use exec() by itself because it is "destructive"—it completely replaces your current program with a new one, meaning any code after the exec() call never runs.
- Lesson 1075 — Process duplication and copy-on-writeLesson 1083 — Combining fork() and exec()Lesson 1096 — The close-on-exec flag
- execl
- While there are several helper functions (like execl or execvp), they all eventually call the system call execve.
- Lesson 1080 — The execve() family overview
- execl()
- When you call execl(), the operating system wipes the current program's memory—its code, variables, and stack—and loads a new executable in its place.
- Lesson 1081 — Replacing process images with execl()
- Executable
- If everything matches up, the Linker spits out a single file: the Executable (like a.out on Linux or program.exe on Windows).
- Lesson 6 — C as a compiled languageLesson 9 — Role of the CompilerLesson 28 — Phase 4: The Linker
- executable binary
- The compiler is the chef that takes your instructions and performs the "work" to produce a finished dish—in this case, an executable binary.
- Lesson 30 — Creating an executable binary
- executable file
- After you have written your code and asked the compiler to translate it, you are left with a finished product: the executable file.
- Lesson 31 — How the OS runs a programLesson 32 — Executing from the command line
- execv()
- Once execv() is called successfully, the current process is wiped clean, and the new program starts fresh using the strings you provided in your array as its own argv.
- Lesson 1082 — Passing arguments to execv()
- execve
- Think of execve as a "body snatcher." When a process calls it, the process doesn't die, but its "soul" (the code it was running) is instantly wiped out and replaced by a new program.
- Lesson 1080 — The execve() family overview
- execve()
- If the child then calls execve() to transform into a completely different program (like running ls or a custom script), those file descriptors stay open.
- Lesson 1096 — The close-on-exec flag
- execvp
- While there are several helper functions (like execl or execvp), they all eventually call the system call execve.
- Lesson 1080 — The execve() family overview
- exit code
- In C, this status report is an integer known as the exit code.
- Lesson 1072 — Process termination and exit codes
- exit()
- Unlike a return statement, which only takes you out of the current function, exit() shuts down the entire program instantly, no matter how many nested functions deep you are.
- Lesson 313 — Exiting the program with exit()Lesson 875 — Cleaning up at exit with `atexit`Lesson 1077 — Capturing child exit statusLesson 1078 — Preventing zombie processesLesson 1087 — Basic signal handling with signal()Lesson 1123 — The pthread_exit function
- exit(0)
- Use exit(0) for a clean, immediate shutdown and exit(1) to stop the program when a fatal error occurs.
- Lesson 313 — Exiting the program with exit()
- exit(1)
- Instead of manually writing your cleanup code before every single exit(1) or return statement, you can register your cleanup function once at the start of main.
- Lesson 313 — Exiting the program with exit()Lesson 875 — Cleaning up at exit with `atexit`
- exp()
- Think of exp() as a "growth machine." If you tell it how much time has passed, it tells you how much something has grown.
- Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- exp(x)
- Use exp(x) for powers of $e$, log(x) for the natural logarithm, and log10(x) for base-10 calculations.
- Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- expectation
- const is about permission (Can my code change this?), while volatile is about expectation (Can the outside world change this?).
- Lesson 917 — Combining `const` and `volatile`
- expected
- Instead of giving up or locking, we simply grab the new expected value and try the calculation again.
- Lesson 1145 — Compare and swap (CAS) basics
- explicit
- When we declare a pointer like int myPtr or char myPtr, we are being explicit.
- Lesson 461 — Implicit vs explicit pointer types
- explicit casting
- If your data is already stored in integer variables, you can use explicit casting to temporarily "pretend" a variable is a float for that specific calculation.
- Lesson 130 — Forcing floating-point divisionLesson 131 — Casting between char and int
- explicit declaration
- An explicit declaration, commonly called a function prototype, is like giving the compiler a "heads-up." You provide the function's signature at the very top of your file, before main().
- Lesson 329 — Implicit vs. explicit declarations
- explicit type
- The address might be exactly the same, but the explicit type changes how the dereference operator (*) behaves.
- Lesson 461 — Implicit vs explicit pointer types
- exponential time complexity
- This is called exponential time complexity.
- Lesson 361 — Fibonacci: The cost of redundancy
- expression
- In C, the ternary operator is an expression, which means the entire thing must evaluate to a single, specific type of value.
- Lesson 197 — Assignment expression return valueLesson 207 — Ternary as an expressionLesson 209 — Type consistency in ternary branches
- Extended Asm
- To make C and assembly talk to each other without crashing your program, we use Extended Asm.
- Lesson 959 — Input and Output operands in assembly
- extern
- Using extern is the primary way to manage "Global State." While you should use global variables sparingly to avoid messy code, extern is essential for sharing configuration settings, game states, or hardware flags across a large program with dozens of different files.
- Lesson 146 — The `extern` keyword for multi-file codeLesson 797 — The `extern` keyword for variablesLesson 918 — Internal vs external linkage basicsLesson 921 — Sharing variables across files with `extern`Lesson 922 — Using `extern` with functionsLesson 923 — Storage class specifier precedenceLesson 925 — Common linkage errors and 'multiple definition'
- External fragmentation
- External fragmentation is like having ten small gaps under your bed.
- Lesson 582 — Internal vs External fragmentationLesson 584 — Allocation strategies: Best-fit
- External Linkage
- By default, any variable or function you declare outside of a function (at the file level) has external linkage.
- Lesson 918 — Internal vs external linkage basicsLesson 919 — The `static` keyword in global scope
- extra memory
- However, if you have to take all the clothes out, lay them neatly on the bed in order, and then put them back into the suitcase, you are using extra memory.
- Lesson 1051 — In-place sorting vs extra memory
F
- F_OK
- To check for a file's existence, we use a special constant called F_OK (short for File OK).
- Lesson 762 — Checking if a file exists
- F_SETLKW
- Use fcntl() with F_SETLKW to ensure only one process at a time can modify a shared file, preventing data corruption through cooperative locking.
- Lesson 1099 — File locking with fcntl()
- F_WRLCK
- We tell the kernel we want an F_WRLCK (Write Lock), which is exclusive.
- Lesson 1099 — File locking with fcntl()
- fabs
- By having a dedicated function for floating-point numbers (fabs) and another for integers (abs), the computer can process the math using the most efficient instructions for that specific data type.
- Lesson 866 — Absolute values for floats with `fabs`
- fabs()
- To compare two floats safely, you subtract one from the other, take the absolute value (using fabs() from the math.h library), and check if the result is less than your tiny threshold.
- Lesson 104 — Comparing floats for equalityLesson 166 — Comparing floating-point numbersLesson 866 — Absolute values for floats with `fabs`Lesson 979 — Mathematical macros using `_Generic`
- fabsf()
- This is why the math library (math.h) gives us three versions of the absolute value function: fabsf() for floats, fabs() for doubles, and fabsl() for long doubles.
- Lesson 979 — Mathematical macros using `_Generic`
- fabsl()
- This is why the math library (math.h) gives us three versions of the absolute value function: fabsf() for floats, fabs() for doubles, and fabsl() for long doubles.
- Lesson 979 — Mathematical macros using `_Generic`
- factorial
- In mathematics, the factorial of a number (written as $n!$) is a perfect example.
- Lesson 357 — Factorial as a recursive example
- factorial(1)
- This continues until it reaches factorial(1).
- Lesson 357 — Factorial as a recursive example
- factorial(4)
- It "pauses" the calculation of 5 and moves inside to calculate factorial(4).
- Lesson 357 — Factorial as a recursive example
- factorial(5)
- When you call factorial(5), the computer doesn't get an answer immediately.
- Lesson 357 — Factorial as a recursive example
- fall-through
- We call this fall-through, and we use the break keyword to stop it.
- Lesson 259 — The role of the break statement in switch
- FALLING
- This prevents bugs where a program enters a state (like FALLING) but has no instructions on what to do next.
- Lesson 668 — Using enums for state machines
- false
- If you try to ask if (0.1 + 0.2 == 0.3), the computer will likely tell you false because the tiny microscopic "dust" at the end of the numbers doesn't match perfectly.
- Lesson 104 — Comparing floats for equalityLesson 162 — The inequality operator `!=`Lesson 163 — Truthiness: 0 vs non-zeroLesson 166 — Comparing floating-point numbersLesson 170 — Short-circuit evaluation of `&&`Lesson 173 — Logical vs Bitwise distinctionLesson 242 — Relational operators: <, <=, >, and >=Lesson 243 — Truthiness: 0 is false, non-zero is trueLesson 249 — Logical NOT (!) for inversionLesson 277 — Using do-while for input re-promptingLesson 667 — Type safety concerns with enumsLesson 966 — C99: Variable declarations and `bool`Lesson 969 — C23: The `bool`, `true`, and `false` keywords
- fast_square
- Each file gets its own private, optimized version of fast_square.
- Lesson 368 — Inline functions in header files
- fatal error
- A fatal error is like realize you have no oven and no flour.
- Lesson 68 — Warnings vs Fatal errors
- fclose
- By checking the return value of fclose, you catch errors that happened at the very last second when the system tried to commit the remaining buffered data to the hardware.
- Lesson 746 — Handling 'Disk Full' scenariosLesson 757 — Deleting files with remove
- fclose()
- In C, closing a file with fclose() does two vital things: it releases the memory the operating system allocated to handle that file, and it "flushes" the data.
- Lesson 711 — Closing files with fcloseLesson 715 — The maximum number of open filesLesson 723 — Rewinding a file to the startLesson 746 — Handling 'Disk Full' scenariosLesson 747 — Safe file closing patternsLesson 1206 — Opening and reading files line-by-line
- fcntl
- You can set this flag when you first open the file using the O_CLOEXEC flag, or later using fcntl.
- Lesson 1096 — The close-on-exec flag
- fcntl()
- Use fcntl() with F_SETLKW to ensure only one process at a time can modify a shared file, preventing data corruption through cooperative locking.
- Lesson 1098 — Non-blocking I/O basicsLesson 1099 — File locking with fcntl()
- FD_CLOEXEC
- The FD_CLOEXEC flag ensures that a file descriptor is automatically closed when a process calls exec, preventing sensitive data leaks to child programs.
- Lesson 1096 — The close-on-exec flag
- fd[0]
- The pipe() function creates a pair of file descriptors—fd[0] for reading and fd[1] for writing—enabling a one-way flow of data between related processes.
- Lesson 1100 — Anatomy of a pipeLesson 1101 — Creating pipes with pipe()Lesson 1104 — Piping data between parent and childLesson 1105 — Redirecting stdout to a pipe
- fd[1]
- The pipe() function creates a pair of file descriptors—fd[0] for reading and fd[1] for writing—enabling a one-way flow of data between related processes.
- Lesson 1100 — Anatomy of a pipeLesson 1101 — Creating pipes with pipe()Lesson 1104 — Piping data between parent and childLesson 1105 — Redirecting stdout to a pipe
- fd1
- If you close fd1, you can still use fd2 to write to the file.
- Lesson 1094 — Duplicating descriptors with dup()
- fd2
- If you close fd1, you can still use fd2 to write to the file.
- Lesson 1094 — Duplicating descriptors with dup()
- fencepost problem
- If you quickly answered "10," you’ve just encountered the fencepost problem.
- Lesson 319 — The Fencepost problem (off-by-one errors)
- feof()
- If you are at the very last character of a file, feof() still returns false because you haven't tried to read past that character yet.
- Lesson 721 — Detecting the end of a file with feofLesson 722 — Why feof inside a loop condition is badLesson 743 — Distinguishing EOF from errors with ferror
- feof(file_pointer)
- The function feof(file_pointer) returns a "true" value (non-zero) only after an input operation has tried to read past the end of the file.
- Lesson 721 — Detecting the end of a file with feofLesson 743 — Distinguishing EOF from errors with ferror
- ferror
- If you detect an error using ferror, handle the problem (like asking the user to plug a USB drive back in), you must call clearerr before the stream will let you work with it again.
- Lesson 744 — Clearing file error indicators with clearerr
- ferror()
- By checking ferror(), you make your code "robust." You are telling the computer: "Stop if the file is over, but alert me if something actually broke."
- Lesson 743 — Distinguishing EOF from errors with ferror
- ferror(file_pointer)
- ferror(file_pointer) returns true only if an actual read/write error occurred (like a disk failure or a lost network connection).
- Lesson 743 — Distinguishing EOF from errors with ferror
- ff
- Using %#x would turn ff into 0xff, which is the standard way programmers write hexadecimal in their code.
- Lesson 689 — Printing hex and octal values
- fflush
- Notice how we use fflush here to ensure the user sees the prompt before the program pauses for input.
- Lesson 751 — Forcing a write with fflushLesson 755 — When to use fflush(stdout)
- fflush()
- This is why if you print a prompt without a \n, it might not appear immediately until you call fflush() or the program ends.
- Lesson 746 — Handling 'Disk Full' scenariosLesson 749 — Full buffering vs Line bufferingLesson 751 — Forcing a write with fflushLesson 1158 — Flushing `stdout` for accurate logs
- fflush(stdout)
- In this example, calling fflush(stdout) ensures the user sees "Loading..." the very moment the line is reached, rather than two seconds later when the program ends.
- Lesson 748 — How C buffers I/O for speedLesson 751 — Forcing a write with fflushLesson 755 — When to use fflush(stdout)Lesson 1158 — Flushing `stdout` for accurate logs
- fgetc
- When a function like fread or fgetc hits the end of a file or encounters a hardware glitch, the stream sets an internal flag (a "sticky note") indicating an error or EOF (End Of File).
- Lesson 716 — Character I/O with fgetc and fputcLesson 719 — Formatted file input with fscanfLesson 721 — Detecting the end of a file with feofLesson 722 — Why feof inside a loop condition is badLesson 739 — Risks of seeking in text modeLesson 744 — Clearing file error indicators with clearerr
- fgetc()
- In C, many input functions like fgetc() or fscanf() return a special constant called EOF when they can no longer read data.
- Lesson 732 — The file position indicatorLesson 743 — Distinguishing EOF from errors with ferrorLesson 754 — Performance: Single char vs block I/O
- fgetc(file_pointer)
- To read a character, you call fgetc(file_pointer).
- Lesson 716 — Character I/O with fgetc and fputc
- fgetpos
- Use fgetpos and fsetpos with the fpos_t type to reliably "bookmark" and return to locations in files of any size.
- Lesson 738 — Using fgetpos and fsetpos for large files
- fgets
- A common "best practice" is to read an entire line of input into a string first (using a function like fgets), validate that the string isn't empty or broken, and then use sscanf to parse the actual data.
- Lesson 433 — Safe input reading with `fgets`Lesson 434 — Removing newlines from `fgets` resultsLesson 701 — Reading safe strings with fgetsLesson 702 — Removing the newline from fgetsLesson 705 — Parsing data from strings with sscanfLesson 706 — The buffer size argument in fgetsLesson 707 — Checking for NULL return in fgetsLesson 717 — String I/is with fgets and fputsLesson 719 — Formatted file input with fscanfLesson 720 — Sequential vs random access conceptsLesson 722 — Why feof inside a loop condition is badLesson 723 — Rewinding a file to the startLesson 739 — Risks of seeking in text modeLesson 761 — Standard stream redirection in shellsLesson 1206 — Opening and reading files line-by-line
- fgets()
- In future lessons, we will use fgets() or scanf() with width limits, both of which allow you to specify the maximum number of characters to read, keeping your "room" safe from overcrowding.
- Lesson 432 — Why `gets` is dangerous and deprecatedLesson 433 — Safe input reading with `fgets`Lesson 434 — Removing newlines from `fgets` resultsLesson 699 — Why gets is dangerous and deprecatedLesson 701 — Reading safe strings with fgetsLesson 732 — The file position indicatorLesson 1092 — File descriptors vs FILE pointersLesson 1153 — Using `fgets()` instead of `scanf()` for stringsLesson 1206 — Opening and reading files line-by-line
- fibonacci(38)
- In the code above, fibonacci(40) calls fibonacci(39) and fibonacci(38).
- Lesson 361 — Fibonacci: The cost of redundancy
- fibonacci(39)
- In the code above, fibonacci(40) calls fibonacci(39) and fibonacci(38).
- Lesson 361 — Fibonacci: The cost of redundancy
- fibonacci(40)
- In the code above, fibonacci(40) calls fibonacci(39) and fibonacci(38).
- Lesson 361 — Fibonacci: The cost of redundancy
- field width
- To fix this, you can specify a field width.
- Lesson 685 — Specifying field width for alignment
- FIFO
- In a standard queue, the rule is FIFO (First-In, First-Out).
- Lesson 1021 — Priority queue conceptual introLesson 1106 — Introduction to named pipes (FIFOs)Lesson 1107 — Creating FIFOs with mkfifo()
- FIFOs are blocking
- The most important thing to remember is that FIFOs are blocking.
- Lesson 1107 — Creating FIFOs with mkfifo()
- FILE
- If the file exists, fopen hands you a pointer to a FILE structure—essentially a bookmark that keeps track of where you are in the text.
- Lesson 708 — The FILE pointer typeLesson 709 — Opening files with fopenLesson 712 — Checking for NULL file pointersLesson 725 — Writing raw bytes with fwriteLesson 758 — Creating temporary files with tmpfileLesson 1092 — File descriptors vs FILE pointersLesson 1206 — Opening and reading files line-by-line
- FILE *
- Think of FILE * as a "handle." When you open a file, the operating system gives you a pointer to a FILE structure.
- Lesson 708 — The FILE pointer typeLesson 718 — Formatted file output with fprintfLesson 723 — Rewinding a file to the startLesson 726 — Reading raw bytes with fread
- FILE *fp
- A FILE pointer (e.g., FILE *fp) is a sophisticated wrapper around a file descriptor.
- Lesson 1092 — File descriptors vs FILE pointers
- file descriptor
- In C, a socket is represented by a simple integer called a file descriptor.
- Lesson 1110 — Creating a socket with socket()
- file descriptor (fd)
- Think of a file descriptor (fd) as a claim check at a coat room.
- Lesson 1092 — File descriptors vs FILE pointers
- file descriptors
- Use file descriptors when you are doing systems programming, like redirecting input/output, working with network sockets, or when you need fine-grained control over exactly when data hits the disk.
- Lesson 1092 — File descriptors vs FILE pointersLesson 1093 — Standard streams (0, 1, 2)Lesson 1100 — Anatomy of a pipeLesson 1101 — Creating pipes with pipe()
- FILE pointer
- A FILE pointer (e.g., FILE *fp) is a sophisticated wrapper around a file descriptor.
- Lesson 1092 — File descriptors vs FILE pointers
- file position indicator
- In C, every open file has a similar mechanism called the file position indicator.
- Lesson 732 — The file position indicator
- file scope
- In C, a variable has file scope (or global scope) when it is defined outside of any function, usually at the very top of your .c file.
- Lesson 137 — Global variables and file scope
- file_1.c
- However, if you want to use function A (defined in file_1.c) inside file_2.c, file_2.c needs a declaration so it knows the function's name, return type, and parameters.
- Lesson 922 — Using `extern` with functions
- file_2.c
- However, if you want to use function A (defined in file_1.c) inside file_2.c, file_2.c needs a declaration so it knows the function's name, return type, and parameters.
- Lesson 922 — Using `extern` with functions
- file_a.h
- In C, a circular dependency happens when file_a.h contains #include "file_b.h", but file_b.h also contains #include "file_a.h".
- Lesson 794 — Circular dependency issues
- file_b.h
- In C, a circular dependency happens when file_a.h contains #include "file_b.h", but file_b.h also contains #include "file_a.h".
- Lesson 794 — Circular dependency issues
- file_logic.c
- When you compile these files together, the compiler sees the extern declaration in main.c and leaves a "placeholder." During the final stage (linking), the computer finds the actual code in file_logic.c and plugs it in.
- Lesson 922 — Using `extern` with functions
- FILE*
- In C, file streams (FILE*) work the same way.
- Lesson 744 — Clearing file error indicators with clearerr
- file1.c
- In C, if you define int score = 0; in file1.c and then define int score = 0; again in file2.c, the compiler will get confused and throw a "multiple definition" error.
- Lesson 921 — Sharing variables across files with `extern`
- file2.c
- In C, if you define int score = 0; in file1.c and then define int score = 0; again in file2.c, the compiler will get confused and throw a "multiple definition" error.
- Lesson 921 — Sharing variables across files with `extern`
- fileno()
- You can actually extract the raw descriptor from a FILE pointer using the fileno() function.
- Lesson 1092 — File descriptors vs FILE pointers
- first
- When you use ++x (Prefix), the value is updated first, and then the expression is evaluated.
- Lesson 202 — Differences in expression resultsLesson 407 — Declaring 2D arrays: Rows and ColumnsLesson 427 — Searching for characters with `strchr`
- first dependency
- $<: Refers to the first dependency (the source file needed to build it).
- Lesson 822 — Automatic variables like `$@` and `$<`
- first member
- In C, when you initialize a union using curly braces { }, the compiler defaults to the first member defined in the union template.
- Lesson 660 — Initializing a union
- first piece of data
- The safest strategy is to initialize your variables using the first piece of data you encounter.
- Lesson 318 — Finding Min and Max in a loop
- First-fit
- In a First-fit mindset, you don't care if there is a "perfect" spot further down that fits your compact car exactly.
- Lesson 583 — Allocation strategies: First-fit
- fit into
- It calculates how many full units of y fit into x and hands you the leftover piece.
- Lesson 865 — Truncation and remainder: `trunc` and `fmod`
- five integers
- If you increment this pointer (array_ptr++), it jumps forward by the size of five integers at once, rather than just one.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- flag (e.g
- To make it clear, we often use the # flag (e.g., %#x).
- Lesson 689 — Printing hex and octal values
- flag3
- In the following example, we use a zero-width bit-field to ensure flag3 doesn't share a storage unit with the first two flags.
- Lesson 651 — Zero-width bit-fields for alignment
- flags
- By using flags—extra bits of text added to the command—you can tell the compiler exactly how you want it to behave.
- Lesson 57 — Basic `gcc` command flags
- flips that
- The second ! flips that 0 back into a 1.
- Lesson 174 — Operator `!` and boolean normalization
- float
- If you provide two different numeric types—like an int and a float—C won't crash, but it will perform "Type Promotion." It will force the smaller type to become the larger type so that the final answer is consistent.
- Lesson 52 — Printing decimals with `%f`Lesson 74 — Naming rules and identifiersLesson 97 — Single precision `float`Lesson 98 — Double precision `double`Lesson 99 — The `long double` typeLesson 100 — Scientific notation in CLesson 101 — Precision loss and rounding errorsLesson 102 — Formatting decimals with `%.nf`Lesson 103 — The `<float.h>` header fileLesson 104 — Comparing floats for equalityLesson 116 — Macros vs. Const variablesLesson 120 — Floating-point suffixes (f, L)Lesson 121 — What is type promotion?Lesson 123 — Hierarchy of types in expressionsLesson 124 — Automatic conversion in assignmentsLesson 125 — Risks of narrowing conversionsLesson 126 — The 'Usual Arithmetic Conversions'Lesson 128 — Common conversion pitfallsLesson 129 — The cast operator `(type)`Lesson 130 — Forcing floating-point divisionLesson 133 — Truncation during float-to-int castsLesson 135 — Readability and intent in castingLesson 150 — The addition operator `+`Lesson 151 — The subtraction operator `-`Lesson 153 — Integer division `/` truncationLesson 154 — Floating-point divisionLesson 155 — The modulo operator `%` with integersLesson 158 — Mixing int and float in arithmeticLesson 166 — Comparing floating-point numbersLesson 194 — Compound multiplication and divisionLesson 209 — Type consistency in ternary branchesLesson 229 — Usual arithmetic conversionsLesson 230 — The `(type)` cast operatorLesson 234 — Safety with explicit castsLesson 235 — The `sizeof` operator with typesLesson 262 — Switch restrictions: integral types onlyLesson 320 — Floating point precision issues in loop conditionsLesson 335 — Parameters vs. ArgumentsLesson 336 — Defining multiple parametersLesson 383 — Declaring an array with `type name[size]`Lesson 456 — The difference between `int *p` and `*p`Lesson 509 — Casting `void *` to specific typesLesson 511 — Generic functions in CLesson 520 — Defining `typedef` for function pointersLesson 527 — Pointer type-punning dangersLesson 599 — Defining a struct with the struct keywordLesson 606 — Returning a struct from a functionLesson 608 — Using typedef with primitive typesLesson 610 — Combining struct definition and typedefLesson 611 — Anonymous structs with typedef
- float myVar = 3.14
- If you are using a float (which takes up 4 bytes), but you write float myVar = 3.14;, the compiler actually sees a double (8 bytes) being squeezed into a smaller float container.
- Lesson 120 — Floating-point suffixes (f, L)
- float.h
- By using the limits defined in float.h, you acknowledge that floating-point math is "fuzzy" and give your program a specific threshold for what counts as "close enough."
- Lesson 907 — Precision and epsilon in `float.h`
- float*
- This rule assumes that pointers of different types (like int and float) will never point to the same memory location.
- Lesson 527 — Pointer type-punning dangersLesson 936 — Strict aliasing rule violations
- Floating-point types
- Floating-point types (like double and float) are at the top because they handle decimals.
- Lesson 229 — Usual arithmetic conversions
- floats
- %f: Used for floats (numbers with decimal points like 3.14).
- Lesson 49 — Introduction to Format Specifiers
- floor
- You need to know which floor the unit is on and then which door number it is on that specific floor.
- Lesson 407 — Declaring 2D arrays: Rows and ColumnsLesson 864 — Rounding with `ceil`, `floor`, and `round`
- floor()
- Conversely, if you are calculating how many full $10 gift cards a user can buy with $25.99, you use floor() because they don't quite have enough for that third card.
- Lesson 864 — Rounding with `ceil`, `floor`, and `round`
- Flow
- Instead, think of printf() as leaving a trail of breadcrumbs that tell you two specific things: State and Flow.
- Lesson 1157 — Strategic `printf()` debugging
- FLT_DIG
- Think of these numbers as a "guarantee." If FLT_DIG is 6, the C standard promises that any 6-digit decimal number can be stored and brought back without losing its value.
- Lesson 908 — Checking `FLT_DIG` and `DBL_DIG` for precision limits
- FLT_EPSILON
- Use FLT_EPSILON from <float.h> to compare floats by checking if their difference is smaller than the machine's limit of precision.
- Lesson 103 — The `<float.h>` header fileLesson 907 — Precision and epsilon in `float.h`
- FLT_MAX
- Instead of hard-coding a limit like 3.4028e+38, you use FLT_MAX, and your program will automatically adapt if it is ever moved to a different type of processor.
- Lesson 103 — The `<float.h>` header file
- fmod
- Use trunc to discard decimals without rounding, and use fmod as the floating-point version of the modulo (%) operator.
- Lesson 865 — Truncation and remainder: `trunc` and `fmod`
- folder path
- Use -L to specify the folder path and -l to specify the library name (minus the 'lib' prefix).
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- followed by a number between the
- By adding a 0 followed by a number between the % and the d, you tell C: "I want this number to be at least this many characters wide, and if it isn't, fill the empty space with zeros."
- Lesson 688 — Zero-padding numerical output
- following
- If you add parentheses greet(), you are following the recipe (calling the function).
- Lesson 515 — Taking the address of a function
- foo
- Instead of manually guessing which register the variable foo is in, you let C handle the mapping:
- Lesson 959 — Input and Output operands in assembly
- fopen
- Because tmpnam only gives you a name and doesn't lock the file, there is a tiny window of time between getting the name and calling fopen where another program could theoretically grab that same name.
- Lesson 709 — Opening files with fopenLesson 740 — Introduction to errnoLesson 741 — Using perror for descriptive errorsLesson 746 — Handling 'Disk Full' scenariosLesson 759 — Generating temp filenames with tmpnamLesson 1204 — Project scope: A custom `grep` cloneLesson 1206 — Opening and reading files line-by-lineLesson 1209 — Error handling for missing files
- FOPEN_MAX
- You can actually see what your specific environment guarantees by printing the FOPEN_MAX constant found in the <stdio.h> library.
- Lesson 715 — The maximum number of open files
- fopen()
- This creates a "file leak." Just like a water leak fills a bucket, a file leak fills up your "desk space." Eventually, fopen() will start returning NULL, not because the file doesn't exist, but because you've hit your limit.
- Lesson 710 — Understanding file modes: r, w, aLesson 711 — Closing files with fcloseLesson 712 — Checking for NULL file pointersLesson 713 — The difference between w and a modesLesson 714 — Handling file not found errorsLesson 715 — The maximum number of open filesLesson 721 — Detecting the end of a file with feofLesson 723 — Rewinding a file to the startLesson 724 — Text mode vs Binary mode (b flag)Lesson 745 — Handling 'Permission Denied' errorsLesson 758 — Creating temporary files with tmpfileLesson 762 — Checking if a file existsLesson 946 — Handling line endings across OSsLesson 1092 — File descriptors vs FILE pointersLesson 1206 — Opening and reading files line-by-lineLesson 1209 — Error handling for missing filesLesson 1217 — Saving the data store to a binary file
- for
- Complexity isn't just about length; it’s about "indentation depth." Every time you add an if statement inside a for loop inside another if statement, you are forcing the next programmer to hold a massive mental map of conditions just to understand one line of code.
- Lesson 4 — Standards: ANSI C vs C99 vs C11Lesson 120 — Floating-point suffixes (f, L)Lesson 224 — The comma operator `,`Lesson 240 — The comma operator in `for` loopsLesson 250 — Curly brace requirements for single vs multi-lineLesson 269 — Using while for indeterminate iterationsLesson 282 — The three parts of a for loop headerLesson 283 — Initialization, condition, and increment flowLesson 284 — Using the for loop as a counterLesson 285 — Scope of the loop variable in C99 vs C89Lesson 286 — Counting backwards with decrement operatorsLesson 287 — Using non-unit increments (e.g., i += 2)Lesson 288 — The comma operator in for loop headersLesson 289 — Optional components: the for(;;) infinite loopLesson 292 — Continue in while vs for loopsLesson 296 — Readability: when to avoid excessive breaksLesson 298 — Introduction to loops inside loopsLesson 300 — Using nested loops to print 2D gridsLesson 308 — Why goto is generally discouragedLesson 311 — The dangers of 'spaghetti code'Lesson 321 — Choosing the right loop for the taskLesson 353 — Concept of self-calling functionsLesson 358 — Iteration vs. Recursion comparisonLesson 364 — When to avoid recursionLesson 390 — Reading array values from user inputLesson 396 — Assigning values vs initializing arraysLesson 399 — Using `for` loops for array traversalLesson 400 — Printing array elements in a sequenceLesson 401 — Reverse traversal of an arrayLesson 402 — Finding the maximum value in an arrayLesson 403 — Calculating the sum and averageLesson 404 — Linear search for a specific valueLesson 405 — Avoiding off-by-one errors in loopsLesson 406 — Modifying all elements in a single passLesson 413 — Summing rows and columns individuallyLesson 430 — Setting memory blocks with `memset`Lesson 443 — Counting vowels and consonantsLesson 536 — Header file stdlib.h for allocationLesson 546 — Resizing blocks with reallocLesson 630 — Declaring an array of structsLesson 636 — Searching through struct arraysLesson 855 — Setting memory blocks with `memset`Lesson 964 — Compiler intrinsics as an alternativeLesson 966 — C99: Variable declarations and `bool`Lesson 972 — Specifying the standard with `-std=` flagsLesson 1061 — Linear Search on arraysLesson 1065 — Time complexity: O(n) vs O(log n)Lesson 1187 — The trap of premature optimizationLesson 1190 — Loop unrolling explainedLesson 1196 — Consistency: K&R vs. Allman style
- for (initialization; condition; increment)
- for (initialization; condition; increment)
- Lesson 283 — Initialization, condition, and increment flow
- for byte
- u: The unit size (b for byte, h for halfword/2 bytes, w for word/4 bytes).
- Lesson 839 — Examining raw memory with `x`
- for decimal
- f: The format (e.g., x for hex, d for decimal, c for char).
- Lesson 839 — Examining raw memory with `x`
- for halfword/2 bytes
- u: The unit size (b for byte, h for halfword/2 bytes, w for word/4 bytes).
- Lesson 839 — Examining raw memory with `x`
- for hex
- f: The format (e.g., x for hex, d for decimal, c for char).
- Lesson 839 — Examining raw memory with `x`
- for input or
- The File Descriptor: The ID of the file or stream (like 0 for input or 1 for output).
- Lesson 1097 — Reading and writing raw bytes
- for Red
- You could use the number 0 for Red, 1 for Yellow, and 2 for Green.
- Lesson 661 — Defining an enum type
- for rows and
- By convention, we use i for rows and j for columns.
- Lesson 411 — Nested `for` loops for 2D traversal
- for true or
- In C, a comparison isn't just an idea—it is an expression that evaluates to the integer 1 for true or 0 for false.
- Lesson 159 — Greater than `>` and less than `<`Lesson 164 — Boolean result of comparisons
- for you and
- The program might work fine on your machine but crash on another, simply because the "garbage" value happened to be 0 for you and 4291 for someone else.
- Lesson 569 — Detecting uninitialized value usage
- for(;;)
- A for(;;) loop creates an intentional infinite loop by omitting all three control expressions, serving as the heartbeat for programs that need to run indefinitely.
- Lesson 289 — Optional components: the for(;;) infinite loop
- Fork then Exec
- To start a new program while keeping our original one alive, we use a two-step pattern: Fork then Exec.
- Lesson 1083 — Combining fork() and exec()
- fork()
- They share the same code, the same variables, and even the same instruction pointer—meaning the child starts executing at the exact same line where the fork() was called.
- Lesson 1073 — Introduction to the fork() system callLesson 1074 — Handling fork() return valuesLesson 1075 — Process duplication and copy-on-writeLesson 1076 — Waiting for children with wait()Lesson 1077 — Capturing child exit statusLesson 1080 — The execve() family overviewLesson 1081 — Replacing process images with execl()Lesson 1083 — Combining fork() and exec()Lesson 1096 — The close-on-exec flagLesson 1101 — Creating pipes with pipe()Lesson 1102 — Unidirectional flow in pipesLesson 1103 — Closing unused pipe endsLesson 1104 — Piping data between parent and childLesson 1116 — Threads vs Processes
- formal shoes
- To let someone in, they must meet two criteria: they must have an invitation AND they must be wearing formal shoes.
- Lesson 253 — Short-circuit evaluation in logical AND
- format
- Those three dots (the ellipsis) tell the compiler: "Expect the format string first, but after that, anything goes."
- Lesson 376 — How `printf` works internally
- format specifier
- If you type printf("My age is age");, the computer will literally print the word "age." To fix this, we use a special placeholder called a format specifier.
- Lesson 50 — Printing integers with `%d`Lesson 87 — Printing integers with `%d` and `%ld`Lesson 99 — The `long double` type
- format specifiers
- We do this using format specifiers, which are special codes starting with a percent sign (%).
- Lesson 49 — Introduction to Format SpecifiersLesson 684 — Format specifiers recap
- format string
- The format string (the text inside quotes containing %d).
- Lesson 50 — Printing integers with `%d`
- forward declaration
- A forward declaration is a way of saying to the compiler: "Hey, there is a struct named Enemy coming later.
- Lesson 628 — Forward declarations of structsLesson 792 — Forward declarations in headersLesson 794 — Circular dependency issues
- four
- Even though "Cat" looks like it only has three characters, it actually takes up four slots in memory:
- Lesson 417 — The Null Terminator `\0` character
- fpos_t
- Future-proofing: Even if files get even larger in the future, your code using fpos_t will likely still work because the compiler manages the underlying data size.
- Lesson 738 — Using fgetpos and fsetpos for large files
- fprintf
- If you have a complex function that performs twenty printf calls to format a report, you don't need to rewrite it to use fprintf and pass a file pointer around.
- Lesson 677 — Introduction to stdin, stdout, and stderrLesson 718 — Formatted file output with fprintfLesson 720 — Sequential vs random access conceptsLesson 725 — Writing raw bytes with fwriteLesson 726 — Reading raw bytes with freadLesson 746 — Handling 'Disk Full' scenariosLesson 750 — Unbuffered output (stderr)Lesson 752 — Setting custom buffers with setvbufLesson 760 — Redirecting streams with freopen
- fprintf()
- When you call printf() or fprintf(), C doesn't usually talk to the hardware right away.
- Lesson 748 — How C buffers I/O for speedLesson 1092 — File descriptors vs FILE pointers
- fputc
- Use fgetc to read and fputc to write a single character, always checking for EOF with an integer variable to know when the file ends.
- Lesson 716 — Character I/O with fgetc and fputc
- fputc()
- Functions like fgetc() or fputc() handle one character at a time.
- Lesson 754 — Performance: Single char vs block I/O
- fputs
- What you'll learn: How to safely read and write whole lines of text in files using the fgets and fputs functions.
- Lesson 717 — String I/is with fgets and fputsLesson 746 — Handling 'Disk Full' scenarios
- fragmentation
- Furthermore, arenas eliminate fragmentation and "manual memory management exhaustion." You don't have to track every single pointer or worry about a free() call for every malloc().
- Lesson 578 — Motivation for custom allocatorsLesson 591 — Trade-offs of arena vs malloc
- fread
- When a function like fread or fgetc hits the end of a file or encounters a hardware glitch, the stream sets an internal flag (a "sticky note") indicating an error or EOF (End Of File).
- Lesson 726 — Reading raw bytes with freadLesson 727 — The size and count parametersLesson 731 — Verifying bytes read vs expectedLesson 744 — Clearing file error indicators with clearerrLesson 754 — Performance: Single char vs block I/OLesson 1218 — Loading data from a binary file
- fread()
- What you'll learn: How to use fread() to instantly reconstruct complex data structures from a binary file back into your program's variables.
- Lesson 727 — The size and count parametersLesson 729 — Reading structs back into memoryLesson 754 — Performance: Single char vs block I/O
- free
- Note: Modern C standards discourage using realloc(ptr, 0) to replace free because it can lead to portability issues, but understanding this behavior helps you see the full spectrum of how realloc manages the heap.
- Lesson 536 — Header file stdlib.h for allocationLesson 541 — The free function signatureLesson 546 — Resizing blocks with reallocLesson 547 — Handling realloc failure safelyLesson 549 — Using realloc as malloc or freeLesson 552 — Leaking in loops and recursionLesson 557 — What is a dangling pointerLesson 566 — Reading 'definitely lost' reportsLesson 578 — Motivation for custom allocatorsLesson 620 — Allocating structs on the heap with mallocLesson 672 — Flexible array members in C99Lesson 868 — Allocating memory with `malloc` and `free`Lesson 988 — Freeing the dynamic arrayLesson 1026 — Pre-order and Post-order traversalLesson 1046 — Graph memory managementLesson 1165 — Installing and running `valgrind`Lesson 1169 — Reading the Valgrind leak summaryLesson 1185 — Profiling memory allocation frequencyLesson 1192 — Preferring stack allocation over heapLesson 1219 — Final memory leak check and cleanup
- Free after use
- The Free after use rule states that for every single time you ask for memory, you must explicitly give it back using the free() function once you are finished with it.
- Lesson 553 — The 'Free after use' rule
- FREE_SHIPPING_THRESHOLD
- Readability: FREE_SHIPPING_THRESHOLD tells a story; 50.00 is just a digit.
- Lesson 771 — Avoiding magic numbers with macros
- free()
- If you call free() on the same pointer a second time, you are "double-freeing." This isn't just a minor mistake; it’s a critical error that usually causes your program to crash instantly or, worse, creates a security hole that hackers can exploit.
- Lesson 522 — Dangling pointers after `free`Lesson 523 — Memory leaks and lost pointersLesson 528 — Tools for pointer debugging (Valgrind)Lesson 534 — Scope of heap-allocated dataLesson 535 — Stack pointers vs Heap pointersLesson 542 — Why freeing NULL is safeLesson 550 — Definition of a memory leakLesson 551 — Losing the last pointer to a blockLesson 553 — The 'Free after use' ruleLesson 554 — Double-freeing a pointerLesson 555 — Invalid pointer increments before freeLesson 557 — What is a dangling pointerLesson 559 — Setting pointers to NULL after freeLesson 562 — Use-after-free vulnerabilitiesLesson 563 — Out-of-bounds array access on heapLesson 564 — Installing Valgrind MemcheckLesson 566 — Reading 'definitely lost' reportsLesson 581 — The concept of memory fragmentationLesson 585 — What is a Memory ArenaLesson 586 — Linear or Bump allocatorsLesson 587 — Resetting an arena in one stepLesson 588 — Arena allocation for frame-based tasksLesson 591 — Trade-offs of arena vs mallocLesson 593 — Using mmap for large allocationsLesson 596 — The munmap functionLesson 621 — Freeing dynamically allocated structsLesson 988 — Freeing the dynamic arrayLesson 996 — Deleting a node by valueLesson 997 — Memory cleanup for linked listsLesson 1008 — Linked list-based stack implementationLesson 1164 — What is a memory leak?Lesson 1166 — Identifying 'Invalid Read' errorsLesson 1167 — Tracking down 'Use After Free' bugsLesson 1170 — Cleaning up heap memory before exitLesson 1171 — Using AddressSanitizer (`-fsanitize=address`)
- free(current)
- If we called free(current) before assigning nextNode = current->next, we would be attempting to access current->next from memory that we no longer own.
- Lesson 997 — Memory cleanup for linked lists
- free(graph)
- Because of this layering, you cannot simply call free(graph) and expect everything to disappear.
- Lesson 1046 — Graph memory management
- free(NULL)
- Calling free(NULL) is completely safe and does nothing, so you don't need to wrap every free() call in an if statement.
- Lesson 522 — Dangling pointers after `free`Lesson 542 — Why freeing NULL is safeLesson 554 — Double-freeing a pointer
- free(numbers)
- It will tell you exactly which line caused the invalid write and confirm that 40 bytes were "definitely lost" because you forgot to free(numbers).
- Lesson 528 — Tools for pointer debugging (Valgrind)
- free(ptr)
- When you call free(ptr), you are telling the computer, "I am done with this memory; you can give it to someone else." The computer marks that memory as available, but it does not wipe the address stored inside your ptr variable.
- Lesson 554 — Double-freeing a pointerLesson 559 — Setting pointers to NULL after freeLesson 562 — Use-after-free vulnerabilitiesLesson 868 — Allocating memory with `malloc` and `free`
- free(scores)
- When you call free(scores), the memory is released, but the pointer scores still holds the address of that memory.
- Lesson 988 — Freeing the dynamic array
- freopen
- By calling freopen, you flip a lever that reroutes that same train onto a different track heading toward "File.txt." The train (your code) doesn't know the tracks have changed; it just keeps moving forward, but it ends up at a different destination.
- Lesson 760 — Redirecting streams with freopen
- from
- In this code, we subtract b from INT_MAX to find the "ceiling." If a is already higher than that ceiling, adding b is guaranteed to overflow.
- Lesson 1154 — Safe integer arithmetic and overflow checks
- front
- If the queue was completely empty before this operation, we also have to point the front at this first element, as they are now both the first and last person in line.
- Lesson 1015 — Front and Rear pointersLesson 1016 — Enqueue operation logicLesson 1017 — Dequeue operation logicLesson 1018 — Circular array implementationLesson 1020 — Linked list queue implementation
- fscanf
- When you use fscanf to read a text file, the computer has to look at every character, decide if it's a digit or a letter, and then calculate the numerical value.
- Lesson 717 — String I/is with fgets and fputsLesson 719 — Formatted file input with fscanfLesson 722 — Why feof inside a loop condition is badLesson 723 — Rewinding a file to the startLesson 726 — Reading raw bytes with freadLesson 1218 — Loading data from a binary file
- fscanf()
- In C, many input functions like fgetc() or fscanf() return a special constant called EOF when they can no longer read data.
- Lesson 743 — Distinguishing EOF from errors with ferror
- fseek
- In text mode, fseek is more like a teleportation device that only works reliably if you have the exact coordinates provided by the file system itself.
- Lesson 733 — Moving the pointer with fseekLesson 738 — Using fgetpos and fsetpos for large filesLesson 739 — Risks of seeking in text mode
- fseek()
- The fseek() function requires three pieces of information: the file pointer, how many bytes to move (the offset), and a starting reference point.
- Lesson 733 — Moving the pointer with fseekLesson 734 — The SEEK_SET, SEEK_CUR, SEEK_END constantsLesson 736 — Finding file size using seek and tellLesson 758 — Creating temporary files with tmpfile
- fsetpos
- You don't necessarily need to know what’s written on the bookmark; you just hand it back to the computer later using fsetpos, and the computer instantly flips to that exact spot.
- Lesson 738 — Using fgetpos and fsetpos for large files
- ftell
- Saving State: If you are processing a massive data file and need to pause, you can save the ftell value to a variable or a config file, then resume from that exact byte later.
- Lesson 735 — Getting current position with ftellLesson 736 — Finding file size using seek and tellLesson 738 — Using fgetpos and fsetpos for large filesLesson 739 — Risks of seeking in text mode
- ftell()
- ftell(): We use this to report the current byte offset.
- Lesson 736 — Finding file size using seek and tell
- ftell(file)
- When you call ftell(file), it returns a long integer representing how many bytes away from the start of the file you are.
- Lesson 736 — Finding file size using seek and tell
- FuelPump
- If you have a Car struct, and inside that Car is an Engine struct, and inside that Engine is a FuelPump struct, you can’t jump straight to the pump.
- Lesson 624 — Accessing members of nested structs
- full buffering
- When you write to a file, C switches to full buffering.
- Lesson 749 — Full buffering vs Line buffering
- func()
- To avoid these bugs, never pass expressions that change values (like i++, --j, or func()) into a macro.
- Lesson 775 — Side effects in macro arguments
- function A
- However, if you want to use function A (defined in file_1.c) inside file_2.c, file_2.c needs a declaration so it knows the function's name, return type, and parameters.
- Lesson 922 — Using `extern` with functions
- function definition
- The Source (math_utils.c): Contains the function definition.
- Lesson 796 — Splitting code into `.c` and `.h`
- function pointer
- A function pointer is simply a variable that stores that starting address, allowing you to "hold" a function in your hand and pass it around your code.
- Lesson 514 — Syntax of function pointersLesson 519 — The `qsort` callback mechanismLesson 675 — Implementing an interface with function pointers in structsLesson 928 — Declaring pointers to functions
- Function Prototype
- A function prototype acts like an "upcoming attractions" trailer; it tells the compiler, "Hey, a function with this specific name and shape exists, and you’ll find the full details later."
- Lesson 326 — Placement of functions in a fileLesson 329 — Implicit vs. explicit declarationsLesson 330 — Function prototype syntaxLesson 331 — Benefits of forward declarationLesson 796 — Splitting code into `.c` and `.h`Lesson 965 — K&R C vs C89/C90 ANSI
- function prototypes
- A header file typically contains function prototypes.
- Lesson 377 — Role of the `.h` file
- function-like macro
- A function-like macro takes this a step further.
- Lesson 772 — Defining function-like macros
- FunctionA
- If FunctionA needs to call FunctionB, but FunctionB also needs to call FunctionA, it is impossible to define one "before" the other.
- Lesson 331 — Benefits of forward declarationLesson 454 — Introduction to the stack frame
- functionA()
- When main() calls functionA(), a new frame for functionA is placed (or "pushed") on top of main.
- Lesson 454 — Introduction to the stack frame
- functional
- Think of the ternary operator as a functional tool and if-else as a procedural tool.
- Lesson 210 — Ternary vs If-Else for assignments
- FunctionB
- If FunctionA needs to call FunctionB, but FunctionB also needs to call FunctionA, it is impossible to define one "before" the other.
- Lesson 331 — Benefits of forward declaration
- functions have a home in memory
- Just like variables, functions have a home in memory.
- Lesson 515 — Taking the address of a function
- functions.c
- If you forgot to include functions.c, the linker would throw an error because it found a "call" but no "destination."
- Lesson 59 — Compiling multiple source filesLesson 806 — Linking multiple object files
- functions.o
- The linker then looks at main.o, sees the request for greet(), finds the actual code for greet() inside functions.o, and patches the two together into the final my_program executable.
- Lesson 806 — Linking multiple object files
- fwrite
- What you'll learn: How to use the two numerical arguments in fread and fwrite to precisely control how much data moves between your memory and a binary file.
- Lesson 725 — Writing raw bytes with fwriteLesson 727 — The size and count parametersLesson 728 — Writing entire structs to diskLesson 752 — Setting custom buffers with setvbufLesson 754 — Performance: Single char vs block I/O
- fwrite()
- Use fwrite() with the "wb" mode to copy raw structs from memory to a file, providing a fast and efficient way to persist your data store.
- Lesson 727 — The size and count parametersLesson 729 — Reading structs back into memoryLesson 754 — Performance: Single char vs block I/OLesson 1217 — Saving the data store to a binary file
G
- game_logic.c
- We define our global variable in main.c, and we want to modify it inside a function in game_logic.c.
- Lesson 146 — The `extern` keyword for multi-file code
- game.c
- This means if you define int global_score = 100; in game.c, you can access that exact same memory location in ui.c by using the extern keyword.
- Lesson 918 — Internal vs external linkage basics
- game.h
- If you accidentally include it twice—perhaps because main.c includes player.h and also includes game.h, which itself includes player.h—the compiler sees the same code twice in a row.
- Lesson 789 — The 'duplicate definition' errorLesson 790 — Creating basic include guardsLesson 925 — Common linkage errors and 'multiple definition'
- garbage value
- This leftover data is known as a garbage value.
- Lesson 77 — Garbage values and uninitialized variables
- gcc
- When you run the gcc command, the compiler looks at main.c, sees that it needs an add function, finds that function inside math_utils.c, and glues them together.
- Lesson 6 — C as a compiled languageLesson 30 — Creating an executable binaryLesson 32 — Executing from the command lineLesson 57 — Basic `gcc` command flagsLesson 59 — Compiling multiple source filesLesson 61 — Introduction to `make` and MakefilesLesson 62 — Automating the build processLesson 69 — Enabling all warnings with `-Wall`Lesson 381 — Compiling multiple `.c` filesLesson 767 — How `gcc -E` shows preprocessor outputLesson 803 — From source code to object filesLesson 805 — What is inside a `.o` fileLesson 812 — Linking with static librariesLesson 818 — Structure of a Makefile RuleLesson 819 — Targets, dependencies, and recipesLesson 820 — The importance of Tab charactersLesson 821 — Using variables in MakefilesLesson 825 — Compiling with debug symbols `-g`Lesson 1160 — Compiling with `-g` for debug symbolsLesson 1182 — Introduction to the `gprof` profilerLesson 1188 — Compiler optimization levels (`-O1`, `-O2`, `-O3`)
- gcc -E
- Use gcc -E to stop the build process early and view the final, expanded text that the preprocessor hands off to the compiler.
- Lesson 767 — How `gcc -E` shows preprocessor output
- gcc -E hello.c
- If you run the command gcc -E hello.c, your terminal will fill with text.
- Lesson 767 — How `gcc -E` shows preprocessor output
- gcc -E hello.c -o preprocessed_output.txt
- gcc -E hello.c -o preprocessed_output.txt
- Lesson 767 — How `gcc -E` shows preprocessor output
- gcc -fPIC -c math_utils.c -o math_utils.o
- gcc -fPIC -c math_utils.c -o math_utils.o
- Lesson 814 — Position Independent Code `-fPIC`
- gcc -fsanitize=address -g my_program.c -o my_program
- gcc -fsanitize=address -g my_program.c -o my_program
- Lesson 1171 — Using AddressSanitizer (`-fsanitize=address`)
- gcc -fsanitize=undefined main.c -o program
- gcc -fsanitize=undefined main.c -o program
- Lesson 941 — Tools to detect UB: UBSan
- gcc -g
- If you compile the code above with gcc -g, and then open it in GDB, you can type list to see your actual C code or print secret_number to see its value.
- Lesson 825 — Compiling with debug symbols `-g`
- gcc -g main.c -o my_program
- gcc -g main.c -o my_program (Map included!)
- Lesson 825 — Compiling with debug symbols `-g`
- gcc -g my_program.c -o my_program
- Compile: gcc -g my_program.c -o my_program
- Lesson 1165 — Installing and running `valgrind`
- gcc -o main.c my_app
- Incorrect: gcc -o main.c my_app (This would actually try to overwrite your source code!)
- Lesson 58 — Naming the output with `-o`
- gcc -std=c89
- If you try to compile the code above with gcc -std=c89, the compiler will complain because int i inside the loop wasn't allowed yet.
- Lesson 972 — Specifying the standard with `-std=` flags
- gcc -v
- By typing gcc -v, you have confirmed that your toolchain is linked and ready to turn your future text files into powerful software.
- Lesson 10 — Installing GCC on Linux/macOS
- gcc -Wall hello.c -o hello
- But if you run gcc -Wall hello.c -o hello, the compiler will give you a friendly heads-up.
- Lesson 57 — Basic `gcc` command flags
- gcc -Wall main.c
- However, if you compile with gcc -Wall main.c, the compiler will shout:
- Lesson 69 — Enabling all warnings with `-Wall`
- gcc 11.4.0
- If you see a wall of text that includes a version number (like gcc 11.4.0 or Apple clang version...), you are successful!
- Lesson 10 — Installing GCC on Linux/macOS
- gcc hello.c
- By default, if you run gcc hello.c, the compiler creates a generic executable file named a.out (or a.exe on Windows).
- Lesson 57 — Basic `gcc` command flagsLesson 58 — Naming the output with `-o`Lesson 60 — Understanding the `a.out` default
- gcc hello.c -o hello
- This is why, as you move toward professional development, you will eventually start using the -o (output) flag to give your programs unique names, like gcc hello.c -o hello.
- Lesson 60 — Understanding the `a.out` default
- gcc hello.c -o my_program
- By typing gcc hello.c -o my_program, the compiler processes your text and creates a new file named my_program.
- Lesson 30 — Creating an executable binary
- gcc main.c
- When you run a standard command like gcc main.c, the compiler is in its polite, quiet mode.
- Lesson 69 — Enabling all warnings with `-Wall`Lesson 786 — Feature toggles via command line `-D`Lesson 804 — The `-c` flag for compilation
- gcc main.c -L. -lmathutils -o my_program
- gcc main.c -L. -lmathutils -o my_program
- Lesson 812 — Linking with static libraries
- gcc main.c -lm
- On some systems (like Linux), when you use <math.h>, you need to tell the compiler to link the math library manually by adding -lm to the end of your compile command, like this: gcc main.c -lm.
- Lesson 861 — Basic power and square root: `pow` and `sqrt`
- gcc main.c -o app
- When you run make, Make sees $@ and thinks, "The target is app, so I'll put that there." It sees $< and thinks, "The first dependency is main.c, so I'll put that there." The actual command executed remains gcc main.c -o app.
- Lesson 822 — Automatic variables like `$@` and `$<`
- gcc main.c -o main
- As your C projects grow, typing gcc main.c -o main every time you make a change becomes tedious.
- Lesson 818 — Structure of a Makefile Rule
- gcc main.c -o my_program
- When you run gcc main.c -o my_program, the linker wraps that printf call and the "Hello" string into the ELF structure.
- Lesson 62 — Automating the build processLesson 808 — The executable ELF formatLesson 815 — Linking with shared libraries `-l` and `-L`Lesson 817 — Why we need build toolsLesson 825 — Compiling with debug symbols `-g`
- gcc main.c -o program
- Up until now, you have likely been compiling your code by typing a command like gcc main.c -o program every single time you make a change.
- Lesson 61 — Introduction to `make` and Makefiles
- gcc main.c functions.c -o my_app
- As your C projects grow, typing gcc main.c functions.c -o my_app every time you make a change becomes tedious.
- Lesson 819 — Targets, dependencies, and recipes
- gcc main.c utils.c tools.c -o mytool
- As your command-line utility grows to include multiple .c and .h files, typing gcc main.c utils.c tools.c -o mytool over and over becomes exhausting and error-prone.
- Lesson 1211 — Writing the Makefile for the project
- gcc src/main.c src/physics.c -Iinclude -o my_app
- When you compile, you would run a command like gcc src/main.c src/physics.c -Iinclude -o my_app.
- Lesson 800 — Organizing /src and /include folders
- gcc test.c -o test
- After compiling with gcc test.c -o test, you would run it using:
- Lesson 564 — Installing Valgrind Memcheck
- gdb
- Compile with the -g flag, then use the run command inside gdb or lldb to execute your program under professional supervision.
- Lesson 826 — Starting GDB with an executableLesson 1161 — Starting a program in `gdb` or `lldb`
- gdb -p <PID>
- Use gdb -p <PID> to hijack a running process, allowing you to debug live issues without restarting the software.
- Lesson 838 — Attaching GDB to a running process
- gdb ./filename
- To debug a program, compile with the -g flag and launch it using gdb ./filename to enter the interactive debugging environment.
- Lesson 826 — Starting GDB with an executable
- gdb ./my_program
- Once you have started GDB in your terminal (usually by typing gdb ./my_program), you will see a prompt that looks like (gdb).
- Lesson 827 — The `run` and `quit` commands
- gear
- If gear is 2, it skips case 1 and goes straight to case 2.
- Lesson 258 — Basic switch syntax and cases
- generic function
- A generic function is like a universal shipping container; it doesn't care what is inside as long as it follows basic handling instructions.
- Lesson 511 — Generic functions in C
- generic_swap
- When we call generic_swap, we cast our specific data addresses into void *.
- Lesson 511 — Generic functions in C
- get_operation
- If we want a function named get_operation that returns a pointer to a function taking two ints and returning an int, it looks like this:
- Lesson 929 — Returning pointers to functions from functions
- get_operation(char op)
- get_operation(char op): This is our function name and its parameter.
- Lesson 929 — Returning pointers to functions from functions
- get_rectangle_stats
- In this example, get_rectangle_stats has a void return type because it doesn't use the standard return slot.
- Lesson 489 — Returning multiple values via pointers
- get_wind_speed()
- If get_wind_speed() connects to a real weather sensor that is currently broken or fluctuating, your test will fail—even if your landing logic is perfect.
- Lesson 1176 — Mocking simple dependencies
- getchar
- But if your next line is a command that reads any character (like getchar or a string input), it will see that leftover Enter key, think you've already pressed Enter for the new prompt, and skip right past it.
- Lesson 697 — How scanf leaves trailing newlines
- getchar()
- If a user types "Apple" and hits Enter, getchar() will grab the 'A' and leave 'p', 'p', 'l', 'e', and the 'newline' character sitting in a hidden waiting area called the input buffer.
- Lesson 680 — Basic character input with getcharLesson 681 — EOF (End Of File) explainedLesson 682 — Using while loops with getcharLesson 683 — Relationship between char and int in I/OLesson 1093 — Standard streams (0, 1, 2)
- getchar() != EOF
- A while loop paired with getchar() != EOF allows you to process input of any length character-by-character until the user signals they are finished.
- Lesson 682 — Using while loops with getchar
- getenv
- What you'll learn: How to access and retrieve configuration data from the operating system's environment using the getenv function.
- Lesson 1071 — Environment variables in C
- getenv()
- Use getenv() to fetch external configuration data, but always check for NULL to ensure the variable actually exists.
- Lesson 1071 — Environment variables in C
- getpid()
- To find out the "passport number" of your own program while it is running, you use a simple function from the unistd.h library called getpid().
- Lesson 1067 — What is a process ID (PID)Lesson 1068 — Getting PID with getpid()
- getppid()
- Every process is born from another; use getppid() to retrieve the unique ID of the process that started the current one.
- Lesson 1069 — Parent processes and getppid()Lesson 1079 — Handling orphaned processes
- gets
- If you gave it a small bucket (a character array) and the user typed a giant waterfall of text, gets would just keep pouring until it spilled over, overwriting other important data in your computer's memory.
- Lesson 706 — The buffer size argument in fgets
- gets()
- If a user types "Administrator", which is 13 characters long, gets() will happily shove those extra letters into memory locations it doesn't own.
- Lesson 432 — Why `gets` is dangerous and deprecatedLesson 699 — Why gets is dangerous and deprecatedLesson 1152 — Why `gets()` is strictly forbidden
- gets(my_buffer)
- When you use gets(my_buffer), you are telling C to take whatever the user types and shove it into my_buffer.
- Lesson 432 — Why `gets` is dangerous and deprecated
- gl
- The OpenGL library prefixes everything with gl (e.g., glVertex3f), and the SDL library prefixes everything with SDL_.
- Lesson 801 — Naming conventions for large projects
- Global Offset Table (GOT)
- This flag tells the compiler to generate a Global Offset Table (GOT).
- Lesson 814 — Position Independent Code `-fPIC`
- global variable
- In C, a global variable is that communal fridge.
- Lesson 142 — The dangers of global variables
- Global variables
- Global variables, however, are like a statue in the Town Square.
- Lesson 137 — Global variables and file scopeLesson 913 — The `volatile` qualifier for hardware mapping
- global_score
- If global_score is defined in game.h, and both player.c and enemy.c include it, they both end up trying to create their own version of that variable.
- Lesson 921 — Sharing variables across files with `extern`Lesson 925 — Common linkage errors and 'multiple definition'
- global_volume
- The linker sees these two separate object files, notices they both have a variable named global_volume, and throws the error because it doesn't know which one is the "real" one.
- Lesson 925 — Common linkage errors and 'multiple definition'
- glVertex3f
- The OpenGL library prefixes everything with gl (e.g., glVertex3f), and the SDL library prefixes everything with SDL_.
- Lesson 801 — Naming conventions for large projects
- gmon.out
- When it finishes, it will automatically generate a file named gmon.out.
- Lesson 1182 — Introduction to the `gprof` profiler
- gmtime
- Specifically, gmtime converts the time to UTC (Greenwich Mean Time), which is the global scientific standard, ignoring local time zones or daylight savings.
- Lesson 893 — Converting `time_t` to UTC with `gmtime`
- goal
- Imagine you have a box called goal containing the number 100.
- Lesson 238 — The Indirection operator `*`
- goes to
- In the code above, the compiler looks at the first pair {0, 0} and knows that 0 goes to x and the second 0 goes to y because that is the order defined in the struct Point.
- Lesson 631 — Initializing arrays of structs
- goes up by one and
- Increment (i++, j--): At the end of every lap, i goes up by one and j goes down by one.
- Lesson 240 — The comma operator in `for` loops
- gold
- That key opens a safe containing the gold (the actual data).
- Lesson 505 — Accessing data through double dereference
- goldCoins = 100
- You might wonder: "Why not just write goldCoins = 100?" In a simple program, you would.
- Lesson 458 — Assigning values via pointers
- goodbye.c
- If you then write a completely different program called goodbye.c and compile that without specifying a name, the compiler will create a new a.out and overwrite the old one.
- Lesson 60 — Understanding the `a.out` default
- Google C Style Guide
- They follow established guides like the Google C Style Guide or the Kernel Style.
- Lesson 40 — C coding style guides
- goto
- A goto statement is like a step that says, "Now jump to the middle of a different recipe on page 42." If you use too many of these jumps, your program’s logic becomes tangled, intertwined, and impossible to follow—much like a bowl of tangled pasta.
- Lesson 306 — Defining labels in C codeLesson 307 — The syntax of the goto statementLesson 308 — Why goto is generally discouragedLesson 309 — Legitimate use case: breaking out of nested loopsLesson 310 — Legitimate use case: error cleanup blocksLesson 311 — The dangers of 'spaghetti code'Lesson 312 — Function returns as a control flow mechanism
- goto cleanup
- Readability: It is immediately clear to other programmers that goto cleanup means "something went wrong; get us out of here safely."
- Lesson 310 — Legitimate use case: error cleanup blocks
- goto found
- By using goto found;, we bypass the remainder of the inner loop, the remainder of the outer loop, and any code sitting between the loops and the label.
- Lesson 309 — Legitimate use case: breaking out of nested loops
- goto my_label
- The Colon: The label destination ends with a colon (my_label:), but the goto command ends with a semicolon (goto my_label;).
- Lesson 307 — The syntax of the goto statement
- gpa
- Each element in the array (classroom[0], classroom[1], etc.) is a complete structure with its own name, id, and gpa.
- Lesson 630 — Declaring an array of structs
- gprof
- gprof is a classic tool for Linux and Unix systems that tracks how many times each function is called and how many milliseconds the CPU spends inside them.
- Lesson 1182 — Introduction to the `gprof` profilerLesson 1183 — Identifying 'Hot Spots' in your code
- grade
- Because the ternary operator is an expression, it allows for "Inline Logic." In the example above, we didn't just use it to set the grade variable; we actually put a second ternary operator directly inside the printf function.
- Lesson 51 — Printing characters with `%c`Lesson 207 — Ternary as an expressionLesson 239 — Member access `.` and `->`Lesson 262 — Switch restrictions: integral types onlyLesson 602 — Initializing structs with brace notationLesson 635 — Sorting an array of structsLesson 879 — Sorting structs by multiple fields
- Graph
- In the world of computer science, we call this map a Graph.
- Lesson 1039 — Vertices and Edges definition
- graph[V][V]
- We assume we have an adjacency matrix graph[V][V] and a simple queue array.
- Lesson 1044 — Breadth-First Search (BFS) logic
- Graphical User Interface (GUI)
- When you use an operating system like Windows or macOS, you are using a Graphical User Interface (GUI).
- Lesson 12 — Introduction to the CLI
- graphics.c
- If physics.c includes constants.h, and graphics.c includes constants.h, and then main.c includes both physics.h and graphics.h, the contents of constants.h will be pasted into your main file multiple times.
- Lesson 789 — The 'duplicate definition' errorLesson 799 — The role of the 'main' fileLesson 817 — Why we need build tools
- graphics.h
- If physics.c includes constants.h, and graphics.c includes constants.h, and then main.c includes both physics.h and graphics.h, the contents of constants.h will be pasted into your main file multiple times.
- Lesson 789 — The 'duplicate definition' error
- gravity_constant
- If you are setting the player_age and the gravity_constant, keep them on separate lines!
- Lesson 196 — Chained assignments `a = b = c`
- greater
- Left Scout: Starts at the beginning and moves right until it finds a value greater than the pivot.
- Lesson 1056 — Quick Sort: Partitioning logic
- Greater than
- This is where the Greater than (>) and Less than (<) operators come in.
- Lesson 159 — Greater than `>` and less than `<`
- GREEN
- GREEN is the "0-th" item, YELLOW is 1, and RED is 2.
- Lesson 662 — Default integer values in enums
- greet
- When the computer reaches greet(); inside the main function, it "jumps" to the greet definition, executes all the code inside those curly braces, and then "jumps" back to exactly where it left off in main.
- Lesson 322 — What is a function?Lesson 351 — Visualizing the stack during nested callsLesson 515 — Taking the address of a function
- greet()
- When the computer reaches greet(); inside the main function, it "jumps" to the greet definition, executes all the code inside those curly braces, and then "jumps" back to exactly where it left off in main.
- Lesson 140 — Automatic duration variablesLesson 322 — What is a function?Lesson 351 — Visualizing the stack during nested callsLesson 515 — Taking the address of a functionLesson 806 — Linking multiple object files
- greeting
- Even though name is longer, the program remains stable because we didn't exceed the 15-byte limit of the greeting array.
- Lesson 425 — Concatenating strings with `strcat`Lesson 436 — Using `strncat` for safer concatenationLesson 767 — How `gcc -E` shows preprocessor output
- greetings.c
- The compiler looks at main.c, sees that it needs a function called say_hello, finds that function inside greetings.c, and stitches them together.
- Lesson 59 — Compiling multiple source files
- greetUser
- When it hits the line greetUser();, the computer pauses what it's doing in main and looks for the block of code labeled greetUser.
- Lesson 325 — Writing your first custom function
- greetUser()
- When it hits the line greetUser();, the computer pauses what it's doing in main and looks for the block of code labeled greetUser.
- Lesson 325 — Writing your first custom function
- grep
- Most professional tools allow users to change how the program behaves by passing "flags." For example, grep uses -i to ignore case sensitivity.
- Lesson 1080 — The execve() family overviewLesson 1105 — Redirecting stdout to a pipeLesson 1204 — Project scope: A custom `grep` cloneLesson 1207 — Implementing string pattern matchingLesson 1208 — Adding command line flags (e.g., `-i` for case)
- grid[0]
- It takes the first inner set and places those values into the first row (grid[0]).
- Lesson 409 — Initializing 2D arrays with nested braces
- grid[1]
- It then takes the second inner set and places them into the second row (grid[1]).
- Lesson 409 — Initializing 2D arrays with nested braces
- grid[i][j]
- When the code runs grid[i][j], it is saying: "Go to row i, then find item j."
- Lesson 411 — Nested `for` loops for 2D traversal
- guaranteed to run at least once
- This means the code inside a do-while loop is guaranteed to run at least once, no matter what.
- Lesson 279 — Comparing while vs do-while use cases
- guest list with addresses
- An array of pointers, however, is like a guest list with addresses.
- Lesson 483 — Array of strings vs 2D char array
H
- had higher precedence than
- If = had higher precedence than +, the code wouldn't make any sense!
- Lesson 212 — Operator precedence table
- handle_interruption
- The operating system forcibly interrupts the while loop, jumps to the handle_interruption function, and then returns to the loop once the function finishes.
- Lesson 1084 — What are Unix signals
- handle_sigint
- Instead, pause my execution and jump to the handle_sigint function."
- Lesson 1087 — Basic signal handling with signal()
- Handler
- Self-documentation: The name Handler tells the next programmer what that function's purpose is, which the raw syntax struct Task (ptr)(int) fails to do.
- Lesson 930 — Complex nested `typedef` structures
- has higher precedence than
- They assume that because * has higher precedence than +, the computer must calculate everything related to the multiplication before even looking at the addition.
- Lesson 216 — Precedence of `*` over `+`Lesson 227 — Order of evaluation vs Precedence
- has_
- Booleans should be questions: If a variable is true or false, prefix it with is_, has_, or can_.
- Lesson 1197 — Meaningful variable naming conventions
- hash
- By adding the original hash to it ((hash << 5) + hash), we effectively multiply by 33.
- Lesson 1038 — String hashing with DJB2
- Hash Function
- Instead, you put the book's title into a special machine called a Hash Function.
- Lesson 1036 — Hash table lookupLesson 1038 — String hashing with DJB2
- haystack
- You have a large field (the haystack) and you are waving your detector to find a specific metal object (the needle).
- Lesson 852 — Finding substrings with `strstr`
- head
- However, there is a small catch: if the node you are deleting is the Head, you must still update your Head pointer variable in your main program to point to target->next, otherwise your program will try to start the list at a memory location that no longer exists.
- Lesson 579 — Building a simple free listLesson 992 — Traversing the list with a while loopLesson 993 — Prepending nodes to the headLesson 994 — Appending nodes to the tailLesson 996 — Deleting a node by valueLesson 997 — Memory cleanup for linked listsLesson 1000 — Handling the tail pointerLesson 1001 — Bidirectional traversalLesson 1003 — Deleting without head traversalLesson 1008 — Linked list-based stack implementation
- head_ref
- Note that we pass a pointer to the head pointer (head_ref) so we can modify the original head back in the main function.
- Lesson 993 — Prepending nodes to the head
- head->prev
- In a standard doubly linked list, the head->prev and tail->next pointers both point to NULL.
- Lesson 1004 — Circular doubly linked lists
- header
- A function definition consists of a header and a body.
- Lesson 323 — Anatomy of a function definition
- header file
- Instead, you put the recipe in its own folder (a source file) and put the name of the dish on a menu (a header file).
- Lesson 382 — Sharing functions across modulesLesson 788 — The purpose of header files
- Header Files
- To stay organized, C programmers split code into two specific types of files: Source files (.c) and Header files (.h).
- Lesson 378 — Separating interface from implementationLesson 796 — Splitting code into `.c` and `.h`
- Header Guard
- A Header Guard is a special wrapper made of preprocessor directives that acts like a velvet rope at a club.
- Lesson 380 — Header Guards: `#ifndef` and `#define`
- heading
- Think of it this way: you use a semicolon at the end of an action, but not at the end of a heading or a container.
- Lesson 22 — Semicolons as statement terminators
- health
- For example, if you wrote struct Player hero = {'B'};, the grade becomes 'B', but the score and health are automatically set to 0 and 0.0.
- Lesson 193 — Compound subtraction `-=`Lesson 493 — Pointer to a constant (`const int *p`)Lesson 602 — Initializing structs with brace notationLesson 729 — Reading structs back into memory
- health = 100
- If you name your specific character variable hero, you can’t just say health = 100; because the computer won't know whose health you are talking about.
- Lesson 601 — The dot operator for member access
- health = health - 10
- In standard math notation, you might write health = health - 10.
- Lesson 193 — Compound subtraction `-=`
- healthPoints
- We declare healthPoints but forget to set its starting value before using it in a calculation.
- Lesson 939 — Using uninitialized variables
- heap
- An interesting feature of this layout is that the Stack and the Heap usually grow toward each other from opposite ends of the available memory space.
- Lesson 504 — Dynamic 2D array structuresLesson 531 — Understanding stack overflowLesson 532 — Introduction to the Heap segmentLesson 535 — Stack pointers vs Heap pointersLesson 868 — Allocating memory with `malloc` and `free`Lesson 1070 — The process memory layoutLesson 1120 — Returning values from threadsLesson 1192 — Preferring stack allocation over heap
- heap buffer overflow
- In C, the heap is that club, malloc() is your reservation, and sitting in seat 14 is a heap buffer overflow.
- Lesson 561 — Heap buffer overflows
- HEATING
- At any given moment, the microwave is doing exactly one thing: it’s either IDLE, HEATING, or PAUSED.
- Lesson 668 — Using enums for state machines
- heatLevel gets the value 92
- Always read the = sign as "gets" or "becomes." Instead of saying "heatLevel equals 92," say "heatLevel gets the value 92." This mental habit will help you avoid confusion when you start writing more complex code.
- Lesson 78 — Assigning values with `=`
- height
- If you have three variables representing the dimensions of a box (length, width, height), putting them on one line makes it clear they belong together.
- Lesson 76 — Multiple declarations in one line
- Hello
- If main.c is newer than the existing hello file, or if hello doesn't exist yet, it runs the gcc command.
- Lesson 42 — Basic `printf` syntaxLesson 57 — Basic `gcc` command flagsLesson 60 — Understanding the `a.out` defaultLesson 761 — Standard stream redirection in shellsLesson 818 — Structure of a Makefile RuleLesson 819 — Targets, dependencies, and recipes
- hello.c
- If you have a file named hello.c, you might run a command like this in your terminal:
- Lesson 15 — The concept of a Source FileLesson 30 — Creating an executable binaryLesson 60 — Understanding the `a.out` defaultLesson 818 — Structure of a Makefile Rule
- helper_math
- However, if another file tries to call helper_math, the linker will fail because that symbol was marked private (static) and kept out of the global phonebook.
- Lesson 809 — Symbol tables and visibility
- helpers.h
- Here is how you would define a shared math helper in a header file (e.g., helpers.h):
- Lesson 368 — Inline functions in header files
- hero
- If you name your specific character variable hero, you can’t just say health = 100; because the computer won't know whose health you are talking about.
- Lesson 601 — The dot operator for member accessLesson 729 — Reading structs back into memory
- hero.health
- For example, hero.health is just an integer.
- Lesson 601 — The dot operator for member access
- hero.health += 10
- You can add to it (hero.health += 10), subtract from it, or pass it into a function.
- Lesson 601 — The dot operator for member access
- hero.health = 100
- You must use the dot: hero.health = 100;.
- Lesson 601 — The dot operator for member access
- hero.level
- Think of the dot as the word "of." When you write hero.level, you are telling C: "Look at the level of hero."
- Lesson 601 — The dot operator for member access
- heroStrength
- The original heroStrength in main was never even touched; it was just the source for the initial photocopy.
- Lesson 344 — Visualizing the stack frame copy
- Hex
- You will rarely use Octal in modern programming, but you will use Hex and Binary constantly when working with colors (like #FF5733), memory addresses, or hardware pins.
- Lesson 119 — Integer literals (Hex, Octal, Binary)
- Hexadecimal
- In programming, we frequently use hexadecimal (base-16) to represent memory addresses or colors.
- Lesson 451 — Hexadecimal notation for memoryLesson 841 — Checking for digits with `isdigit` and `isxdigit`
- high
- The Recursive Step: If the target is smaller than the middle, we call the function again, but we update the high boundary.
- Lesson 1055 — Merge Sort: Recursive splittingLesson 1062 — Binary Search: Iterative approachLesson 1063 — Binary Search: Recursive approach
- high-level
- A high-level approach would be using an app on your phone.
- Lesson 1 — What is a low-level language?
- highScores[5]
- If your array has a size of 3, asking for highScores[5] is like trying to open a locker that isn't there.
- Lesson 386 — Accessing elements with the `[]` operator
- HOME
- Instead of hard-coding a folder path like C:\Users\Bob\Documents, you can ask the system for HOME.
- Lesson 1071 — Environment variables in C
- home address
- They don't need to know what is inside the box yet; they need to know your home address so they can physically put the box inside your mailbox.
- Lesson 490 — Swapping two numbers using pointersLesson 692 — How scanf uses memory addresses
- Hot Spots
- In programming, these high-traffic areas are called Hot Spots.
- Lesson 1183 — Identifying 'Hot Spots' in your code
- house
- In C, when you create a string using an array like char myName[] = "Alice";, you are building a house.
- Lesson 484 — Memory layout of string pointers
- houses down (
- He starts at the beginning of the street (a), walks exactly 3 houses down (+ 3), and opens the door (*) to get the letter.
- Lesson 473 — The equivalence of `a[i]` and `*(a + i)`
- how
- The .h file defines what a tool does, while the .c file defines how it does it.
- Lesson 377 — Role of the `.h` file
- htons
- Always use htons when sending data and ntohs when receiving it to ensure your numbers remain consistent across different types of hardware.
- Lesson 952 — Network byte order and `htons`/`ntohs`
- htons()
- Because of this, we must use helper functions like htons() (Host TO Network Short) to ensure our port numbers are in the universal "Network Byte Order."
- Lesson 952 — Network byte order and `htons`/`ntohs`Lesson 1109 — The sockaddr_in structure
- htons(80)
- On a standard PC, htons(80) will flip the bytes of the number.
- Lesson 952 — Network byte order and `htons`/`ntohs`
I
- i -= 10
- By using expressions like i += 2 or i -= 10 in your loop header, you control the "stride" of the loop, allowing you to skip values efficiently.
- Lesson 287 — Using non-unit increments (e.g., i += 2)
- i *= 2
- If you wanted to double a value every time, you could even use i *= 2.
- Lesson 287 — Using non-unit increments (e.g., i += 2)
- i += 2
- By using expressions like i += 2 or i -= 10 in your loop header, you control the "stride" of the loop, allowing you to skip values efficiently.
- Lesson 287 — Using non-unit increments (e.g., i += 2)
- i += 5
- If you are calculating a discount for every fifth item in a list, you could use i += 5.
- Lesson 287 — Using non-unit increments (e.g., i += 2)
- i < 10
- When counting up, we usually use i < 10.
- Lesson 286 — Counting backwards with decrement operators
- i < 100
- However, the computer spends extra energy on "loop overhead"—checking if the condition is still true (is i < 100?) and incrementing the counter (i++).
- Lesson 1190 — Loop unrolling explained
- i < 5
- Crucially, the condition i < 5 prevents the program from trying to access scores[5], which doesn't exist.
- Lesson 282 — The three parts of a for loop headerLesson 400 — Printing array elements in a sequence
- i < size
- Always use i < size instead of i <= size to ensure your loop stops exactly one step before the boundary.
- Lesson 405 — Avoiding off-by-one errors in loopsLesson 478 — Bounds checking and pointer safety
- i <= 10
- The loop continues as long as the middle condition (i <= 10) remains true.
- Lesson 288 — The comma operator in for loop headers
- i <= 5
- Incorrect: i <= 5 (Attempts to access index 5, which is out of bounds)
- Lesson 405 — Avoiding off-by-one errors in loops
- i <= num_elements
- If we had used i <= num_elements, the loop would have tried to print scores[5].
- Lesson 405 — Avoiding off-by-one errors in loops
- i <= size
- Always use i < size instead of i <= size to ensure your loop stops exactly one step before the boundary.
- Lesson 405 — Avoiding off-by-one errors in loops
- i = 2
- Second Pass: The outer loop increments to i = 2.
- Lesson 303 — Controlling the inner loop with outer loop variables
- i = i++
- You might look at the expression i = i++ and assume the logic is straightforward: take the current value of i, assign it to itself, and then increment it.
- Lesson 225 — Undefined behavior: `i = i++`Lesson 937 — Sequence point violations
- i = size
- If you accidentally start at i = size, you are pointing at a memory location just outside the array, which contains "garbage" data or could cause your program to crash.
- Lesson 401 — Reverse traversal of an array
- i == 500
- A conditional breakpoint allows you to stay hands-off until a specific logical condition is met, such as i == 500 or error_code != 0.
- Lesson 835 — Setting conditional breakpoints
- i > 0
- Conversely, if you set a condition that is always true (like i > 0 while adding to i), your loop will run forever.
- Lesson 286 — Counting backwards with decrement operatorsLesson 401 — Reverse traversal of an array
- i--
- Step Down: Use the decrement operator (i--) to subtract one from the variable every time the code block finishes.
- Lesson 286 — Counting backwards with decrement operatorsLesson 401 — Reverse traversal of an array
- I/O Redirection
- The most common reason is I/O Redirection.
- Lesson 1094 — Duplicating descriptors with dup()
- i++
- To make i++ work, the computer has to remember what the value was before the increment happened so it can use that old value in the current expression.
- Lesson 205 — Performance: Prefix vs PostfixLesson 282 — The three parts of a for loop headerLesson 283 — Initialization, condition, and increment flowLesson 284 — Using the for loop as a counterLesson 286 — Counting backwards with decrement operatorsLesson 287 — Using non-unit increments (e.g., i += 2)Lesson 292 — Continue in while vs for loopsLesson 399 — Using `for` loops for array traversalLesson 401 — Reverse traversal of an arrayLesson 775 — Side effects in macro argumentsLesson 778 — Macros vs inline functionsLesson 1190 — Loop unrolling explained
- id
- You don't have to manage two different struct types for liquids and solids; you have one master InventoryItem that adapts to your needs while keeping common data (like id) in a single, predictable place.
- Lesson 622 — The importance of NULL checks for struct pointersLesson 630 — Declaring an array of structsLesson 670 — Combining structs and unions
- IDE
- An IDE is like an automatic—it’s smoother, but it hides the mechanics from you.
- Lesson 13 — Using a Text Editor vs IDE
- identifier
- You have many identical jars, so you put labels on them like "Salt," "Sugar," or "Flour." In C, a variable is like one of those jars, and the name you give it is called an identifier.
- Lesson 74 — Naming rules and identifiersLesson 498 — The 'Clockwise/Spiral' rule for declarations
- IDLE
- At any given moment, the microwave is doing exactly one thing: it’s either IDLE, HEATING, or PAUSED.
- Lesson 668 — Using enums for state machines
- if
- Complexity isn't just about length; it’s about "indentation depth." Every time you add an if statement inside a for loop inside another if statement, you are forcing the next programmer to hold a massive mental map of conditions just to understand one line of code.
- Lesson 1 — What is a low-level language?Lesson 9 — Role of the CompilerLesson 23 — Case sensitivity in CLesson 132 — Safe downcasting techniquesLesson 163 — Truthiness: 0 vs non-zeroLesson 164 — Boolean result of comparisonsLesson 165 — Common pitfall: `=` vs `==`Lesson 167 — Logical NOT `!`Lesson 172 — Building complex logical expressionsLesson 173 — Logical vs Bitwise distinctionLesson 207 — Ternary as an expressionLesson 217 — Precedence of assignmentLesson 242 — Relational operators: <, <=, >, and >=Lesson 243 — Truthiness: 0 is false, non-zero is trueLesson 244 — The if statement syntaxLesson 245 — The else clause for alternative pathsLesson 246 — Else-if ladders for multiple conditionsLesson 248 — Logical OR (||) for combined conditionsLesson 250 — Curly brace requirements for single vs multi-lineLesson 251 — Variable scope inside if-else blocksLesson 253 — Short-circuit evaluation in logical ANDLesson 254 — Short-circuit evaluation in logical ORLesson 255 — Common mistake: assignment (=) vs equality (==)Lesson 256 — Nested if statements and dangling else logicLesson 257 — Using if statements for input validationLesson 258 — Basic switch syntax and casesLesson 264 — Comparing switch-case vs else-if laddersLesson 271 — Infinite loops: while(1) and while(true)Lesson 274 — The do-while syntax and the trailing semicolonLesson 281 — Pitfall: condition check occurs after executionLesson 287 — Using non-unit increments (e.g., i += 2)Lesson 290 — The break statement: exiting a loop earlyLesson 291 — The continue statement: skipping to the next iterationLesson 293 — Using break to exit infinite loops on conditionLesson 297 — Alternative patterns to avoid break and continueLesson 308 — Why goto is generally discouragedLesson 310 — Legitimate use case: error cleanup blocksLesson 312 — Function returns as a control flow mechanismLesson 318 — Finding Min and Max in a loopLesson 353 — Concept of self-calling functionsLesson 354 — Importance of the Base CaseLesson 402 — Finding the maximum value in an arrayLesson 404 — Linear search for a specific valueLesson 437 — Checking bounds before array accessLesson 443 — Counting vowels and consonantsLesson 462 — Checking for NULL before dereferencingLesson 525 — Dereferencing the NULL pointerLesson 536 — Header file stdlib.h for allocationLesson 539 — Checking for NULL return valuesLesson 542 — Why freeing NULL is safe
- if (!is_finished)
- Instead of writing if (is_finished == 0), which feels mathematical and clunky, you can write if (!is_finished).
- Lesson 249 — Logical NOT (!) for inversion
- if (!is_logged_in)
- Instead of writing if (is_logged_in == 0), you can write if (!is_logged_in).
- Lesson 167 — Logical NOT `!`
- if (0.1 + 0.2 == 0.3)
- If you try to ask if (0.1 + 0.2 == 0.3), the computer will likely tell you false because the tiny microscopic "dust" at the end of the numbers doesn't match perfectly.
- Lesson 104 — Comparing floats for equality
- if (a + b > INT_MAX)
- You can't just do if (a + b > INT_MAX) because the addition a + b might overflow before the comparison even happens.
- Lesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checks
- if (age >= 21)
- If you write if (age >= 21), it might be obvious today that 21 is the legal drinking age.
- Lesson 771 — Avoiding magic numbers with macros
- if (balance > LONG_MAX)
- If you are calculating a bank balance, you can check if (balance > LONG_MAX) to prevent an overflow before it happens, regardless of whether a long is 32-bits or 64-bits on that specific machine.
- Lesson 942 — Limits of `limits.h` and `stdint.h`
- if (condition) { ... }
- Use if (condition) { ... } to create a gated block of code that only runs when your condition evaluates to true.
- Lesson 244 — The if statement syntax
- if (fptr != NULL)
- By always checking if (fptr != NULL) before calling fclose(), you build a safety net.
- Lesson 747 — Safe file closing patterns
- if (is_finished == 0)
- Instead of writing if (is_finished == 0), which feels mathematical and clunky, you can write if (!is_finished).
- Lesson 249 — Logical NOT (!) for inversion
- if (is_logged_in == 0)
- Instead of writing if (is_logged_in == 0), you can write if (!is_logged_in).
- Lesson 167 — Logical NOT `!`
- if (is_sunny && is_weekend && have_gas)
- if (is_sunny && is_weekend && have_gas).
- Lesson 247 — Logical AND (&&) for combined conditions
- if (is_sunny)
- However, because the else is closest to if (is_sunny), it actually means: "If it is the weekend but NOT sunny, stay inside." If is_weekend were 0, nothing would print at all!
- Lesson 256 — Nested if statements and dangling else logic
- if (isEmpty())
- Without the if (isEmpty()) check, the line stack[top] would try to access stack[-1].
- Lesson 1013 — Handling Stack Underflow
- if (light == 0)
- If you see if (light == 0), you have to remember what 0 means.
- Lesson 664 — Enums vs constant integers
- if (message == NULL)
- In the example above, if we didn't have the if (message == NULL) check, the printf function would try to read memory at address zero, causing a crash.
- Lesson 1149 — Validating function arguments with `NULL` checks
- if (my_total > INT_MAX)
- Using these constants makes your code "portable." If you write a program that checks if (my_total > INT_MAX), that code will work correctly whether the maximum integer is 32,767 (on old 16-bit systems) or 2,147,483,647 (on modern systems).
- Lesson 904 — Integer ranges in `limits.h`
- if (my_variable < INT_MAX)
- Using <limits.h> makes your code "portable." If you write a program that checks if (my_variable < INT_MAX), that code will work perfectly whether the maximum is 32 thousand or 2 billion.
- Lesson 96 — The `<limits.h>` header file
- if (ptr != NULL)
- If you have a complex program where different functions might try to use the same pointer, setting it to NULL ensures that a simple if (ptr != NULL) check can prevent a catastrophic crash.
- Lesson 459 — Initializing pointers to NULLLesson 559 — Setting pointers to NULL after freeLesson 622 — The importance of NULL checks for struct pointers
- if (s + 1 > s)
- If you write if (s + 1 > s), and s is a signed integer, the compiler might simplify that entire expression to true and remove the check entirely.
- Lesson 935 — Signed integer overflow vs Unsigned wrap
- if (s->top == MAX - 1)
- Because C doesn't automatically stop you from writing data past the end of an array, the if (s->top == MAX - 1) check is your safety net.
- Lesson 1009 — The Push operation
- if (signal == 2)
- When you see if (signal == RED), it is much easier to understand than if (signal == 2).
- Lesson 662 — Default integer values in enums
- if (signal == RED)
- When you see if (signal == RED), it is much easier to understand than if (signal == 2).
- Lesson 662 — Default integer values in enums
- if (status == 0)
- While this works, your code will soon be filled with lines like if (status == 0).
- Lesson 661 — Defining an enum type
- if (status == 2)
- If you see if (status == 2), you have to hunt through your notes to remember what "2" means.
- Lesson 668 — Using enums for state machines
- if (string1 == string2)
- In C, you might be tempted to compare two strings using if (string1 == string2).
- Lesson 426 — Comparing strings with `strcmp`
- if (top >= MAX - 1)
- By adding an if (top >= MAX - 1) check, you create a "boundary guard" that ensures your stack stays within its allocated "home" in memory.
- Lesson 1012 — Handling Stack Overflow
- if (x + 1 > x)
- If you later write a check like if (x + 1 > x), the compiler might delete the entire if statement because, according to the "contract," x + 1 can never overflow.
- Lesson 934 — What 'Undefined Behavior' actually means
- if (x = 10)
- The most common mistake for new C programmers is typing if (x = 10) when they mean if (x == 10).
- Lesson 241 — Relational operators: == and !=
- if (x = 5)
- To the computer, if (x = 5) is a valid command to "set x to 5, then tell me if 5 is true." Since 5 is not 0, it is always true.
- Lesson 161 — The equality operator `==`Lesson 255 — Common mistake: assignment (=) vs equality (==)
- if (x == 10)
- The most common mistake for new C programmers is typing if (x = 10) when they mean if (x == 10).
- Lesson 241 — Relational operators: == and !=
- if both sides are
- Because & only results in a 1 if both sides are 1, using our mask will zero out everything except the bit we care about.
- Lesson 188 — Common bitwise idioms
- if statement
- An if statement to check if the current item matches your criteria.
- Lesson 317 — The Counter pattern (counting occurrences)
- if-else
- If you find yourself needing to handle three or more conditions, or if your line of code is stretching across the entire screen, do your future self a favor: hit the Enter key and write a standard if-else block instead.
- Lesson 206 — Syntax of `? :`Lesson 207 — Ternary as an expressionLesson 210 — Ternary vs If-Else for assignmentsLesson 211 — Readability concerns with `? :`Lesson 251 — Variable scope inside if-else blocksLesson 252 — The ternary operator (?:) as a shortcutLesson 262 — Switch restrictions: integral types onlyLesson 264 — Comparing switch-case vs else-if laddersLesson 294 — Using continue to skip invalid data entriesLesson 318 — Finding Min and Max in a loopLesson 443 — Counting vowels and consonantsLesson 517 — Arrays of function pointersLesson 898 — Interpreting errors with `perror`Lesson 1074 — Handling fork() return values
- if-else if
- When you have one variable that could be several different fixed values (like 1, 2, or 3), a switch is much cleaner and easier to read than a long chain of if-else if statements.
- Lesson 258 — Basic switch syntax and cases
- if-else if-else
- Most developers follow a rule of thumb: if you need to check more than three conditions, it is usually better to use a standard if-else if-else block.
- Lesson 208 — Nesting ternary operators
- if/else
- In modern C, almost everything a goto does can be done better with while loops, for loops, or if/else structures.
- Lesson 311 — The dangers of 'spaghetti code'Lesson 770 — The danger of semicolon in `#define`
- ignoreCase
- If you were building a search tool, you would now use that ignoreCase variable to decide whether to convert strings to lowercase before comparing them.
- Lesson 1208 — Adding command line flags (e.g., `-i` for case)
- ignores the
- While isgraph() catches everything from A to &, ispunct() ignores the A and only catches the &.
- Lesson 843 — Distinguishing `ispunct` and `isgraph`
- ile
- To check for a file's existence, we use a special constant called F_OK (short for File OK).
- Lesson 762 — Checking if a file exists
- image_01.png
- Build a complex filename (like image_01.png, image_02.png).
- Lesson 703 — Formatting strings in memory with sprintf
- image_02.png
- Build a complex filename (like image_01.png, image_02.png).
- Lesson 703 — Formatting strings in memory with sprintf
- immediate initialization
- The best way to avoid this "dark side" of C is to adopt a habit of immediate initialization.
- Lesson 939 — Using uninitialized variables
- Implementation-defined behavior
- Instead, it categorizes "weird" code into two main buckets: Implementation-defined behavior and Undefined Behavior (UB).
- Lesson 943 — Implementation-defined behavior vs UB
- implicit
- If you tell a friend to go to "123 Maple Street," that is an implicit piece of information.
- Lesson 461 — Implicit vs explicit pointer types
- implicit declaration
- In older versions of C, if you called a function named calculate_tax() before defining it, the compiler would shrug and say, "I'll assume this function exists somewhere and that it returns an integer." This is an implicit declaration.
- Lesson 329 — Implicit vs. explicit declarationsLesson 334 — Common errors with missing prototypes
- impossible
- To make this work, you choose a value that would be impossible or invalid in a real scenario.
- Lesson 314 — The Sentinel Value pattern
- in
- The d in %d stands for "decimal," which is the standard way we represent whole numbers (integers) like 5, 42, or -10.
- Lesson 50 — Printing integers with `%d`Lesson 490 — Swapping two numbers using pointers
- in a
- To display a literal % in a printf statement, use a double percent sign %%.
- Lesson 690 — Escaping the percent sign %%
- in the prototype and
- Interestingly, the names of the variables in the prototype don't technically have to match the definition (e.g., you could use p and r in the prototype and price and rate in the definition).
- Lesson 332 — Matching prototypes with definitions
- in the third position and the
- Because the input has a 1 in the third position and the mask also has a 1 there, the result becomes 4 (00000100).
- Lesson 180 — Masking bits with `&`
- In-order traversal
- To take advantage of this and print the tree's contents in order (like a sorted list), we use a recursive strategy called In-order traversal.
- Lesson 1025 — In-order traversal (Sorted output)
- in-place
- If you rearrange the clothes by shifting them around within the suitcase until they fit perfectly, you are sorting in-place.
- Lesson 1051 — In-place sorting vs extra memory
- inary dig
- Each bulb represents a "bit" (a binary digit).
- Lesson 179 — Understanding binary representation
- include
- You might have a src folder for your code and an include folder for your headers.
- Lesson 63 — Header search paths
- includes
- If A includes B, then B must be able to stand on its own or only depend on things "below" it.
- Lesson 802 — Dependency graphing in your head
- increment
- Look at how the increment function fails to change the original score:
- Lesson 346 — Preparing for pass by reference
- increment happens last
- The most important thing to remember is that the increment happens last.
- Lesson 283 — Initialization, condition, and increment flow
- increment(myScore)
- When main calls increment(myScore), the value 10 is plucked out and dropped into the function's local score variable.
- Lesson 346 — Preparing for pass by reference
- incremental build
- This is called an incremental build, and it is the secret to staying productive as a programmer.
- Lesson 817 — Why we need build toolsLesson 824 — Incremental builds and file timestamps
- indentation
- The most important use of whitespace is indentation.
- Lesson 36 — Whitespace and indentation
- indented logging
- To see what’s actually happening, we use a technique called indented logging.
- Lesson 363 — Visualizing recursive depth
- indeterminate
- When you declare a local variable, its initial value is indeterminate.
- Lesson 560 — Reading from uninitialized memory
- indeterminate iterations
- Unlike a for loop, which is usually built for counting a specific number of steps, the while loop is designed for indeterminate iterations.
- Lesson 269 — Using while for indeterminate iterations
- index
- Without this sequence point, the compiler might try to evaluate arr[index] at the same time it is trying to increment index.
- Lesson 223 — Sequence points in logic `&&` and `||`
- index % size
- Circular arrays use the modulo operator (index % size) to connect the end of the array back to the start, allowing for continuous reuse of empty memory slots.
- Lesson 1018 — Circular array implementation
- indirection operator
- In programming, this act of "following the map" to see what’s inside the house is called dereferencing, and we use the indirection operator (*) to do it.
- Lesson 238 — The Indirection operator `*`
- Inefficient
- In the Inefficient example, the char members act like "spacers" that force the compiler to add padding multiple times.
- Lesson 641 — Reordering members to reduce padding
- infinite loop
- This is called an infinite loop, and it will cause your program to freeze or crash because it is stuck doing the same task over and over.
- Lesson 268 — Updating the loop variable to avoid infinite loopsLesson 289 — Optional components: the for(;;) infinite loop
- INFINITY
- The <math.h> library provides two special constants for this: NAN and INFINITY.
- Lesson 867 — Handling `NAN` and `INFINITY` constants
- Ingredient
- If the recipe says, "Take the Ingredient and chop it, then take the Ingredient and boil it," and you decide that your Ingredient is "an apple that I must wash first," the recipe becomes:
- Lesson 775 — Side effects in macro arguments
- init
- The child becomes an "orphan." In modern systems, the system adopts these orphans, usually reassigning them to a special system process (like systemd or init) which has a PID of 1.
- Lesson 1069 — Parent processes and getppid()Lesson 1079 — Handling orphaned processes
- Initialization
- Initialization is the act of clearing out that junk and putting your own specific value inside for the first time.
- Lesson 79 — Declaration vs. Initialization
- initialize
- If you type up, GDB will inform you that you are now in initialize.
- Lesson 834 — Moving between frames with `up` and `down`
- initializer list
- When you declare an array, you can use an initializer list—a comma-separated list of values inside curly braces.
- Lesson 396 — Assigning values vs initializing arrays
- initializing
- To avoid bugs that are incredibly hard to track down, get into the habit of initializing your variables as soon as you create them: int score = 0;.
- Lesson 77 — Garbage values and uninitialized variables
- inline
- In C, when you prefix a function with the inline keyword, you are telling the compiler: "Instead of jumping to this function's location in memory, please just copy and paste the function's code directly into the spot where it's called."
- Lesson 366 — The `inline` keyword purposeLesson 367 — Compiler discretion with inliningLesson 368 — Inline functions in header filesLesson 369 — When to use inline functionsLesson 370 — Macros vs. Inline functionsLesson 778 — Macros vs inline functionsLesson 1194 — Using `inline` functions effectively
- Inline Assembly
- If you need to move data into a specific register (like the eax register on x86 processors) to talk to hardware, you use Inline Assembly.
- Lesson 961 — Direct register access
- inline functions are usually the winner
- In modern C, inline functions are usually the winner. They provide "type safety," meaning the compiler will warn you if you try to pass a string into a math function.
- Lesson 778 — Macros vs inline functions
- inner loop
- Nested loops work the same way: an inner loop completes its entire run for every single step of the outer loop.
- Lesson 299 — Inner loop vs outer loop execution orderLesson 300 — Using nested loops to print 2D gridsLesson 301 — Nested loops for multiplication tables
- Inorder Successor
- To keep the tree in order, you look for the Inorder Successor—the smallest value in the right subtree.
- Lesson 1029 — The three cases of node deletion
- input
- The compiler looks at your constraints, picks two registers, moves the value of input into the second register, runs your assembly, and then moves the result from the first register back into the output variable.
- Lesson 180 — Masking bits with `&`Lesson 280 — Scope of variables declared inside do-whileLesson 822 — Automatic variables like `$@` and `$<`Lesson 873 — Converting strings to doubles with `strtod`Lesson 916 — Optimization benefits of `restrict`Lesson 959 — Input and Output operands in assembly
- input buffer
- If a user types "Apple" and hits Enter, getchar() will grab the 'A' and leave 'p', 'p', 'l', 'e', and the 'newline' character sitting in a hidden waiting area called the input buffer.
- Lesson 680 — Basic character input with getchar
- input_handlerskey_code
- This technique is the backbone of "jump tables" in low-level programming and is frequently used to handle user input in games, where input_handlerskey_code triggers the correct action instantly.
- Lesson 517 — Arrays of function pointers
- input.c
- If you change just one line of code in input.c, do you really need to wait for the computer to re-translate the other five files?
- Lesson 817 — Why we need build tools
- input[1]
- If I write to output[0], I might be changing the value of input[1]!" To be safe, it would reload input[i] from the slow main memory every single time.
- Lesson 916 — Optimization benefits of `restrict`
- input[i]
- If I write to output[0], I might be changing the value of input[1]!" To be safe, it would reload input[i] from the slow main memory every single time.
- Lesson 916 — Optimization benefits of `restrict`
- insert
- Each time insert calls itself, the "problem" gets smaller.
- Lesson 1024 — Recursive insertion logic
- Insertion Sort
- While algorithms like Bubble Sort and Insertion Sort are typically stable, Quick Sort is often unstable because it swaps elements over long distances.
- Lesson 1051 — In-place sorting vs extra memoryLesson 1052 — Stability in sorting algorithms
- inside
- However, when you declare an array inside a function (a local array), C prioritizes speed over cleanliness.
- Lesson 347 — What is a Stack Frame?Lesson 395 — Initialization of local vs global arraysLesson 412 — Printing a 2D matrix to the console
- inside an
- The most common mistake for beginners is using = when they mean == inside an if statement.
- Lesson 255 — Common mistake: assignment (=) vs equality (==)
- inside your
- To display a single percent sign % in a string, you must write it as %% inside your printf function.
- Lesson 48 — The percent sign `%%` literal
- instead of
- In C, any non-zero value is treated as "True." If you accidentally use = instead of ==, you aren't asking a question; you are performing an action that almost always results in "True."
- Lesson 126 — The 'Usual Arithmetic Conversions'Lesson 165 — Common pitfall: `=` vs `==`
- instead of the expected
- Due to the order of operations (multiplication before addition), you would get 8 instead of the expected 16.
- Lesson 772 — Defining function-like macros
- int
- If you absolutely need a variable that is exactly 32 bits regardless of the computer it runs on, advanced C programmers use specific headers like <stdint.h>, but understanding the fluid nature of the basic int is the first step toward writing software that works everywhere.
- Lesson 9 — Role of the CompilerLesson 23 — Case sensitivity in CLesson 24 — The `return 0;` statementLesson 30 — Creating an executable binaryLesson 74 — Naming rules and identifiersLesson 75 — The syntax of a declarationLesson 76 — Multiple declarations in one lineLesson 81 — The `int` keywordLesson 82 — Short vs. Long integersLesson 83 — The `long long` typeLesson 84 — Using the `sizeof` operatorLesson 85 — Platform dependency of sizesLesson 86 — Fixed-width types from `<stdint.h>`Lesson 87 — Printing integers with `%d` and `%ld`Lesson 88 — Minimum and maximum valuesLesson 89 — The `signed` keywordLesson 95 — When to choose unsigned over signedLesson 96 — The `<limits.h>` header fileLesson 116 — Macros vs. Const variablesLesson 121 — What is type promotion?Lesson 122 — Integer promotion rulesLesson 123 — Hierarchy of types in expressionsLesson 124 — Automatic conversion in assignmentsLesson 125 — Risks of narrowing conversionsLesson 126 — The 'Usual Arithmetic Conversions'Lesson 127 — Mixing signed and unsigned in mathLesson 128 — Common conversion pitfallsLesson 130 — Forcing floating-point divisionLesson 131 — Casting between char and intLesson 132 — Safe downcasting techniquesLesson 133 — Truncation during float-to-int castsLesson 135 — Readability and intent in castingLesson 138 — Shadowing: Nested scope name clashesLesson 150 — The addition operator `+`Lesson 151 — The subtraction operator `-`Lesson 152 — Multiplication `*` mechanicsLesson 153 — Integer division `/` truncationLesson 154 — Floating-point divisionLesson 155 — The modulo operator `%` with integersLesson 157 — Basic arithmetic overflowLesson 158 — Mixing int and float in arithmeticLesson 183 — Left shift `<<` mechanicsLesson 189 — Using bitwise operators for flagsLesson 203 — Incrementing pointers (preview)Lesson 209 — Type consistency in ternary branchesLesson 228 — Implicit promotion to `int`Lesson 229 — Usual arithmetic conversionsLesson 230 — The `(type)` cast operatorLesson 231 — Truncation during castingLesson 233 — Promotion of `char` and `short`
- int (*a)[n]
- int a[n] is a collection of many addresses, while int (a)[n] is a single address pointing to a specific array structure.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- int *
- By declaring the pointer as an int *, you are telling C, "The thing at the end of this address is an integer, so look at the next 4 bytes of memory to find the full value."
- Lesson 455 — Declaring pointer variables with `*`Lesson 456 — The difference between `int *p` and `*p`Lesson 461 — Implicit vs explicit pointer typesLesson 507 — The `void *` generic typeLesson 508 — Why you can't dereference `void *`Lesson 509 — Casting `void *` to specific typesLesson 510 — Implicit conversion to `void *`Lesson 927 — Arrays of pointers vs Pointers to arrays
- int * const
- Use int * const when you have a specific memory buffer (like a hardware register) that must never be swapped for another address during your program's execution.
- Lesson 494 — Constant pointer to a value (`int * const p`)Lesson 911 — Difference between `const int *` and `int * const`
- int * p
- You might see programmers write int p;, int p;, or even int * p;.
- Lesson 455 — Declaring pointer variables with `*`
- int *a[n]
- int a[n] is a collection of many addresses, while int (a)[n] is a single address pointing to a specific array structure.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- int *ap[10]
- If you try to read int *ap[10] as "integer pointer array," you’ll actually get it wrong.
- Lesson 926 — Reading declarations with the 'Right-Left' rule
- int *arr
- Up to this point, you have likely used malloc() to create an array, storing the address in a simple pointer like int *arr.
- Lesson 981 — Structure for dynamic arrays
- int *items
- While you could use a pointer like int *items, this forces the actual data to live somewhere else in memory, requiring two separate allocations and causing the CPU to jump around to find your data.
- Lesson 672 — Flexible array members in C99
- int *myPtr
- When we declare a pointer like int myPtr or char myPtr, we are being explicit.
- Lesson 461 — Implicit vs explicit pointer types
- int *p
- When we declare int p, we are telling C: "This variable holds the location of an integer." When we declare int *pp, we are saying: "This variable holds the location of a variable that holds the location of an integer."
- Lesson 134 — Casting pointers (Introductory look)Lesson 455 — Declaring pointer variables with `*`Lesson 456 — The difference between `int *p` and `*p`Lesson 501 — Declaring `int **pp`
- int *ptr
- If you declare int *ptr; without initializing it, that pointer is "wild." It is pointing to a completely random, unpredictable location in your computer’s RAM.
- Lesson 457 — The Dereference operator `*`Lesson 459 — Initializing pointers to NULLLesson 521 — Uninitialized 'wild' pointersLesson 652 — Limitations of bit-field addressesLesson 1155 — Initializing pointers to `NULL` immediately
- int *restrict ptr
- When you declare a pointer as int *restrict ptr, you are saying: "For the lifetime of this pointer, only this specific pointer (or values derived directly from it) will be used to access the object it points to."
- Lesson 915 — The `restrict` pointer qualifier
- int *temp = ptr
- If you must use pointer arithmetic, create a copy like int *temp = ptr; and move temp instead.
- Lesson 555 — Invalid pointer increments before free
- int age = 0
- In our example, simply changing the declaration to int age = 0; clears the error.
- Lesson 1168 — Detecting uninitialized memory reads
- int age = 25
- Each room has a unique room number, like "Room 101" or "Room 5002." When you create a variable in C, like int age = 25;, the computer picks an empty room and puts the value 25 inside it.
- Lesson 237 — The Address-of operator `&`
- int argc
- This is handled through two special parameters: int argc (the count) and char argv (the arguments).
- Lesson 506 — Command line arguments `char **argv`
- int arr[] = {[10] = 1}
- If you define an array without a fixed size—like int arr[] = {[10] = 1};—the compiler is smart enough to see the highest index mentioned (10) and automatically make the array large enough to hold it (size 11).
- Lesson 394 — Designated initializers (C99)
- int b
- Then, it adds padding at the end so that if you created an array of these structures, the next int b in the second element would also be correctly aligned.
- Lesson 571 — CPU word size and alignmentLesson 638 — Understanding memory alignmentLesson 643 — Alignment requirements for different types
- int balance = -50
- For example, int balance = -50; works perfectly fine.
- Lesson 89 — The `signed` keyword
- int batteryLevel
- In this code, int batteryLevel is an abstraction.
- Lesson 8 — Hardware abstraction in C
- int board[3][4]
- Unlike a static array (like int board[3][4]), this structure lives on the heap.
- Lesson 504 — Dynamic 2D array structures
- int const *ptr
- Does int const *ptr mean the pointer is constant, or the integer is constant?
- Lesson 498 — The 'Clockwise/Spiral' rule for declarations
- int count = 0
- If we had used int count = 0; without the static keyword, the output would simply be "Visitor number: 1" three times in a row, because the variable would reset to zero every time the function started.
- Lesson 145 — Persisting data between function calls
- int counter
- If you have a global int counter, and ten threads increment it at once, they will trip over each other, leading to data races and wrong totals.
- Lesson 1122 — Thread-local storage basicsLesson 1142 — Atomic types like atomic_int
- int found = 1
- You would need to use a "flag" (a variable like int found = 1;) and check that flag in the outer loop, or use a return statement if you are ready to exit the entire function.
- Lesson 305 — Breaking out of nested loops: the limitation of break
- int global_score
- If you simply write int global_score; at the top of both files, the compiler gets confused.
- Lesson 797 — The `extern` keyword for variables
- int global_score = 0
- In C, variables have a specific "home." When you declare int global_score = 0; at the top of a file, you are telling the compiler to reserve a spot in memory for that integer.
- Lesson 797 — The `extern` keyword for variables
- int global_score = 100
- This means if you define int global_score = 100; in game.c, you can access that exact same memory location in ui.c by using the extern keyword.
- Lesson 918 — Internal vs external linkage basics
- int grid[2][3]
- When we declare a 2D array like int grid[2][3], our brains immediately visualize a table with two rows and three columns.
- Lesson 408 — Memory layout: Row-major order
- int health
- When you call malloc(sizeof(struct Character)), the computer looks at your struct definition, adds up the bytes for the int health and int level, and finds a contiguous block of memory that fits.
- Lesson 620 — Allocating structs on the heap with malloc
- int i
- If you try to compile the code above with gcc -std=c89, the compiler will complain because int i inside the loop wasn't allowed yet.
- Lesson 966 — C99: Variable declarations and `bool`Lesson 972 — Specifying the standard with `-std=` flags
- int i = 0
- A starting point: Usually int i = 0; (because arrays in C always start at index 0).
- Lesson 399 — Using `for` loops for array traversal
- int i = 1
- In this example, int i = 1 sets the stage.
- Lesson 283 — Initialization, condition, and increment flow
- int i = 10
- Start High: Set your variable to the starting maximum value (e.g., int i = 10).
- Lesson 286 — Counting backwards with decrement operators
- int ignoreMe
- By using unnamed bit-fields, you ensure that mode starts at exactly the 6th bit without cluttering your code with "dummy" variables like int reserved1; or int ignoreMe;.
- Lesson 650 — Unnamed bit-fields for padding
- int items[10]
- In standard C, if you define int items[10], your crate is always exactly big enough for 10 items.
- Lesson 672 — Flexible array members in C99
- int level
- When you call malloc(sizeof(struct Character)), the computer looks at your struct definition, adds up the bytes for the int health and int level, and finds a contiguous block of memory that fits.
- Lesson 620 — Allocating structs on the heap with malloc
- int locker
- In C, this is like declaring a standard variable: int locker;.
- Lesson 383 — Declaring an array with `type name[size]`
- int main()
- Up until now, you have likely seen int main() or int main(void).
- Lesson 506 — Command line arguments `char **argv`
- int main() { ... }
- int main() { ... }: This is the heart of your program.
- Lesson 17 — The 'Hello World' code
- int main(void)
- Up until now, you have likely seen int main() or int main(void).
- Lesson 506 — Command line arguments `char **argv`
- int matrix[5][10]
- If you have int matrix[5][10], sizeof(matrix) will not return 50 (the total number of integers).
- Lesson 931 — The `sizeof` operator with complex types
- int myNumber
- Instead of writing int myNumber;, you write struct Player player1;.
- Lesson 600 — Declaring struct variables
- int numbers[3]
- In C, if you write int numbers[] = {10, 20, 30};, the compiler looks at your list, counts three items, and automatically treats it as int numbers[3].
- Lesson 393 — Omitting size during initializationLesson 472 — Accessing arrays with pointer notation
- int numbers[5]
- When you declare an array like int numbers[5];, you aren't just creating a row of five integers; you are also creating a convenient way to find the very first element.
- Lesson 471 — Array names as constant pointersLesson 474 — Passing arrays to functions as pointersLesson 476 — Pointer to the start of an array
- int pi = 3
- While the C compiler won't force you to use uppercase (it will let you name a constant int pi = 3;), doing so makes your code much harder for humans to read.
- Lesson 117 — Naming conventions for constants
- int playerHealth
- In the example above, int playerHealth; tells the computer: "Reserve a spot in memory for a whole number and call it playerHealth." You can then put a value in it using the equals sign.
- Lesson 81 — The `int` keyword
- int power
- If you declare a variable (int power;) but forget to initialize it, and then try to use it in a calculation, your program will use whatever "garbage" number happened to be sitting in that memory slot from a previous task.
- Lesson 79 — Declaration vs. Initialization
- int pp
- When we declare int p, we are telling C: "This variable holds the location of an integer." When we declare int *pp, we are saying: "This variable holds the location of a variable that holds the location of an integer."
- Lesson 501 — Declaring `int **pp`
- int ptr
- A pointer to a pointer (declared as int ptr) is like a locked box that contains a second treasure map.
- Lesson 502 — Visualizing pointer chains
- int ptr = (int)malloc(sizeof(int))
- If you have ever looked at C++ code, you might see something like int ptr = (int)malloc(sizeof(int));.
- Lesson 540 — Casting malloc return in C vs C++
- int ptrToPtr
- In C, we denote this with two asterisks: int ptrToPtr;.
- Lesson 500 — Concept of double indirection
- int reserved1
- By using unnamed bit-fields, you ensure that mode starts at exactly the 6th bit without cluttering your code with "dummy" variables like int reserved1; or int ignoreMe;.
- Lesson 650 — Unnamed bit-fields for padding
- int roomNumber
- When you declare a single variable, like int roomNumber;, you are booking one room.
- Lesson 389 — The relationship between array size and memory
- int score = 0
- In C, if you define int score = 0; in file1.c and then define int score = 0; again in file2.c, the compiler will get confused and throw a "multiple definition" error.
- Lesson 77 — Garbage values and uninitialized variablesLesson 143 — The `auto` keywordLesson 146 — The `extern` keyword for multi-file codeLesson 793 — What should NOT go in a headerLesson 921 — Sharing variables across files with `extern`
- int score = 10
- When you write a line of code like int score = 10;, two specific things happen in your computer's memory:
- Lesson 448 — How variables are stored in RAM
- int score = 100
- When you write int score = 100;, two things happen:
- Lesson 80 — Variables in memory addresses
- int score = 50
- In C, when you create a variable like int score = 50;, you are putting the "mail" (the number 50) into one of those mailboxes.
- Lesson 449 — The Address-of operator `&`
- int scores[10]
- Up until now, you have likely created arrays like this: int scores[10];.
- Lesson 982 — Initial memory allocation with malloc
- int scores[5]
- If you declare an array without any curly braces at all (e.g., int scores[5];), the memory is left "dirty." It contains whatever random data was left there by the last program that used it.
- Lesson 383 — Declaring an array with `type name[size]`Lesson 391 — Initialization with curly braces `{}`Lesson 392 — Partial initialization and default zerosLesson 393 — Omitting size during initializationLesson 397 — The danger of uninitialized arrays
- int screen[5][10]
- When you write int screen[5][10], you are telling the computer to set aside enough space for 50 integers.
- Lesson 407 — Declaring 2D arrays: Rows and Columns
- int temperature = -10
- One handy trick to remember: you can also use the minus sign to represent a negative number directly, such as int temperature = -10;.
- Lesson 151 — The subtraction operator `-`
- int total = 10 + 5
- For example, if you write int total = 10 + 5;, C first calculates 15 and then stores that final number into the variable named total.
- Lesson 150 — The addition operator `+`
- int total = 50
- It is as if your code became int total = 50;.
- Lesson 328 — Returning values from functions
- int x
- When you declare a regular integer, like int x;, and don't give it a value, it contains "garbage"—whatever leftover data was sitting in that memory slot.
- Lesson 459 — Initializing pointers to NULLLesson 521 — Uninitialized 'wild' pointersLesson 536 — Header file stdlib.h for allocationLesson 537 — The malloc function signatureLesson 569 — Detecting uninitialized value usageLesson 868 — Allocating memory with `malloc` and `free`Lesson 939 — Using uninitialized variablesLesson 1168 — Detecting uninitialized memory reads
- int x = (int)2.0f
- If we simply cast a float to an int (int x = (int)2.0f), C translates the value to the integer 2.
- Lesson 657 — Using unions for type punning
- int x = 10
- If you give a global variable a value (like int x = 10;), it goes in the Initialized Data segment.
- Lesson 119 — Integer literals (Hex, Octal, Binary)Lesson 515 — Taking the address of a functionLesson 1070 — The process memory layout
- int x = printWelcomeMessage()
- If you tried to write int x = printWelcomeMessage();, the compiler would get confused and throw an error.
- Lesson 324 — The `void` return type
- int_fast32_t
- However, portability experts often prefer "minimum-width" types like int_least16_t (at least 16 bits) or "fastest" types like int_fast32_t (the speediest type that holds at least 32 bits).
- Lesson 942 — Limits of `limits.h` and `stdint.h`
- int_least16_t
- However, portability experts often prefer "minimum-width" types like int_least16_t (at least 16 bits) or "fastest" types like int_fast32_t (the speediest type that holds at least 32 bits).
- Lesson 942 — Limits of `limits.h` and `stdint.h`
- INT_MAX
- To help us handle these limits, C provides the <limits.h> header, which contains two vital constants: INT_MAX (the largest possible integer) and INT_MIN (the smallest possible negative integer).
- Lesson 88 — Minimum and maximum valuesLesson 96 — The `<limits.h>` header fileLesson 132 — Safe downcasting techniquesLesson 904 — Integer ranges in `limits.h`Lesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checksLesson 942 — Limits of `limits.h` and `stdint.h`Lesson 1154 — Safe integer arithmetic and overflow checks
- INT_MIN
- To help us handle these limits, C provides the <limits.h> header, which contains two vital constants: INT_MAX (the largest possible integer) and INT_MIN (the smallest possible negative integer).
- Lesson 88 — Minimum and maximum valuesLesson 96 — The `<limits.h>` header fileLesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checksLesson 1154 — Safe integer arithmetic and overflow checks
- int*
- It’s the language's way of saying, "I’m pointing to something in memory, but I don't know if it's an integer or a character." Inside the function, you tell C what the data is by "casting" it back to an int*, allowing qsort to remain flexible enough to sort anything.
- Lesson 512 — The `memcpy` function signatureLesson 513 — Implementing a generic swap functionLesson 527 — Pointer type-punning dangersLesson 540 — Casting malloc return in C vs C++Lesson 881 — Handling the `void*` return of `bsearch`Lesson 936 — Strict aliasing rule violationsLesson 1059 — Using C library 'qsort' function
- int* p
- You might see programmers write int p;, int p;, or even int * p;.
- Lesson 455 — Declaring pointer variables with `*`
- int32_t
- Use <stdint.h> types like int32_t or uint8_t when you need guaranteed, consistent variable sizes across different computers.
- Lesson 86 — Fixed-width types from `<stdint.h>`Lesson 942 — Limits of `limits.h` and `stdint.h`
- int8_t
- Use signed char or unsigned char (or even better, int8_t or uint8_t from <stdint.h>).
- Lesson 86 — Fixed-width types from `<stdint.h>`Lesson 945 — The significance of `char` signness
- integer
- Even better, use an integer as your loop counter and calculate the decimal value based on that integer.
- Lesson 320 — Floating point precision issues in loop conditionsLesson 493 — Pointer to a constant (`const int *p`)
- integer division
- If you divide two integers (whole numbers), C performs integer division.
- Lesson 130 — Forcing floating-point divisionLesson 154 — Floating-point division
- integer overflow
- This is called integer overflow, and it can lead to massive bugs or security holes.
- Lesson 882 — Common pitfalls in comparison function logicLesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checks
- Integer Promotion
- The most common form of this is Integer Promotion.
- Lesson 121 — What is type promotion?
- integers
- %d: Used for integers (whole numbers like 5, -42, or 0).
- Lesson 49 — Introduction to Format Specifiers
- integral types
- To achieve this, it only accepts integral types.
- Lesson 262 — Switch restrictions: integral types only
- Integration testing
- Integration testing is like putting three gears together and turning the first one to see if the third one moves.
- Lesson 1177 — Integration testing vs. Unit testing
- intent
- Using const isn't just about preventing errors; it's about intent.
- Lesson 35 — Documenting intent vs mechanicsLesson 496 — When to use `const` with pointers
- Interface
- By defining a standard set of function pointers, you create an Interface: a contract that says "any struct of this type will have a function named operate, but how it operates is up to the specific instance."
- Lesson 675 — Implementing an interface with function pointers in structs
- internal
- When you apply the static keyword to a global variable or function, you change its linkage from external to internal.
- Lesson 919 — The `static` keyword in global scope
- Internal fragmentation
- Internal fragmentation is like buying a large suitcase to carry a single pair of socks.
- Lesson 582 — Internal vs External fragmentation
- Internal Linkage
- Internal Linkage is like a conversation happening inside a specific apartment; the neighbors next door have no idea it’s happening.
- Lesson 918 — Internal vs external linkage basics
- internal_key
- By using opaque types, you create a "contract." You can change internal_key to a double or rename it entirely inside the .c file, and the user’s code won't break.
- Lesson 673 — Opaque types with header files
- interrupt service routines
- Use volatile whenever you are dealing with memory-mapped I/O, interrupt service routines, or shared global variables in multi-threaded applications where a value might change without the compiler seeing it happen in the current code block.
- Lesson 914 — How `volatile` prevents compiler optimization
- into
- If you try to pass 0 or -1.0 into log(), your program will return a special value called NaN (Not a Number) or -HUGE_VAL, representing negative infinity.
- Lesson 234 — Safety with explicit castsLesson 688 — Zero-padding numerical outputLesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- into the variable
- It performs this action, putting the value 5 into the variable b.
- Lesson 196 — Chained assignments `a = b = c`
- intPtr
- Because you told C that intPtr points to an int, the compiler handles the math behind the scenes.
- Lesson 461 — Implicit vs explicit pointer typesLesson 465 — How data types affect step size
- intrinsics
- Most modern compilers (like GCC and Clang) provide intrinsics: built-in functions that talk directly to the CPU.
- Lesson 956 — The `__builtin_bswap` compiler intrinsics
- intt
- This could be a missing semicolon, a misspelled keyword like intt instead of int, or an unclosed curly brace.
- Lesson 1156 — The difference between syntax and logic errors
- invalid
- To make this work, you choose a value that would be impossible or invalid in a real scenario.
- Lesson 314 — The Sentinel Value pattern
- Invalid Read
- An Invalid Read means you tried to look at data you don't own, while an Invalid Write means you tried to change it.
- Lesson 568 — Finding invalid reads and writes
- Invalid read of size 4
- Invalid read of size 4 (The "size 4" usually means an int).
- Lesson 1166 — Identifying 'Invalid Read' errors
- invalid read or write
- When you use malloc, the clerk gives you a room key (a pointer) and says, "You have access to room 402." An invalid read or write happens when you try to barge into room 403 or try to sleep in the hallway.
- Lesson 568 — Finding invalid reads and writes
- Invalid Write
- An Invalid Read means you tried to look at data you don't own, while an Invalid Write means you tried to change it.
- Lesson 568 — Finding invalid reads and writes
- inventory.h
- As your projects grow, you might include player.h in your main.c, but also in inventory.h.
- Lesson 791 — How `#pragma once` works
- InventoryItem
- You don't have to manage two different struct types for liquids and solids; you have one master InventoryItem that adapts to your needs while keeping common data (like id) in a single, predictable place.
- Lesson 670 — Combining structs and unions
- invitation
- To let someone in, they must meet two criteria: they must have an invitation AND they must be wearing formal shoes.
- Lesson 253 — Short-circuit evaluation in logical AND
- IPv4
- While the operating system uses a generic structure called sockaddr for all types of communication (like Bluetooth or internal files), we use the specialized sockaddr_in specifically for IPv4 internet networking.
- Lesson 1109 — The sockaddr_in structure
- is "stronger" than
- By internalizing that * is "stronger" than +, you can write complex formulas without worrying that the computer will misinterpret your intent.
- Lesson 216 — Precedence of `*` over `+`
- is 1 and
- You can look at the "Variables" window and see that i is 1 and sum is 0.
- Lesson 1162 — Setting breakpoints and stepping through code
- is a
- If x is a float, it returns the function pointer for sqrtf.
- Lesson 979 — Mathematical macros using `_Generic`
- is a very large negative number
- If a is a very large positive number and b is a very large negative number, a - b might exceed the limits of a signed integer, wrap around to a negative value, and tell qsort that the larger number is actually smaller.
- Lesson 882 — Common pitfalls in comparison function logic
- is also a valid number
- Because 0 is also a valid number, atoi cannot tell you if the conversion failed or if the user actually typed "0".
- Lesson 871 — Converting strings to integers with `atoi` and `atol`
- is greater than
- To check if adding b to a will cause an overflow, you check if a is greater than INT_MAX - b.
- Lesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checks
- is just
- To the compiler, Cinnamon is just 0 and Salt is just 1.
- Lesson 667 — Type safety concerns with enums
- is not equal
- If your name is not equal to a name on that list, you are allowed to pass.
- Lesson 162 — The inequality operator `!=`
- is one digit and
- Because 9 is one digit and 10 is two, the text on the screen will shift or "jump" to the right as the numbers grow.
- Lesson 688 — Zero-padding numerical output
- is represented as
- In memory, the number 1 is represented as 00 00 00 01 (in hex).
- Lesson 951 — Checking system endianness at runtime
- is the absolute definition of
- In the eyes of a C compiler, the number 0 is the absolute definition of false.
- Lesson 163 — Truthiness: 0 vs non-zero
- is the business card
- If p is the business card, *p is the act of actually driving to the office and looking inside.
- Lesson 456 — The difference between `int *p` and `*p`
- is_
- Booleans should be questions: If a variable is true or false, prefix it with is_, has_, or can_.
- Lesson 1197 — Meaningful variable naming conventions
- is_authenticated
- For example, is_authenticated is much clearer than status.
- Lesson 1197 — Meaningful variable naming conventions
- is_door_locked()
- The real function is_door_locked() checks physical hardware.
- Lesson 1176 — Mocking simple dependencies
- is_on
- Endianness and Ordering: If you define is_on first, one compiler might put it in the "Lowest" (Rightmost) bit of the byte, while another might put it in the "Highest" (Leftmost) bit.
- Lesson 954 — Bit-fields in structures and portability
- is_raining
- If you have a variable representing is_raining, then !is_raining means "it is sunny." It takes whatever boolean value you give it and turns it into its exact opposite.
- Lesson 167 — Logical NOT `!`Lesson 249 — Logical NOT (!) for inversion
- is_running
- If you have a simple flag (like is_running) that many threads need to check, an atomic load is the most efficient way to handle it without risking data corruption.
- Lesson 1143 — Atomic load and store
- is_weekend
- However, because the else is closest to if (is_sunny), it actually means: "If it is the weekend but NOT sunny, stay inside." If is_weekend were 0, nothing would print at all!
- Lesson 256 — Nested if statements and dangling else logic
- isalpha
- Think of isalpha as a digital gatekeeper that only lets the letters A through Z (either uppercase or lowercase) pass through.
- Lesson 840 — Testing for alphabetic characters with `isalpha`
- isalpha()
- When you use the functions in <ctype.h>, such as isalpha(), isdigit(), or tolower(), you might assume they accept a standard char.
- Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- isalpha(c)
- Use isalpha(c) from <ctype.h> to quickly check if a character is a letter (A-Z or a-z).
- Lesson 840 — Testing for alphabetic characters with `isalpha`
- isdigit
- What you'll learn: Why you must cast arguments to (unsigned char) when using functions like isdigit or toupper to prevent program crashes.
- Lesson 841 — Checking for digits with `isdigit` and `isxdigit`Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- isdigit()
- When you use the functions in <ctype.h>, such as isalpha(), isdigit(), or tolower(), you might assume they accept a standard char.
- Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- isEmpty()
- This is usually a simple function called isEmpty() that checks if your stack pointer or top index is at its starting position (typically -1 or NULL).
- Lesson 1013 — Handling Stack Underflow
- isgraph
- The relationship is simple: isgraph is the parent category, and ispunct is a specific sub-category that excludes alphanumeric characters.
- Lesson 843 — Distinguishing `ispunct` and `isgraph`
- isgraph()
- When working with the <ctype.h> library, you will encounter two functions that seem to overlap: ispunct() and isgraph().
- Lesson 843 — Distinguishing `ispunct` and `isgraph`
- isinf()
- Use isnan() and isinf() to detect mathematical errors or overflows, as standard equality checks (==) will not work on these special constants.
- Lesson 867 — Handling `NAN` and `INFINITY` constants
- islower()
- The functions isupper() and islower() act like digital detectives.
- Lesson 844 — Case testing with `isupper` and `islower`
- islower(c)
- Use isupper(c) to check for capital letters and islower(c) to check for small letters, ensuring you #include <ctype.h> first.
- Lesson 844 — Case testing with `isupper` and `islower`
- isnan()
- Use isnan() and isinf() to detect mathematical errors or overflows, as standard equality checks (==) will not work on these special constants.
- Lesson 867 — Handling `NAN` and `INFINITY` constants
- isOn
- The colon tells the compiler: "Don't give isOn a full integer's worth of space; just give it one solitary bit."
- Lesson 648 — The colon operator and bit width
- ispunct
- The relationship is simple: isgraph is the parent category, and ispunct is a specific sub-category that excludes alphanumeric characters.
- Lesson 843 — Distinguishing `ispunct` and `isgraph`
- ispunct()
- When working with the <ctype.h> library, you will encounter two functions that seem to overlap: ispunct() and isgraph().
- Lesson 843 — Distinguishing `ispunct` and `isgraph`
- isspace
- The isspace function provides a clean, portable way to detect spaces, tabs, and newlines by returning a non-zero value for any whitespace character.
- Lesson 842 — Identifying whitespace with `isspace`
- isupper()
- The functions isupper() and islower() act like digital detectives.
- Lesson 844 — Case testing with `isupper` and `islower`
- isupper(c)
- Use isupper(c) to check for capital letters and islower(c) to check for small letters, ensuring you #include <ctype.h> first.
- Lesson 844 — Case testing with `isupper` and `islower`
- isxdigit
- Use isdigit to find numbers 0-9, and isxdigit when you need to include the letters A-F for hexadecimal values.
- Lesson 841 — Checking for digits with `isdigit` and `isxdigit`
- it does not return
- The most critical thing to understand about execl() is that it does not return.
- Lesson 1081 — Replacing process images with execl()
- Item 0: 0
- If you ran this code, you might see Item 0: 0, Item 1: 32764, and Item 2: -1073741824.
- Lesson 397 — The danger of uninitialized arrays
- Item 1: 32764
- If you ran this code, you might see Item 0: 0, Item 1: 32764, and Item 2: -1073741824.
- Lesson 397 — The danger of uninitialized arrays
- Item 2: -1073741824
- If you ran this code, you might see Item 0: 0, Item 1: 32764, and Item 2: -1073741824.
- Lesson 397 — The danger of uninitialized arrays
- itemPrice * SALES_TAX_RATE
- Readability: itemPrice * SALES_TAX_RATE reads like a human sentence.
- Lesson 118 — Literal vs. Symbolic constants
- items[i] = 0
- In the code example above, GDB would stop on the line items[i] = 0; the moment i reached 3, revealing a buffer overflow that accidentally overwrote the target variable.
- Lesson 836 — Using `watch` for memory changes
- itemsRead
- If itemsRead is less than 3, we know the file ended early or an error occurred.
- Lesson 696 — Handling the return value of scanfLesson 726 — Reading raw bytes with fread
- Iteration
- Iteration is like standing at the bottom and saying, "While I haven't reached the top, move my left foot, then my right foot." You stay in one "state" and keep track of your progress with a counter.
- Lesson 358 — Iteration vs. Recursion comparison
- Iteration Number
- To trace a loop, draw three columns: Iteration Number, Variable Values, and Condition Check (True/False).
- Lesson 273 — Tracing while loop execution on paper
J
- j < 5
- Instead of saying j < 5 (which creates a fixed width), we say j <= i.
- Lesson 302 — The 'triangle' pattern logic
- j <= i
- Instead of saying j < 5 (which creates a fixed width), we say j <= i.
- Lesson 302 — The 'triangle' pattern logic
- Job
- Imagine you have a Person struct that contains a pointer to a Job struct.
- Lesson 629 — Deep vs shallow copies of nested structs
- John
- If your file has a full name like John Doe, fscanf with %s will only grab John.
- Lesson 719 — Formatted file input with fscanf
- John Doe
- If your file has a full name like John Doe, fscanf with %s will only grab John.
- Lesson 719 — Formatted file input with fscanf
- joinable
- By default, when you create a thread in C using pthread_create, it is joinable.
- Lesson 1121 — Detaching threads
K
- K&R
- In C, two "dialects" rule the landscape: K&R and Allman.
- Lesson 1196 — Consistency: K&R vs. Allman style
- Kernel Style
- They follow established guides like the Google C Style Guide or the Kernel Style.
- Lesson 40 — C coding style guides
- key
- A robust lookup function will check if the key stored at that index actually matches the search_key you provided.
- Lesson 505 — Accessing data through double dereferenceLesson 1031 — Key-Value pair conceptLesson 1036 — Hash table lookup
- Key-Value Store
- In programming, this is a Key-Value Store.
- Lesson 1212 — Project scope: A simple Key-Value store
- Keys must be unique
- The most important rule is that Keys must be unique. Just as two people can't have different lockers with the same number, you cannot have two identical keys in a data structure.
- Lesson 1031 — Key-Value pair concept
- kill
- If you want to force a stuck program to close (using the kill command) or check how much memory a specific program is using, you need to know its PID.
- Lesson 1067 — What is a process ID (PID)Lesson 1085 — Common signals: SIGINT, SIGTERM, SIGKILL
- kill -9
- When the OS sends SIGKILL (via kill -9), it doesn't even talk to your program.
- Lesson 1085 — Common signals: SIGINT, SIGTERM, SIGKILL
- kill()
- If you try to kill() a process belonging to another user or the System, the function will return -1 and set errno to indicate that permission was denied.
- Lesson 1086 — Sending signals with kill()
L
- L-value
- To understand how this works, you need to understand the two "sides" of the operation: the L-value and the R-value.
- Lesson 191 — L-values vs R-values
- label
- In the example above, the compiler inserts 3 bytes of empty padding after label so that quantity starts on a memory address that is a multiple of 4.
- Lesson 73 — What is a variable?Lesson 309 — Legitimate use case: breaking out of nested loopsLesson 637 — The sizeof operator on structs
- label maker
- sprintf, on the other hand, is like a label maker.
- Lesson 703 — Formatting strings in memory with sprintf
- label_name
- The goto statement requires a named label followed by a colon (label_name:) to act as a destination, allowing the program to jump directly to that line.
- Lesson 307 — The syntax of the goto statement
- Large integers
- Large integers (like long long) are in the middle.
- Lesson 229 — Usual arithmetic conversions
- largest
- While a struct allocates enough memory to hold all its members simultaneously, a union only allocates enough memory to hold its largest member.
- Lesson 653 — Defining a union with the union keyword
- last fixed argument
- The va_start macro requires two pieces of information: your va_list variable and the name of the last fixed argument before the dots.
- Lesson 373 — Using `va_list` and `va_start`
- Last Name
- For example, if you want to sort a list of employees by Department and then by Last Name, you would first sort by name, then perform a stable sort by department.
- Lesson 1052 — Stability in sorting algorithms
- LD_LIBRARY_PATH
- LD_LIBRARY_PATH is an environment variable that tells the dynamic linker extra directories to search for shared libraries at runtime.
- Lesson 816 — Runtime library loading and `LD_LIBRARY_PATH`
- leaks
- Most developers in the Apple ecosystem use a built-in tool called leaks or the Address Sanitizer (ASan) instead, but for this course, we recommend using a Linux virtual machine or Docker if you want to follow along with Valgrind specifically.
- Lesson 564 — Installing Valgrind Memcheck
- Least Privilege
- It follows the principle of Least Privilege: a variable should only exist where it is absolutely needed.
- Lesson 285 — Scope of the loop variable in C99 vs C89
- left
- When you are standing at a node, the left pointer leads you to a whole new subtree where all the values are smaller, and the right pointer leads to a subtree where all the values are larger.
- Lesson 78 — Assigning values with `=`Lesson 190 — Simple assignment `=`Lesson 1022 — Recursive tree node structureLesson 1026 — Pre-order and Post-order traversal
- left subtree
- In a BST, every single value in the left subtree must be smaller than the Root, and every single value in the right subtree must be larger than the Root.
- Lesson 1023 — Properties of a Binary Search Tree
- left-alignment
- If you want left-alignment, simply put a minus sign (-) before the number.
- Lesson 685 — Specifying field width for alignment
- Left-to-Right Associativity
- In C, this "first-come, first-served" logic is called Left-to-Right Associativity.
- Lesson 213 — Left-to-right associativity
- len
- Rather than writing a manual loop every time, the C Standard Library provides a handy tool called strlen (short for string length).
- Lesson 847 — Finding string length with `strlen`
- length
- Both functions require three main ingredients: the socket file descriptor (the ID of your connection), a buffer (the actual data), and the length of that data.
- Lesson 76 — Multiple declarations in one lineLesson 420 — Length vs Size of a string arrayLesson 423 — Getting length with `strlen`Lesson 1115 — Sending and receiving over socketsLesson 1193 — Avoiding redundant calculations in loops
- length - 1
- Loop Bounds: Ensure your loop stops exactly at length - 1.
- Lesson 403 — Calculating the sum and average
- Length (strlen)
- Length (strlen): This tells you how much data is actually in the array.
- Lesson 423 — Getting length with `strlen`
- length + 1
- When you define the size of your array, you must ensure the size is at least length + 1.
- Lesson 419 — Initializing strings with sizesLesson 420 — Length vs Size of a string array
- letter
- To use unions successfully, your code must keep track of which member is currently "active." If you write to the letter, only read from the letter until you assign something else.
- Lesson 655 — Accessing union members
- letter = getchar()
- In this example, letter = getchar() happens first.
- Lesson 197 — Assignment expression return value
- level
- C looks at the "first slot" of the function call, sees 10, and assigns that value to the first parameter, level.
- Lesson 337 — Positional matching of argumentsLesson 601 — The dot operator for member accessLesson 729 — Reading structs back into memory
- Level 0
- In GDB, the "top" of the stack (the current function) is Level 0.
- Lesson 834 — Moving between frames with `up` and `down`
- Level 1
- Then it returns to Level 2 to print "(Done with 2)", and finally back to Level 1 to print "(Done with 3)".
- Lesson 356 — Tracing a simple recursive callLesson 834 — Moving between frames with `up` and `down`
- Level 2
- Then it returns to Level 2 to print "(Done with 2)", and finally back to Level 1 to print "(Done with 3)".
- Lesson 356 — Tracing a simple recursive call
- Level 3
- The computer goes back to Level 3 to finish the last line of code, printing "(Done with 1)".
- Lesson 356 — Tracing a simple recursive call
- levelUp
- When levelUp(heroStrength) is called, the value 50 is plucked out of main's memory and pasted into a new memory location labeled strength inside levelUp.
- Lesson 344 — Visualizing the stack frame copy
- levelUp(heroStrength)
- When levelUp(heroStrength) is called, the value 50 is plucked out of main's memory and pasted into a new memory location labeled strength inside levelUp.
- Lesson 344 — Visualizing the stack frame copy
- lexicographical comparison
- To see if "apple" matches "apple," we use a process called lexicographical comparison via the strcmp (string compare) function.
- Lesson 850 — Lexicographical comparison with `strcmp`
- lib
- There is a small trick here: by convention, shared library files start with lib and end with .so (on Linux) or .dylib (on macOS).
- Lesson 812 — Linking with static librariesLesson 815 — Linking with shared libraries `-l` and `-L`
- libc
- Since a shared library (like libc) is used by many different programs simultaneously, it cannot guarantee it will always be loaded at the exact same memory address.
- Lesson 814 — Position Independent Code `-fPIC`
- libmathhelper.so
- For example, to link a library file named libmathhelper.so, you simply write -lmathhelper.
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- libmathutils.a
- If you have a library called libmathutils.a, you tell your compiler where to find it and to include it during the final build phase:
- Lesson 812 — Linking with static libraries
- libphysics.so
- Imagine you have a project where your library is stored in a folder named /libs and the file is named libphysics.so.
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- library
- To perform tasks like displaying words or reading what a user types, you need to "borrow" tools from a specialized toolbox called a library.
- Lesson 41 — The `stdio.h` library
- library name
- Use -L to specify the folder path and -l to specify the library name (minus the 'lib' prefix).
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- library shelf location
- Passing by pointer is like handing your colleague a small sticky note with the library shelf location of the manual.
- Lesson 491 — Efficiency of passing large structs by pointer
- libs
- By adding your custom directory to LD_LIBRARY_PATH, the linker checks your libs folder first.
- Lesson 816 — Runtime library loading and `LD_LIBRARY_PATH`
- libutils.a
- If you want a teammate to use your math functions, you can just give them the libutils.a file and the corresponding .h header files.
- Lesson 811 — Creating archives with the `ar` tool
- Lifetime
- Lifetime is the duration the actor is actually in the building.
- Lesson 139 — Lifetime vs. Scope
- LIFO
- The defining rule of a stack is LIFO, which stands for Last-In, First-Out.
- Lesson 1006 — Stack abstract data type conceptLesson 1007 — Array-based stack implementation
- light
- Because the compiler treats light as a simple int, it doesn't verify if the new value makes sense for that specific category.
- Lesson 667 — Type safety concerns with enums
- limit
- If you run this, C converts -5 to a massive unsigned integer to match the type of limit.
- Lesson 127 — Mixing signed and unsigned in math
- limit = 100
- Is it okay to change limit = 100 halfway through the code?
- Lesson 117 — Naming conventions for constants
- limited scope
- A static variable has a limited scope (it can only be seen inside its function) but a permanent lifetime (it stays in memory for the entire duration of the program).
- Lesson 139 — Lifetime vs. Scope
- limits.h
- Use limits.h to check the boundaries of standard types and stdint.h to define variables with specific size requirements, ensuring your code runs safely on everything from a toaster to a supercomputer.
- Lesson 88 — Minimum and maximum valuesLesson 904 — Integer ranges in `limits.h`Lesson 942 — Limits of `limits.h` and `stdint.h`
- line
- It prints every line that contains that string.
- Lesson 1204 — Project scope: A custom `grep` clone
- Line 5
- If you try to compile this, the compiler will point to Line 5.
- Lesson 67 — Line number tracking
- Line B
- Typing next (or just n) will execute the greet() function entirely and move the pointer directly to Line B.
- Lesson 830 — Stepping through code with `next` and `step`
- line buffering
- By default, when you print to the screen (stdout), C uses line buffering.
- Lesson 749 — Full buffering vs Line buffering
- line-buffered
- Standard output (stdout) is typically line-buffered.
- Lesson 748 — How C buffers I/O for speed
- Linear Allocator
- A Linear Allocator (also called a Bump Allocator) is like a tall stack of clean trays.
- Lesson 586 — Linear or Bump allocators
- Linear Search
- You wouldn't start at page one and flip through every single sheet (that is Linear Search).
- Lesson 1061 — Linear Search on arraysLesson 1062 — Binary Search: Iterative approachLesson 1064 — Importance of sorted data
- linked list
- This is the fundamental building block of a linked list, a data structure where each element (a "node") points to the next one in line.
- Lesson 626 — Self-referential structs for linked listsLesson 989 — Defining the self-referential node struct
- Linker
- When you compile this code, the compiler sees the declaration and says, "Okay, I'll leave a placeholder here for calculate." However, once the compiler finishes, the Linker steps in to connect the placeholder to the actual logic.
- Lesson 28 — Phase 4: The LinkerLesson 29 — Understanding `.o` and `.obj` filesLesson 64 — Library linking basicsLesson 70 — The 'undefined reference' linker errorLesson 381 — Compiling multiple `.c` filesLesson 807 — Understanding 'undefined reference' errorsLesson 808 — The executable ELF format
- Linker Error
- If you try to use a function that doesn't exist, you get a Linker Error (like the famous undefined reference).
- Lesson 28 — Phase 4: The Linker
- Linker Substitution
- To do this simply in C, we often use Linker Substitution.
- Lesson 1176 — Mocking simple dependencies
- linking
- Building a C program is usually a two-step dance: compiling (translating code into machine language) and linking (stitching those translations into a final app).
- Lesson 804 — The `-c` flag for compilationLesson 805 — What is inside a `.o` file
- Linux
- If you are on Linux, you likely already have a package manager—think of it like an app store for your command line.
- Lesson 10 — Installing GCC on Linux/macOS
- list
- If you compiled this with the -g flag (which is required for GDB to "see" your text), typing list inside GDB would show you exactly these lines, complete with their line numbers.
- Lesson 825 — Compiling with debug symbols `-g`Lesson 828 — Listing source code with `list`Lesson 853 — Tokenizing strings with `strtok`
- list main
- Shows the code at the start of the main function.
- Lesson 828 — Listing source code with `list`
- list of locations
- A pointer to a pointer is like a finger pointing to a list of locations where those folders are kept.
- Lesson 504 — Dynamic 2D array structures
- listen()
- The listen() function marks a socket as passive, allowing it to queue incoming connection requests in a backlog until the program is ready to process them.
- Lesson 1112 — Listening for connectionsLesson 1113 — Accepting client connections
- Literal Constant
- In C, the number 0.07 is a Literal Constant.
- Lesson 118 — Literal vs. Symbolic constants
- literal string
- When you want the messenger to deliver a message exactly as you wrote it—letter for letter—we call that a literal string.
- Lesson 43 — Printing literal strings
- Little Endian
- Little Endian flips it: you put "EE" in the first box, "FF" in the second, and "CO" in the third.
- Lesson 950 — Big Endian vs Little Endian explained
- Little-Endian
- Some CPUs (like Intel) store the "small" part of a number first (Little-Endian), while others store the "big" part first (Big-Endian).
- Lesson 951 — Checking system endianness at runtimeLesson 952 — Network byte order and `htons`/`ntohs`Lesson 953 — Manual byte swapping techniques
- lives
- The computer matches the first %d with the first variable after the comma (score), and the second %d with the second variable (lives).
- Lesson 50 — Printing integers with `%d`
- LL
- To tell the compiler a constant number is a long long, we often add the suffix LL to the end of the number.
- Lesson 83 — The `long long` type
- lldb
- Compile with the -g flag, then use the run command inside gdb or lldb to execute your program under professional supervision.
- Lesson 1161 — Starting a program in `gdb` or `lldb`
- LLONG_MAX
- The largest value a long long can hold. This is guaranteed to be at least 64 bits (roughly 9 quintillion) on any modern system.
- Lesson 88 — Minimum and maximum valuesLesson 909 — Managing large constants: `LONG_MAX` vs `LLONG_MAX`
- Load Factor
- In a hash table, this "crowdedness" is called the Load Factor.
- Lesson 1037 — Load factor and rehashing
- Local Paths
- #include "my_settings.h": The quotes tell the compiler to look in Local Paths (your desk) first, and then check any paths you provided with the -I flag.
- Lesson 63 — Header search paths
- local variable
- One common mistake is returning a pointer to a local variable created inside the thread function.
- Lesson 136 — Local variables and block scopeLesson 1120 — Returning values from threads
- local variables
- This tray contains everything that specific function needs to do its job—specifically, its local variables.
- Lesson 137 — Global variables and file scopeLesson 142 — The dangers of global variablesLesson 349 — Storage of local variablesLesson 530 — Stack frame lifecycle and local variables
- localScore
- When addScore(myScore) is called, C looks at the value inside myScore (which is 50) and copies that number into a brand new memory bucket named localScore.
- Lesson 486 — Pass-by-value limitations
- localtime
- When you look inside the struct tm returned by localtime, there are two "gotchas" that trip up every C programmer:
- Lesson 892 — Converting `time_t` to local time with `localtime`
- localtime()
- The localtime() function is your "sorter." It takes that raw number and breaks it down into a struct tm, which contains separate variables for years, months, days, hours, and minutes.
- Lesson 891 — Breaking down time with `struct tm`Lesson 892 — Converting `time_t` to local time with `localtime`
- lock
- To fully unlock the mutex, the thread must call unlock the exact same number of times it called lock.
- Lesson 1126 — Locking and unlocking mutexesLesson 1130 — Recursive mutexes
- Lock Ordering
- The simplest way to prevent this architectural disaster is Lock Ordering.
- Lesson 1139 — Common synchronization pitfalls
- lock-free
- An algorithm is lock-free if, at any point in time, at least one thread in the system is making progress.
- Lesson 1146 — Lock-free programming concepts
- locked box
- The paper tells you where to find a locked box (the first pointer).
- Lesson 505 — Accessing data through double dereference
- log_debug_info()
- If you tried to call log_debug_info() from a different file like main.c, the compiler would behave as if the function doesn't exist, even if you typed the name correctly.
- Lesson 798 — Static functions for file scoping
- log_internal_state()
- If you try to access engine_temp or call log_internal_state() from a different file like main.c, the compiler will act as if they don't exist.
- Lesson 919 — The `static` keyword in global scope
- log_message
- You could create a Logger struct with a function pointer log_message.
- Lesson 675 — Implementing an interface with function pointers in structs
- log()
- The math.h library provides three essential functions for this: exp(), log(), and log10().
- Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- log(x)
- This is the natural logarithm ($\ln$). It is the inverse of exp(). If exp(1) is $e$, then log(e) is 1.
- Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- log10()
- The math.h library provides three essential functions for this: exp(), log(), and log10().
- Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- log10(x)
- This is the common logarithm (base 10). This is very intuitive for humans because it essentially counts the number of zeros in a large number. For example, log10(1000) is 3.
- Lesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`
- Logger
- You could create a Logger struct with a function pointer log_message.
- Lesson 675 — Implementing an interface with function pointers in structs
- logger.h
- Level 1 (The Base): Low-level utilities like logger.h or constants.h.
- Lesson 802 — Dependency graphing in your head
- logger.o
- Because of $@ and $<, this single rule works for logger.o, math_utils.o, or player.o without you ever having to type those names manually.
- Lesson 822 — Automatic variables like `$@` and `$<`
- logic
- Variables separate the configuration of your build from the logic of your build.
- Lesson 257 — Using if statements for input validationLesson 821 — Using variables in Makefiles
- logic.c
- When you compile your test, you simply link logic.c and test_main.c with your mock_sensor.c instead of the real hardware driver.
- Lesson 1176 — Mocking simple dependenciesLesson 1210 — Structuring the project into multiple `.c` files
- Logical NOT
- This is where the Logical NOT operator comes in.
- Lesson 249 — Logical NOT (!) for inversion
- logical operators
- Use logical operators for decision-making, such as if statements (e.g., "If the user is logged in AND has a premium account").
- Lesson 173 — Logical vs Bitwise distinction
- long
- If you are calculating a bank balance, you can check if (balance > LONG_MAX) to prevent an overflow before it happens, regardless of whether a long is 32-bits or 64-bits on that specific machine.
- Lesson 82 — Short vs. Long integersLesson 84 — Using the `sizeof` operatorLesson 85 — Platform dependency of sizesLesson 86 — Fixed-width types from `<stdint.h>`Lesson 87 — Printing integers with `%d` and `%ld`Lesson 88 — Minimum and maximum valuesLesson 89 — The `signed` keywordLesson 96 — The `<limits.h>` header fileLesson 132 — Safe downcasting techniquesLesson 152 — Multiplication `*` mechanicsLesson 155 — The modulo operator `%` with integersLesson 231 — Truncation during castingLesson 235 — The `sizeof` operator with typesLesson 735 — Getting current position with ftellLesson 736 — Finding file size using seek and tellLesson 738 — Using fgetpos and fsetpos for large filesLesson 871 — Converting strings to integers with `atoi` and `atol`Lesson 904 — Integer ranges in `limits.h`Lesson 909 — Managing large constants: `LONG_MAX` vs `LLONG_MAX`Lesson 932 — Using `typeof` in C23Lesson 942 — Limits of `limits.h` and `stdint.h`
- long double
- While a double usually occupies 8 bytes of memory, a long double often uses 12 or 16 bytes (depending on your computer’s architecture), allowing it to store many more digits after the decimal point with significantly less rounding error.
- Lesson 99 — The `long double` typeLesson 103 — The `<float.h>` header fileLesson 120 — Floating-point suffixes (f, L)Lesson 647 — Restrictions on bit-field types
- long long
- A reliable rule of thumb for C programming is to order your members by size, descending. Start with your double or long long types, move to int, then short, and put char at the very bottom.
- Lesson 83 — The `long long` typeLesson 88 — Minimum and maximum valuesLesson 187 — Shift operator constraintsLesson 229 — Usual arithmetic conversionsLesson 641 — Reordering members to reduce padding
- LONG_MAX
- Always use LONG_MAX and LLONG_MAX from <limits.h> to check for overflows and define boundaries for large integer variables.
- Lesson 909 — Managing large constants: `LONG_MAX` vs `LLONG_MAX`
- Look in this directory
- The uppercase -L flag stands for Look in this directory.
- Lesson 815 — Linking with shared libraries `-l` and `-L`
- Look to the left
- Look to the left. If you see *, say "pointer to." If you see a type (like int), say that type.
- Lesson 926 — Reading declarations with the 'Right-Left' rule
- Look to the right
- Look to the right. If you see [], say "array of." If you see (), say "function returning."
- Lesson 926 — Reading declarations with the 'Right-Left' rule
- looking at the address
- If you use the name alone greet, you are just looking at the address written on the paper.
- Lesson 515 — Taking the address of a function
- looks
- It is important to remember that %.nf only changes how the number looks on the screen.
- Lesson 102 — Formatting decimals with `%.nf`
- loop
- While losing a few bytes once might not be noticed, losing those bytes inside a loop or a recursive function creates a compound interest effect that can quickly consume every byte of RAM your computer has available.
- Lesson 317 — The Counter pattern (counting occurrences)Lesson 552 — Leaking in loops and recursion
- looping
- By limiting the scope to an array of structs, you focus on the most important C concepts: string manipulation (copying names into the keys), looping (searching for a specific key), and memory layout.
- Lesson 1212 — Project scope: A simple Key-Value store
- lost your original key
- If the mover comes back and says, "Sorry, there are no larger units available," but then realizes they lost your original key during the search, you are in trouble.
- Lesson 547 — Handling realloc failure safely
- low
- We then tell the function to handle the left half (from low to mid) and the right half (from mid + 1 to high).
- Lesson 1055 — Merge Sort: Recursive splittingLesson 1062 — Binary Search: Iterative approachLesson 1063 — Binary Search: Recursive approach
- low-level
- A low-level approach is like standing in the kitchen.
- Lesson 1 — What is a low-level language?
- lowercase
- Always name your files in lowercase, use underscores instead of spaces, and ensure they end in a lowercase .c.
- Lesson 16 — Naming conventions for .c files
- lowercase_snake_case
- While modern computers can handle spaces and capital letters, C tradition (and many professional tools) prefers lowercase_snake_case.
- Lesson 16 — Naming conventions for .c files
- ls
- Because your original code has been erased and replaced by the new program (in this case, the ls command), the original process effectively ends when the new program finishes.
- Lesson 12 — Introduction to the CLILesson 32 — Executing from the command lineLesson 564 — Installing Valgrind MemcheckLesson 874 — Communicating with the OS using `system`Lesson 1080 — The execve() family overviewLesson 1081 — Replacing process images with execl()Lesson 1083 — Combining fork() and exec()Lesson 1096 — The close-on-exec flagLesson 1105 — Redirecting stdout to a pipe
- ls -l
- If you run ls -l, you'll notice the file type starts with a p (for pipe).
- Lesson 1107 — Creating FIFOs with mkfifo()
- ls | grep
- When you run ls | grep, the shell forks a process for ls and uses dup2 to point its stdout to a pipe.
- Lesson 1105 — Redirecting stdout to a pipe
- luckyNumbers[3]
- If you try to access luckyNumbers[3] in the example above, you are asking C for the fourth item in a three-item list.
- Lesson 385 — Array indexing starting from zero
M
- Machine Code
- Its job is to take those assembly words and translate them into a specific sequence of binary numbers known as Machine Code.
- Lesson 27 — Phase 3: Assembly to Object CodeLesson 30 — Creating an executable binary
- macOS
- If you are on macOS, Apple provides these tools through a package called "Command Line Tools." Open your terminal and type:
- Lesson 10 — Installing GCC on Linux/macOSLesson 564 — Installing Valgrind Memcheck
- macros
- Use macros only when you need "generic" behavior (logic that works on int, float, and double simultaneously) or when you need to perform special preprocessor tricks that a regular function simply cannot do.
- Lesson 768 — Defining constants with `#define`Lesson 778 — Macros vs inline functionsLesson 932 — Using `typeof` in C23Lesson 1077 — Capturing child exit status
- magnitude
- You are interested in the magnitude of the movement, not the direction.
- Lesson 866 — Absolute values for floats with `fabs`
- main
- Use pthread_exit() when you have complex logic where a thread needs to stop deep inside a nested function, or when you want the main thread to finish its own work but allow background threads to keep processing in the background.
- Lesson 6 — C as a compiled languageLesson 15 — The concept of a Source FileLesson 17 — The 'Hello World' codeLesson 20 — The `main()` function entry pointLesson 21 — Curly braces `{}` and blocksLesson 23 — Case sensitivity in CLesson 24 — The `return 0;` statementLesson 30 — Creating an executable binaryLesson 31 — How the OS runs a programLesson 32 — Executing from the command lineLesson 71 — Common beginner typosLesson 141 — Function parameters as local scopeLesson 251 — Variable scope inside if-else blocksLesson 322 — What is a function?Lesson 325 — Writing your first custom functionLesson 327 — The `return` statement flowLesson 328 — Returning values from functionsLesson 334 — Common errors with missing prototypesLesson 341 — Understanding 'Pass by Value'Lesson 344 — Visualizing the stack frame copyLesson 345 — Limitations of pass by valueLesson 346 — Preparing for pass by referenceLesson 347 — What is a Stack Frame?Lesson 350 — Return addresses in memoryLesson 351 — Visualizing the stack during nested callsLesson 454 — Introduction to the stack frameLesson 486 — Pass-by-value limitationsLesson 489 — Returning multiple values via pointersLesson 490 — Swapping two numbers using pointersLesson 530 — Stack frame lifecycle and local variablesLesson 600 — Declaring struct variablesLesson 760 — Redirecting streams with freopenLesson 767 — How `gcc -E` shows preprocessor outputLesson 799 — The role of the 'main' fileLesson 823 — Phony targets like `clean` and `all`Lesson 828 — Listing source code with `list`Lesson 829 — Setting breakpoints with `break`Lesson 833 — Inspecting the call stack with `backtrace`Lesson 836 — Using `watch` for memory changesLesson 875 — Cleaning up at exit with `atexit`Lesson 993 — Prepending nodes to the headLesson 1118 — Passing arguments to threadsLesson 1122 — Thread-local storage basicsLesson 1123 — The pthread_exit functionLesson 1174 — Building a minimal custom test harnessLesson 1202 — Indentation and whitespace rulesLesson 1208 — Adding command line flags (e.g., `-i` for case)
- main.c
- When you run make, Make sees $@ and thinks, "The target is app, so I'll put that there." It sees $< and thinks, "The first dependency is main.c, so I'll put that there." The actual command executed remains gcc main.c -o app.
- Lesson 29 — Understanding `.o` and `.obj` filesLesson 57 — Basic `gcc` command flagsLesson 59 — Compiling multiple source filesLesson 146 — The `extern` keyword for multi-file codeLesson 377 — Role of the `.h` fileLesson 378 — Separating interface from implementationLesson 379 — Using `#include` with quotesLesson 381 — Compiling multiple `.c` filesLesson 382 — Sharing functions across modulesLesson 788 — The purpose of header filesLesson 789 — The 'duplicate definition' errorLesson 790 — Creating basic include guardsLesson 791 — How `#pragma once` worksLesson 796 — Splitting code into `.c` and `.h`Lesson 797 — The `extern` keyword for variablesLesson 798 — Static functions for file scopingLesson 799 — The role of the 'main' fileLesson 802 — Dependency graphing in your headLesson 806 — Linking multiple object filesLesson 809 — Symbol tables and visibilityLesson 817 — Why we need build toolsLesson 819 — Targets, dependencies, and recipesLesson 822 — Automatic variables like `$@` and `$<`Lesson 824 — Incremental builds and file timestampsLesson 825 — Compiling with debug symbols `-g`Lesson 919 — The `static` keyword in global scopeLesson 921 — Sharing variables across files with `extern`Lesson 922 — Using `extern` with functionsLesson 1159 — Using `__FILE__` and `__LINE__` macrosLesson 1201 — Using `clang-format` for automationLesson 1210 — Structuring the project into multiple `.c` filesLesson 1211 — Writing the Makefile for the project
- main.c -> auth.h -> database.h
- In this graph, the flow is main.c -> auth.h -> database.h.
- Lesson 802 — Dependency graphing in your head
- main.c:5:10: error: expected ';' after expression
- main.c:5:10: error: expected ';' after expression
- Lesson 66 — Reading compiler error messages
- main.c:5:10: error: expected ';' before 'return'
- When you compile a program with an error, your terminal will spit out a message that usually looks like this: main.c:5:10: error: expected ';' before 'return'.
- Lesson 67 — Line number tracking
- main.exe
- Between your text file (main.c) and your final app (main.exe), there is a crucial middle step: the Object File.
- Lesson 29 — Understanding `.o` and `.obj` files
- main.h
- If you ever find yourself wanting to include main.h inside database.h, stop!
- Lesson 802 — Dependency graphing in your head
- main.o
- However, if main.o tries to call a function located in math.o, the object file just leaves a blank space with a sticky note saying, "I'll need someone to plug in the math logic here later."
- Lesson 29 — Understanding `.o` and `.obj` filesLesson 806 — Linking multiple object filesLesson 819 — Targets, dependencies, and recipesLesson 824 — Incremental builds and file timestamps
- main()
- If you accidentally include a main() function in two different files within the same project, the compiler will get confused—like an airport with two different control towers giving conflicting orders—and will throw a "multiple definition" error.
- Lesson 17 — The 'Hello World' codeLesson 20 — The `main()` function entry pointLesson 21 — Curly braces `{}` and blocksLesson 31 — How the OS runs a programLesson 149 — Memory segments: Stack vs. DataLesson 306 — Defining labels in C codeLesson 307 — The syntax of the goto statementLesson 313 — Exiting the program with exit()Lesson 322 — What is a function?Lesson 326 — Placement of functions in a fileLesson 329 — Implicit vs. explicit declarationsLesson 330 — Function prototype syntaxLesson 331 — Benefits of forward declarationLesson 339 — Local scope of parametersLesson 342 — Memory allocation for parametersLesson 348 — Pushing and popping framesLesson 349 — Storage of local variablesLesson 351 — Visualizing the stack during nested callsLesson 353 — Concept of self-calling functionsLesson 381 — Compiling multiple `.c` filesLesson 395 — Initialization of local vs global arraysLesson 454 — Introduction to the stack frameLesson 503 — Modifying a pointer inside a functionLesson 600 — Declaring struct variablesLesson 799 — The role of the 'main' fileLesson 885 — Seeding the generator with `srand`Lesson 886 — Why you should only seed onceLesson 888 — Getting a unique seed with `time(NULL)`Lesson 1072 — Process termination and exit codesLesson 1080 — The execve() family overviewLesson 1093 — Standard streams (0, 1, 2)Lesson 1119 — Waiting for threads with pthread_joinLesson 1123 — The pthread_exit functionLesson 1170 — Cleaning up heap memory before exitLesson 1175 — Separating logic from `main()` for testability
- MainCode.c
- If half are named MainCode.c and the other half are math_functions.c, your project becomes a messy "junk drawer." Sticking to lowercase names with underscores is a "handshake" between you and other programmers, signaling that you follow standard professional conventions.
- Lesson 16 — Naming conventions for .c files
- make
- When you type make clean to sweep away your old .o files, make will look at that file and say: "clean is up to date." It won't run your cleanup commands because it thinks the "job" of creating a file named clean is already finished.
- Lesson 61 — Introduction to `make` and MakefilesLesson 62 — Automating the build processLesson 817 — Why we need build toolsLesson 818 — Structure of a Makefile RuleLesson 819 — Targets, dependencies, and recipesLesson 820 — The importance of Tab charactersLesson 821 — Using variables in MakefilesLesson 822 — Automatic variables like `$@` and `$<`Lesson 823 — Phony targets like `clean` and `all`Lesson 824 — Incremental builds and file timestampsLesson 1211 — Writing the Makefile for the project
- make all
- Instead of typing make main, you just type make (which defaults to the first target) or make all.
- Lesson 823 — Phony targets like `clean` and `all`
- make clean
- When you type make clean to sweep away your old .o files, make will look at that file and say: "clean is up to date." It won't run your cleanup commands because it thinks the "job" of creating a file named clean is already finished.
- Lesson 823 — Phony targets like `clean` and `all`Lesson 1211 — Writing the Makefile for the project
- make main
- Instead of typing make main, you just type make (which defaults to the first target) or make all.
- Lesson 823 — Phony targets like `clean` and `all`
- Makefile
- Once you have saved a file named Makefile (no extension) in your project folder, you no longer need to remember complex GCC arguments.
- Lesson 61 — Introduction to `make` and MakefilesLesson 62 — Automating the build processLesson 818 — Structure of a Makefile RuleLesson 1211 — Writing the Makefile for the project
- malloc
- While calloc is slightly slower than malloc (because the computer has to spend time writing zeros to every memory address), it prevents a very common class of bugs: accidentally using uninitialized variables.
- Lesson 532 — Introduction to the Heap segmentLesson 534 — Scope of heap-allocated dataLesson 536 — Header file stdlib.h for allocationLesson 537 — The malloc function signatureLesson 538 — Calculating size with sizeofLesson 539 — Checking for NULL return valuesLesson 540 — Casting malloc return in C vs C++Lesson 541 — The free function signatureLesson 543 — Contiguous allocation with callocLesson 544 — Difference between malloc and callocLesson 545 — Zero-initialization overheadLesson 546 — Resizing blocks with reallocLesson 549 — Using realloc as malloc or freeLesson 552 — Leaking in loops and recursionLesson 555 — Invalid pointer increments before freeLesson 558 — Returning addresses of local variablesLesson 561 — Heap buffer overflowsLesson 563 — Out-of-bounds array access on heapLesson 565 — Running a program under ValgrindLesson 566 — Reading 'definitely lost' reportsLesson 568 — Finding invalid reads and writesLesson 576 — The aligned_alloc functionLesson 578 — Motivation for custom allocatorsLesson 580 — Managing a static memory poolLesson 591 — Trade-offs of arena vs mallocLesson 592 — Introduction to brk and sbrkLesson 593 — Using mmap for large allocationsLesson 594 — Anonymous memory mappingsLesson 598 — Page faults and resident set sizeLesson 620 — Allocating structs on the heap with mallocLesson 621 — Freeing dynamically allocated structsLesson 672 — Flexible array members in C99Lesson 736 — Finding file size using seek and tellLesson 868 — Allocating memory with `malloc` and `free`Lesson 869 — Contiguous allocation with `calloc`Lesson 870 — Resizing blocks with `realloc`Lesson 982 — Initial memory allocation with mallocLesson 985 — Amortized time complexityLesson 986 — Accessing elements by indexLesson 988 — Freeing the dynamic arrayLesson 991 — Allocating a new node in memoryLesson 993 — Prepending nodes to the headLesson 1046 — Graph memory managementLesson 1118 — Passing arguments to threadsLesson 1120 — Returning values from threadsLesson 1131 — Cleaning up mutex resourcesLesson 1149 — Validating function arguments with `NULL` checksLesson 1165 — Installing and running `valgrind`Lesson 1169 — Reading the Valgrind leak summaryLesson 1185 — Profiling memory allocation frequency
- malloc.c
- If you notice your program is spending 20% of its execution time inside malloc.c, you don't have a logic error—you have an allocation frequency problem.
- Lesson 1185 — Profiling memory allocation frequency
- malloc()
- To stay safe, always ensure every malloc() has a corresponding free(), and never overwrite a pointer variable unless you are certain the memory it currently points to has been released or its address is stored safely elsewhere.
- Lesson 523 — Memory leaks and lost pointersLesson 525 — Dereferencing the NULL pointerLesson 528 — Tools for pointer debugging (Valgrind)Lesson 534 — Scope of heap-allocated dataLesson 535 — Stack pointers vs Heap pointersLesson 545 — Zero-initialization overheadLesson 550 — Definition of a memory leakLesson 551 — Losing the last pointer to a blockLesson 553 — The 'Free after use' ruleLesson 561 — Heap buffer overflowsLesson 581 — The concept of memory fragmentationLesson 585 — What is a Memory ArenaLesson 586 — Linear or Bump allocatorsLesson 588 — Arena allocation for frame-based tasksLesson 591 — Trade-offs of arena vs mallocLesson 594 — Anonymous memory mappingsLesson 981 — Structure for dynamic arraysLesson 997 — Memory cleanup for linked listsLesson 1070 — The process memory layoutLesson 1089 — Signal safety and reentrant functionsLesson 1164 — What is a memory leak?Lesson 1170 — Cleaning up heap memory before exit
- malloc(count * sizeof(type))
- Use malloc(count * sizeof(type)) to reserve a block of heap memory, and always check if the resulting pointer is NULL before using it.
- Lesson 982 — Initial memory allocation with malloc
- malloc(sizeof(struct Character))
- When you call malloc(sizeof(struct Character)), the computer looks at your struct definition, adds up the bytes for the int health and int level, and finds a contiguous block of memory that fits.
- Lesson 620 — Allocating structs on the heap with malloc
- mandatory
- However, when you are measuring a data type directly (like int or float), the parentheses are mandatory.
- Lesson 235 — The `sizeof` operator with types
- Manual memory
- Manual memory (The Heap) is like a giant warehouse across town.
- Lesson 533 — Manual vs automatic memory management
- manual override
- Think of an explicit cast as a manual override.
- Lesson 234 — Safety with explicit casts
- Map
- Inside that Drawer is a Map that tells you exactly where the Treasure (the actual data) is hidden.
- Lesson 500 — Concept of double indirectionLesson 616 — The arrow operator `->` syntax
- MAP_ANONYMOUS
- However, when we use the MAP_ANONYMOUS flag, we tell the OS: "Give me a block of RAM that isn't connected to any file."
- Lesson 594 — Anonymous memory mappings
- mask
- Think of a mask as a piece of paper with a single hole punched in it.
- Lesson 188 — Common bitwise idioms
- Massif
- To catch these "chatty" allocation patterns, you can use profiling tools like Valgrind with the Massif tool.
- Lesson 1185 — Profiling memory allocation frequency
- master light switch
- Think of conditional compilation as a master light switch for your code: you can leave the "debug lamps" plugged in, but turn them all off with one click before shipping.
- Lesson 787 — Managing debug prints with macros
- math or logic
- If you are using a 8-bit variable for math or logic, be explicit.
- Lesson 945 — The significance of `char` signness
- math_functions.c
- If half are named MainCode.c and the other half are math_functions.c, your project becomes a messy "junk drawer." Sticking to lowercase names with underscores is a "handshake" between you and other programmers, signaling that you follow standard professional conventions.
- Lesson 16 — Naming conventions for .c files
- math_tools.c
- If main.c tries to use a function sitting in math_tools.c, it will complain that it doesn't recognize the function name.
- Lesson 377 — Role of the `.h` fileLesson 798 — Static functions for file scopingLesson 805 — What is inside a `.o` file
- math_tools.o
- When you compile this into math_tools.o, the file contains the binary logic for add and calculate.
- Lesson 805 — What is inside a `.o` file
- MATH_UTILS_H
- The first time the compiler hits this file, MATH_UTILS_H isn't defined, so it enters the file and defines it.
- Lesson 380 — Header Guards: `#ifndef` and `#define`
- math_utils.c
- If you forgot to include math_utils.c in the command, the linker would get confused and throw an "undefined reference" error because it couldn't find the instructions for add.
- Lesson 381 — Compiling multiple `.c` filesLesson 799 — The role of the 'main' fileLesson 802 — Dependency graphing in your headLesson 803 — From source code to object filesLesson 807 — Understanding 'undefined reference' errorsLesson 810 — What is a static library `.a`Lesson 811 — Creating archives with the `ar` toolLesson 814 — Position Independent Code `-fPIC`
- math_utils.o
- Because of $@ and $<, this single rule works for logger.o, math_utils.o, or player.o without you ever having to type those names manually.
- Lesson 803 — From source code to object filesLesson 809 — Symbol tables and visibilityLesson 822 — Automatic variables like `$@` and `$<`
- math.h
- To compare two floats safely, you subtract one from the other, take the absolute value (using fabs() from the math.h library), and check if the result is less than your tiny threshold.
- Lesson 166 — Comparing floating-point numbersLesson 862 — Exponential and logarithmic functions: `exp`, `log`, `log10`Lesson 864 — Rounding with `ceil`, `floor`, and `round`Lesson 866 — Absolute values for floats with `fabs`Lesson 979 — Mathematical macros using `_Generic`
- math.o
- However, if main.o tries to call a function located in math.o, the object file just leaves a blank space with a sticky note saying, "I'll need someone to plug in the math logic here later."
- Lesson 29 — Understanding `.o` and `.obj` files
- MathFunc
- Anyone reading your code immediately understands that op belongs to the MathFunc family, making your programs much easier to maintain.
- Lesson 520 — Defining `typedef` for function pointers
- matrix[A][B]
- To add an edge in an undirected adjacency matrix, you must set two values—matrix[a][b] and matrix[b][a]—to 1.
- Lesson 1040 — Adjacency Matrix implementationLesson 1043 — Adding edges in undirected graphs
- matrix[b][a]
- To add an edge in an undirected adjacency matrix, you must set two values—matrix[a][b] and matrix[b][a]—to 1.
- Lesson 1043 — Adding edges in undirected graphs
- matrix[i][j]
- This is because every matrix[i][j] must equal matrix[j][i].
- Lesson 1043 — Adding edges in undirected graphs
- matrix[j][i]
- This is because every matrix[i][j] must equal matrix[j][i].
- Lesson 1043 — Adding edges in undirected graphs
- max
- By the time the loop finishes, the variables min and max have "survived" every comparison, representing the extremes of the entire group.
- Lesson 318 — Finding Min and Max in a loopLesson 402 — Finding the maximum value in an array
- MAX_PLAYERS
- Before the compiler even looks at your logic, the preprocessor literally replaces the text MAX_PLAYERS with the digit 4.
- Lesson 115 — Defining constants with `#define`Lesson 768 — Defining constants with `#define`
- MAX_RECORDS
- By always checking your record_count against your MAX_RECORDS, you ensure that your data store remains stable.
- Lesson 1216 — Adding and Deleting records safely
- MAX_RECORDS 100
- Because C doesn't automatically shrink or grow arrays, we usually define a maximum capacity, like MAX_RECORDS 100.
- Lesson 1216 — Adding and Deleting records safely
- MAX_SPEED
- By using #undef, you ensure that MAX_SPEED doesn't leak into other parts of a large project where that name might mean something completely different.
- Lesson 769 — Removing definitions with `#undef`
- MAX_USER_LIMIT
- If you see MAX_USER_LIMIT in all caps, your brain instantly registers: "This is a constant.
- Lesson 117 — Naming conventions for constants
- Max-Heap
- In a Max-Heap, the highest value is always at the very top—the CEO.
- Lesson 1058 — Heap Sort: Binary heap concept
- Maximum Search Time = Tree Height
- Therefore, the Maximum Search Time = Tree Height.
- Lesson 1030 — Tree height and balancing concept
- maxLimit
- In this example, even though currentTemp isn't higher than maxLimit, the >= operator returns true because they are equal.
- Lesson 160 — Greater or equal `>=` and less or equal `<=`
- mechanics
- In programming, this is called documenting mechanics.
- Lesson 35 — Documenting intent vs mechanics
- megaphone
- Think of printf like a megaphone: you speak into it, and the output is broadcast immediately for the world to see.
- Lesson 703 — Formatting strings in memory with sprintf
- mem
- Because mem functions know the exact size of the buffer, the compiler and the CPU can perform "vectorization"—processing 16, 32, or even 64 bytes in a single clock cycle.
- Lesson 860 — Performance differences between `str` and `mem` functions
- member
- You must tell C which structure you are talking about before you can ask for a member inside it.
- Lesson 633 — Combining array indexing and member access
- membership_fee
- In the example above, the two membership_fee variables are actually two different people with the same name living in different houses.
- Lesson 251 — Variable scope inside if-else blocks
- memcheck
- Valgrind is most famous for its memcheck tool.
- Lesson 528 — Tools for pointer debugging (Valgrind)
- memchr
- Because memchr requires you to provide a specific size, it is safe to use on binary data where a zero byte might just be part of the data rather than the end of the "sentence." It is a robust tool for navigating raw buffers and binary files.
- Lesson 859 — Searching memory bytes with `memchr`
- memcmp
- Since memcmp checks every single bit, including the junk in the gaps, it may find differences where you didn't expect them.
- Lesson 858 — Comparing memory blocks with `memcmp`Lesson 860 — Performance differences between `str` and `mem` functions
- memcpy
- If you truly need to look at the raw bits of a variable (for example, to send them over a network), the only safe way is to use a pointer to a character type (char or unsigned char) or the memcpy function.
- Lesson 511 — Generic functions in CLesson 512 — The `memcpy` function signatureLesson 513 — Implementing a generic swap functionLesson 526 — Misaligned pointer accessLesson 527 — Pointer type-punning dangersLesson 856 — Copying memory with `memcpy`Lesson 857 — Handling overlapping regions with `memmove`Lesson 859 — Searching memory bytes with `memchr`Lesson 860 — Performance differences between `str` and `mem` functionsLesson 936 — Strict aliasing rule violations
- memmove
- Because memmove has to check for overlaps and potentially copy data in reverse, it can be slightly slower than the "dumb" memcpy.
- Lesson 857 — Handling overlapping regions with `memmove`
- memory address
- We can't put a whole struct Node inside itself (that would be like trying to put a box inside an identical-sized box), but we can store the memory address (a pointer) of another node.
- Lesson 80 — Variables in memory addressesLesson 237 — The Address-of operator `&`Lesson 506 — Command line arguments `char **argv`Lesson 626 — Self-referential structs for linked listsLesson 692 — How scanf uses memory addressesLesson 989 — Defining the self-referential node structLesson 1022 — Recursive tree node structure
- memory alignment
- This requirement is called memory alignment.
- Lesson 576 — The aligned_alloc functionLesson 638 — Understanding memory alignment
- Memory Arena
- A Memory Arena (also called a region or zone) is like taking a large cafeteria tray to the buffet.
- Lesson 585 — What is a Memory Arena
- memory efficiency
- The primary reason is memory efficiency.
- Lesson 653 — Defining a union with the union keywordLesson 656 — Overlapping memory in unions
- memory layout
- By limiting the scope to an array of structs, you focus on the most important C concepts: string manipulation (copying names into the keys), looping (searching for a specific key), and memory layout.
- Lesson 1212 — Project scope: A simple Key-Value store
- memory leak
- If you lose the "key" (the pointer) without cleaning up, the memory stays occupied—this is what we call a memory leak.
- Lesson 523 — Memory leaks and lost pointersLesson 532 — Introduction to the Heap segmentLesson 533 — Manual vs automatic memory managementLesson 988 — Freeing the dynamic arrayLesson 997 — Memory cleanup for linked listsLesson 1169 — Reading the Valgrind leak summary
- memory mapping
- Unnamed bit-fields are essential for memory mapping.
- Lesson 650 — Unnamed bit-fields for padding
- memory-mapped I/O
- Use volatile whenever you are dealing with memory-mapped I/O, interrupt service routines, or shared global variables in multi-threaded applications where a value might change without the compiler seeing it happen in the current code block.
- Lesson 914 — How `volatile` prevents compiler optimization
- Memory-mapped peripheral registers
- Memory-mapped peripheral registers (like the example above).
- Lesson 913 — The `volatile` qualifier for hardware mapping
- memset
- The memset function (found in the <string.h> header) is your "giant squeegee." It is designed to fill a block of memory with a specific byte value as fast as possible.
- Lesson 430 — Setting memory blocks with `memset`Lesson 855 — Setting memory blocks with `memset`Lesson 859 — Searching memory bytes with `memchr`
- merge
- The merge function takes a range within an array, treats it as two halves, and uses a temporary array to build the result.
- Lesson 1054 — Merge Sort: The Merge function
- Merge Sort
- Some algorithms, like Merge Sort, follow a "divide and conquer" approach that requires creating temporary arrays to hold data while comparing it.
- Lesson 1051 — In-place sorting vs extra memory
- Message
- By subtracting the start of the string (message) from the pointer returned by the function, we can calculate the exact index where the character lives.
- Lesson 671 — Anonymous unions inside structsLesson 851 — Searching for characters with `strchr` and `strrchr`
- message[0] = 'B'
- If you try to do something like message[0] = 'B'; to turn "Hello" into "Bello," your program will likely crash (a "Segmentation Fault").
- Lesson 479 — String literals as `char` pointers
- message[0] = 'J'
- In C, if you try to modify a string literal—for example, by writing message[0] = 'J';—your program will likely crash with a "Segmentation Fault." The compiler won't always warn you about this danger because char * looks like any other pointer that is allowed to change data.
- Lesson 485 — Using `const char *` for safety
- mid
- We then tell the function to handle the left half (from low to mid) and the right half (from mid + 1 to high).
- Lesson 1055 — Merge Sort: Recursive splittingLesson 1062 — Binary Search: Iterative approach
- mid + 1
- We then tell the function to handle the left half (from low to mid) and the right half (from mid + 1 to high).
- Lesson 1055 — Merge Sort: Recursive splitting
- might result in
- If C didn't do this, adding 0.5 to 1 might result in 1 instead of 1.5 because the computer might try to force everything into a whole-number format.
- Lesson 126 — The 'Usual Arithmetic Conversions'
- min
- However, if you are looking for the minimum value in a list of positive test scores and you start your min at 0, no score will ever be smaller than 0.
- Lesson 318 — Finding Min and Max in a loop
- MinGW
- On Windows, the most popular free "translator" for this job is MinGW (Minimalist GNU for Windows).
- Lesson 11 — Setting up MinGW on Windows
- Minimum Viable Product (MVP)
- Instead, we are going to focus on a Minimum Viable Product (MVP).
- Lesson 1204 — Project scope: A custom `grep` clone
- misaligned access
- In the world of C, this "stitching together" is called a misaligned access.
- Lesson 526 — Misaligned pointer access
- missing_document.txt
- If missing_document.txt is not there, your console will display:
- Lesson 741 — Using perror for descriptive errors
- mkdir
- When you type ls or mkdir, the shell doesn't become that command; it forks a child.
- Lesson 1083 — Combining fork() and exec()
- mkfifo()
- mkfifo() creates a special file on the system that acts as a permanent gateway for unrelated processes to exchange data streams.
- Lesson 1106 — Introduction to named pipes (FIFOs)Lesson 1107 — Creating FIFOs with mkfifo()
- mkstemp
- In modern, high-security professional software, developers often use more advanced functions like mkstemp.
- Lesson 759 — Generating temp filenames with tmpnam
- mkstemp()
- By using mkstemp(), you ensure that if a file with that random name already exists, the system will try a different random name until it finds a truly unique one, leaving no room for a hacker to intercept your data.
- Lesson 763 — Temporary file security risks
- mktemp()
- Older C functions like tmpnam() or mktemp() are dangerous because they only suggest a filename.
- Lesson 763 — Temporary file security risks
- mktime
- Notice that mktime modifies the original my_date variable to fill in the day of the week, saving you from doing the complex calendar math yourself.
- Lesson 895 — Converting `struct tm` back to `time_t` with `mktime`
- mmap
- If you pass an incorrect length or a pointer that wasn't returned by mmap, the operating system will likely throw an error, as you are trying to return "books" that don't belong to you.
- Lesson 590 — Growing an arena with virtual memoryLesson 593 — Using mmap for large allocationsLesson 594 — Anonymous memory mappingsLesson 596 — The munmap function
- mmap()
- When you ask the operating system for a specific chunk of memory using system calls like mmap(), you don't just get a blank slate; you get to decide what the CPU is allowed to do with that space.
- Lesson 594 — Anonymous memory mappingsLesson 595 — Memory protection constants (PROT_READ)
- mock
- A mock is a "stunt double." It has the exact same name and signature as the real function, but instead of doing hard work, it returns a hard-coded value that you control.
- Lesson 1176 — Mocking simple dependencies
- mock_sensor.c
- When you compile your test, you simply link logic.c and test_main.c with your mock_sensor.c instead of the real hardware driver.
- Lesson 1176 — Mocking simple dependencies
- mode
- By using unnamed bit-fields, you ensure that mode starts at exactly the 6th bit without cluttering your code with "dummy" variables like int reserved1; or int ignoreMe;.
- Lesson 650 — Unnamed bit-fields for padding
- modular building
- The -c flag allows for modular building: you prepare the pieces individually so that the final assembly is fast and organized.
- Lesson 804 — The `-c` flag for compilation
- Modular Compilation
- In C, object files allow for Modular Compilation:
- Lesson 29 — Understanding `.o` and `.obj` files
- modulo operator
- To capture that "leftover" value, we use the modulo operator, represented by the percent sign %.
- Lesson 155 — The modulo operator `%` with integers
- modulo operator (%)
- However, because rand() gives you such a wide range of numbers, you will almost always use the modulo operator (%) to "squish" that number into a range that is useful for your program.
- Lesson 883 — Generating pseudo-random numbers with `rand`Lesson 887 — Scaling `rand` results to a specific rangeLesson 1018 — Circular array implementationLesson 1032 — A simple modular hash function
- MONDAY
- You can add Monday to Red, or assign the number 402 to a variable that is supposed to only hold True or False.
- Lesson 662 — Default integer values in enumsLesson 667 — Type safety concerns with enums
- money
- Portability: If you define Money as a float and later realize you need more precision, you only have to change one line of code (the typedef) to turn every Money variable into a double.
- Lesson 343 — Why changing a parameter doesn't affect the callerLesson 608 — Using typedef with primitive types
- month is zero-indexed
- First, the month is zero-indexed, so December is 11.
- Lesson 891 — Breaking down time with `struct tm`
- MOT_
- If you are writing a module for managing a motor, every public function and global variable should start with MOT_ or motor_.
- Lesson 801 — Naming conventions for large projects
- motor_
- If you are writing a module for managing a motor, every public function and global variable should start with MOT_ or motor_.
- Lesson 801 — Naming conventions for large projects
- mov
- In C, a command like mov might exist on both platforms, but the order of the inputs and how the CPU handles them is completely different.
- Lesson 26 — Phase 2: Compilation to AssemblyLesson 27 — Phase 3: Assembly to Object CodeLesson 957 — The `asm` keyword syntaxLesson 963 — Platform-specific assembly (x86 vs ARM)
- msg.data.text
- Normally, nesting a union requires giving it a name, leading to clunky access like msg.data.text.
- Lesson 671 — Anonymous unions inside structs
- MSYS2
- The simplest way to get MinGW is through a project called MSYS2, which manages the installation for you.
- Lesson 11 — Setting up MinGW on Windows
- mtx_init
- C11 provides thrd_create to start a task and mtx_init for "mutexes" (locks), which ensure two chefs don't try to use the same knife at the exact same time.
- Lesson 967 — C11: Multi-threading and Anonymous structures
- multiple definition
- If two different source files (.c files) both claim to "own" the same global variable, the linker gets confused and quits with a multiple definition error.
- Lesson 925 — Common linkage errors and 'multiple definition'
- multiply_and_print
- Instead of writing separate functions for add_and_print and multiply_and_print, we write one compute function that accepts a "math rule" as an argument.
- Lesson 518 — Passing functions as arguments
- munmap
- The munmap function releases a specific range of memory pages back to the operating system, requiring both the starting address and the exact size of the region.
- Lesson 596 — The munmap function
- must be sorted
- However, there is a catch: to use the O(log n) approach, your data must be sorted beforehand.
- Lesson 1065 — Time complexity: O(n) vs O(log n)
- Mutex
- In C programming, a Mutex (short for Mutual Exclusion) is that key.
- Lesson 1125 — Initializing a pthread_mutex_tLesson 1126 — Locking and unlocking mutexesLesson 1127 — Critical section best practicesLesson 1132 — Introduction to condition variablesLesson 1145 — Compare and swap (CAS) basics
- mutex_a
- If Thread 1 has already grabbed mutex_a, Thread 2 will simply wait at the very first line of its code until Thread 1 is completely finished with both locks.
- Lesson 1139 — Common synchronization pitfalls
- mutex_b
- If both Thread 1 and Thread 2 are programmed to always lock mutex_a before mutex_b, the deadlock vanishes.
- Lesson 1139 — Common synchronization pitfalls
- Mutexes
- To solve this in C, we use two tools: Mutexes (to ensure only one thread touches the rack at a time) and Semaphores (to track how many spots are full or empty).
- Lesson 1124 — Understanding race conditionsLesson 1136 — The producer-consumer problem
- My First Program.c
- Bad: My First Program.c (Spaces can break command-line tools).
- Lesson 16 — Naming conventions for .c files
- my_age
- The sequence point ensures that by the time display_age starts, my_age has officially become 26 in the computer's memory.
- Lesson 226 — Function call sequence points
- my_age++
- In this example, the expression my_age++ has a value (25) and a side effect (changing the variable to 26).
- Lesson 226 — Function call sequence points
- my_area
- Instead, it directly modifies my_area and my_perimeter back in the main function.
- Lesson 489 — Returning multiple values via pointers
- my_array[3]
- When you write my_array[3], you are using "array subscript notation." It’s comfortable and easy to read.
- Lesson 473 — The equivalence of `a[i]` and `*(a + i)`
- my_buffer
- When you use gets(my_buffer), you are telling C to take whatever the user types and shove it into my_buffer.
- Lesson 432 — Why `gets` is dangerous and deprecated
- my_date
- Notice that mktime modifies the original my_date variable to fill in the day of the week, saving you from doing the complex calendar math yourself.
- Lesson 895 — Converting `struct tm` back to `time_t` with `mktime`
- my_float
- This often fails because the compiler doesn't expect ptr_as_int to affect my_float.
- Lesson 527 — Pointer type-punning dangers
- my_function()
- Creation: When my_function() starts, a block of memory is reserved on the stack.
- Lesson 530 — Stack frame lifecycle and local variables
- my_label
- The Colon: The label destination ends with a colon (my_label:), but the goto command ends with a semicolon (goto my_label;).
- Lesson 307 — The syntax of the goto statement
- my_logger.log_message()
- Your main program doesn't have to change; it simply calls my_logger.log_message(), trusting that the correct behavior has been "plugged in."
- Lesson 675 — Implementing an interface with function pointers in structs
- my_perimeter
- Instead, it directly modifies my_area and my_perimeter back in the main function.
- Lesson 489 — Returning multiple values via pointers
- my_program
- If you were to peak inside the resulting my_program file with a tool like readelf, you would see the OS-level headers that turn your simple C logic into a formal, runnable application.
- Lesson 30 — Creating an executable binaryLesson 57 — Basic `gcc` command flagsLesson 59 — Compiling multiple source filesLesson 806 — Linking multiple object filesLesson 808 — The executable ELF formatLesson 812 — Linking with static libraries
- my_project.supp
- You can copy that block into a file named my_project.supp.
- Lesson 570 — Suppressing known tool warnings
- my_settings.h
- When it sees #include "my_settings.h", it pauses, opens your file named my_settings.h, copies everything inside it, and pastes it directly into your main file at that exact spot before the compiler even starts reading the code.
- Lesson 766 — The `#include` directive for local files
- my_variable
- Because standard C variables usually start with lowercase letters (my_variable), a capitalized name signals that you are looking at a custom-defined type.
- Lesson 75 — The syntax of a declarationLesson 612 — Naming conventions for typedef types
- myAccount
- In this example, Account_t is the blueprint, and myAccount is the actual data.
- Lesson 612 — Naming conventions for typedef types
- myApp
- .size: Look inside myApp for a member named size.
- Lesson 624 — Accessing members of nested structs
- myApp.size.width
- When you see myApp.size.width, read it from left to right as a map:
- Lesson 624 — Accessing members of nested structs
- myBook.pages = 300
- Up until now, you might have filled these compartments one by one using the "dot" operator: myBook.pages = 300;.
- Lesson 602 — Initializing structs with brace notation
- myCar
- For example, if you have myCar.speed, you are looking directly at the "speed" property of the myCar object.
- Lesson 616 — The arrow operator `->` syntax
- myCar.speed
- For example, if you have myCar.speed, you are looking directly at the "speed" property of the myCar object.
- Lesson 616 — The arrow operator `->` syntax
- myData.decimal
- When you write to myData.decimal, the computer writes 32 bits to memory in a format called IEEE 754 (the standard for decimals).
- Lesson 659 — The danger of reading the wrong union member
- myData.integer
- When you ask for myData.integer, the computer looks at those exact same 32 bits but interprets them using two's complement (the standard for integers).
- Lesson 659 — The danger of reading the wrong union member
- myGrid
- In the example above, myGrid acts like a table.
- Lesson 407 — Declaring 2D arrays: Rows and Columns
- myHealth
- In the code above, the variable names myLevel and myHealth don't actually matter to the displayStats function.
- Lesson 337 — Positional matching of arguments
- myInt
- Just show me the bits." The myInt member gives us the integer 1073741824, which is the decimal version of those raw bits.
- Lesson 657 — Using unions for type punning
- MyLabel
- They are case-sensitive (MyLabel is different from mylabel).
- Lesson 306 — Defining labels in C code
- myLevel
- In the code above, the variable names myLevel and myHealth don't actually matter to the displayStats function.
- Lesson 337 — Positional matching of arguments
- myNumber
- It looks at myNumber, sees the value 10, and scribbles 10 into that new memory spot.
- Lesson 341 — Understanding 'Pass by Value'
- myPtr
- Your pointer myPtr simply holds the address of that distant neighborhood.
- Lesson 484 — Memory layout of string pointers
- mySavings
- Once the function finishes, the money variable is destroyed, and mySavings remains exactly as it was.
- Lesson 343 — Why changing a parameter doesn't affect the caller
- myScore
- When addScore(myScore) is called, C looks at the value inside myScore (which is 50) and copies that number into a brand new memory bucket named localScore.
- Lesson 346 — Preparing for pass by referenceLesson 486 — Pass-by-value limitations
- mytool
- The make utility looks for the file, checks if main.c or utils.c are newer than the existing mytool executable, and runs the compiler only if needed.
- Lesson 1211 — Writing the Makefile for the project
- myValues
- In the example below, notice how we pass myValues to the function.
- Lesson 474 — Passing arrays to functions as pointers
- myVariable
- No spaces: Use "camelCase" (like myVariable) or "snake_case" (like my_variable).
- Lesson 75 — The syntax of a declaration
N
- n - i - 1
- You might notice the inner loop runs until n - i - 1.
- Lesson 445 — Sorting an array using Bubble Sort
- n <= 0
- Once the base case (n <= 0) is reached, no new frames are added.
- Lesson 359 — The call stack in recursion
- n=3
- When count(3) is called, a frame for n=3 is pushed onto the stack.
- Lesson 359 — The call stack in recursion
- name
- To declare an array in C, you need three specific pieces of information: the type of data you are storing, a name for the array, and the size (how many slots you need) inside square brackets.
- Lesson 239 — Member access `.` and `->`Lesson 383 — Declaring an array with `type name[size]`Lesson 436 — Using `strncat` for safer concatenationLesson 630 — Declaring an array of structsLesson 879 — Sorting structs by multiple fieldsLesson 938 — Accessing out-of-bounds memory
- NAME = value
- To create one, use the equals sign: NAME = value.
- Lesson 821 — Using variables in Makefiles
- name[5] = '\0'
- By setting name[5] = '\0', you chop off the newline, leaving you with a clean "Alice".
- Lesson 702 — Removing the newline from fgets
- Named Pipe
- A FIFO (First-In, First-Out) is often called a Named Pipe.
- Lesson 1107 — Creating FIFOs with mkfifo()
- NAN
- A NAN is like a contagious virus: any math operation involving a NAN will result in another NAN.
- Lesson 867 — Handling `NAN` and `INFINITY` constants
- NASA_ROVER_
- Be Unique: Always prefix guards with your project name (e.g., NASA_ROVER_).
- Lesson 1203 — Header guard best practices
- NDEBUG
- Instead of manually deleting every assert() line from your source code—which would be a nightmare to put back later if you found a bug—the C Standard Library provides a "kill switch" called NDEBUG (which stands for "No Debug").
- Lesson 901 — Using `assert` for internal debuggingLesson 902 — Disabling assertions with `NDEBUG`
- needle
- You have a large field (the haystack) and you are waving your detector to find a specific metal object (the needle).
- Lesson 852 — Finding substrings with `strstr`
- negative
- A negative number if the first item comes before the second.
- Lesson 1059 — Using C library 'qsort' function
- nested loop
- We use a nested loop: an outer loop that handles the rows and an inner loop that handles the individual columns within those rows.
- Lesson 412 — Printing a 2D matrix to the console
- nested loops
- In C, we replicate this movement using nested loops.
- Lesson 411 — Nested `for` loops for 2D traversalLesson 445 — Sorting an array using Bubble Sort
- NET_
- Use unique, module-specific prefixes (like UI_ or NET_) for all public functions and global variables to prevent naming conflicts in large projects.
- Lesson 801 — Naming conventions for large projects
- Network
- But as your project grows into dozens of .c files, you might have one file handling Network connections and another handling User profiles.
- Lesson 801 — Naming conventions for large projects
- Network Byte Order
- To fix this, the internet uses a standard "postal code" rule: all data traveling over a network must be in Big-Endian format, also known as Network Byte Order.
- Lesson 952 — Network byte order and `htons`/`ntohs`
- Never trust the user
- The golden rule of command-line utilities is: Never trust the user. You must check argc before touching anything in argv.
- Lesson 1205 — Handling `argc` and `argv` robustly
- new
- To avoid these traps, always set the pointers on your new node first.
- Lesson 1005 — Common pointer update pitfalls
- new_node
- When you insert a new node (new_node) between two existing nodes (prev_node and next_node), you must update four pointers to maintain the integrity of the chain.
- Lesson 1002 — Inserting in a doubly linked list
- new_node->next
- If you update prev_node->next before you've saved its value into new_node->next, you lose your connection to the rest of the list—it’s like dropping the hand of the person behind you before the new person has grabbed it.
- Lesson 1002 — Inserting in a doubly linked list
- new_node->prev
- New Node's Prev: Point new_node->prev to the prev_node.
- Lesson 1002 — Inserting in a doubly linked list
- newfd
- In plain English, this says: "Make newfd a copy of oldfd." If newfd was already open, the system closes it first to make room for the new connection.
- Lesson 1095 — Redirecting output with dup2()
- newline character
- In C, we use a special symbol called the newline character, written as \n.
- Lesson 44 — Newline character `\n`
- newNode->next = NULL
- By setting newNode->next = NULL, you are essentially saying, "This is a valid node, but it isn't connected to a chain yet." Without this step, the next pointer would contain "garbage" data—a random memory address that could cause your program to crash if you tried to follow it.
- Lesson 991 — Allocating a new node in memory
- next
- By setting newNode->next = NULL, you are essentially saying, "This is a valid node, but it isn't connected to a chain yet." Without this step, the next pointer would contain "garbage" data—a random memory address that could cause your program to crash if you tried to follow it.
- Lesson 626 — Self-referential structs for linked listsLesson 830 — Stepping through code with `next` and `step`Lesson 836 — Using `watch` for memory changesLesson 989 — Defining the self-referential node structLesson 991 — Allocating a new node in memoryLesson 992 — Traversing the list with a while loopLesson 993 — Prepending nodes to the headLesson 994 — Appending nodes to the tailLesson 996 — Deleting a node by valueLesson 998 — The 'prev' pointer conceptLesson 999 — Updating the node structLesson 1001 — Bidirectional traversalLesson 1003 — Deleting without head traversalLesson 1004 — Circular doubly linked listsLesson 1005 — Common pointer update pitfallsLesson 1008 — Linked list-based stack implementation
- next available slot
- Instead, you are telling the pointer to move to the next available slot of that specific data type.
- Lesson 465 — How data types affect step size
- next_free_byte
- It is best used for "scratchpad" memory where you fill the pool during a task and reset the next_free_byte to zero when the task is finished.
- Lesson 580 — Managing a static memory pool
- next_node
- When you insert a new node (new_node) between two existing nodes (prev_node and next_node), you must update four pointers to maintain the integrity of the chain.
- Lesson 1002 — Inserting in a doubly linked list
- next_node->prev
- Backward Link: Point next_node->prev to the new_node.
- Lesson 1002 — Inserting in a doubly linked list
- nextNode = current->next
- If we called free(current) before assigning nextNode = current->next, we would be attempting to access current->next from memory that we no longer own.
- Lesson 997 — Memory cleanup for linked lists
- no equals sign
- Notice that there is no equals sign and no semicolon at the end.
- Lesson 768 — Defining constants with `#define`
- no semicolon
- Notice that there is no equals sign and no semicolon at the end.
- Lesson 768 — Defining constants with `#define`
- no type
- If there is no type (just *p in an equation), you are traveling through the pointer to the value it points to.
- Lesson 456 — The difference between `int *p` and `*p`
- Node
- In a linked list stack, every element is a node containing two things: the data and a pointer to the next node.
- Lesson 579 — Building a simple free listLesson 989 — Defining the self-referential node structLesson 1008 — Linked list-based stack implementationLesson 1020 — Linked list queue implementation
- Node B
- In programming terms, if you are at Node C and need to access Node B, a singly linked list leaves you stranded.
- Lesson 998 — The 'prev' pointer concept
- Node buckets
- By using Node buckets, we are creating an array of "Head Pointers." Each index in our array acts as the start of a linked list.
- Lesson 1034 — Implementing the bucket array
- Node C
- In programming terms, if you are at Node C and need to access Node B, a singly linked list leaves you stranded.
- Lesson 998 — The 'prev' pointer concept
- node->data
- Indirectly lost: The memory for the int array (node->data).
- Lesson 567 — Identifying 'indirectly lost' memory
- non-portable
- While bit-fields are efficient, they come with a major warning: they are highly non-portable.
- Lesson 954 — Bit-fields in structures and portability
- nondeterministic
- Race conditions are the most hated bugs in systems programming because they are nondeterministic.
- Lesson 1124 — Understanding race conditions
- nop
- During the optimization phase (like -O2 or -O3), it might decide the nop is dead code and remove it entirely.
- Lesson 958 — The basic `volatile` asm block
- normalCount
- In the code above, normalCount is born and dies with every function call.
- Lesson 144 — Static local variables
- notebook
- A static variable is like a notebook kept in that same room; even if everyone leaves and comes back tomorrow, the notes from the last meeting are still there.
- Lesson 920 — The `static` keyword inside functions
- nput/
- The name stands for Standard Input/Output, and the .h indicates it is a "header" file.
- Lesson 18 — The `#include` directiveLesson 678 — The header file <stdio.h>
- ntohl()
- While many systems provide built-in functions like ntohl() for networking, writing your own swap logic ensures your code is portable across different compilers and platforms.
- Lesson 953 — Manual byte swapping techniques
- ntohs
- Always use htons when sending data and ntohs when receiving it to ensure your numbers remain consistent across different types of hardware.
- Lesson 952 — Network byte order and `htons`/`ntohs`
- ntohs()
- network to host short (converts it back so your programs can read it).
- Lesson 952 — Network byte order and `htons`/`ntohs`
- NULL
- A NULL pointer is a special "grounding" value that tells the computer, "This pointer intentionally points to nothing." If you accidentally try to use a NULL pointer, the program will crash instantly and predictably, which is much easier to fix than a wild pointer causing silent damage.
- Lesson 427 — Searching for characters with `strchr`Lesson 428 — Searching for substrings with `strstr`Lesson 429 — Tokenizing strings with `strtok`Lesson 459 — Initializing pointers to NULLLesson 462 — Checking for NULL before dereferencingLesson 521 — Uninitialized 'wild' pointersLesson 522 — Dangling pointers after `free`Lesson 525 — Dereferencing the NULL pointerLesson 539 — Checking for NULL return valuesLesson 542 — Why freeing NULL is safeLesson 546 — Resizing blocks with reallocLesson 547 — Handling realloc failure safelyLesson 549 — Using realloc as malloc or freeLesson 554 — Double-freeing a pointerLesson 557 — What is a dangling pointerLesson 559 — Setting pointers to NULL after freeLesson 562 — Use-after-free vulnerabilitiesLesson 602 — Initializing structs with brace notationLesson 603 — Designated initializers in C99Lesson 622 — The importance of NULL checks for struct pointersLesson 626 — Self-referential structs for linked listsLesson 707 — Checking for NULL return in fgetsLesson 709 — Opening files with fopenLesson 710 — Understanding file modes: r, w, aLesson 712 — Checking for NULL file pointersLesson 714 — Handling file not found errorsLesson 715 — The maximum number of open filesLesson 740 — Introduction to errnoLesson 741 — Using perror for descriptive errorsLesson 745 — Handling 'Permission Denied' errorsLesson 747 — Safe file closing patternsLesson 753 — The setbuf shorthandLesson 762 — Checking if a file existsLesson 851 — Searching for characters with `strchr` and `strrchr`Lesson 852 — Finding substrings with `strstr`Lesson 853 — Tokenizing strings with `strtok`Lesson 859 — Searching memory bytes with `memchr`Lesson 870 — Resizing blocks with `realloc`Lesson 880 — Using `bsearch` on sorted arraysLesson 881 — Handling the `void*` return of `bsearch`Lesson 889 — Getting system time with `time_t`Lesson 897 — The global `errno` variableLesson 898 — Interpreting errors with `perror`Lesson 901 — Using `assert` for internal debuggingLesson 903 — When to use `errno` vs return codesLesson 970 — C23: The `nullptr` constantLesson 982 — Initial memory allocation with mallocLesson 988 — Freeing the dynamic arrayLesson 990 — Creating the head pointerLesson 992 — Traversing the list with a while loop
- null statement
- However, when you accidentally place one immediately after a while condition, you create what programmers call a null statement.
- Lesson 272 — Common error: semicolon after while header
- null terminator
- However, there is a catch: C strings must always end with a special hidden character called the null terminator, written as \0.
- Lesson 416 — Defining strings with double quotesLesson 417 — The Null Terminator `\0` characterLesson 418 — Difference between `'a'` and `"a"`Lesson 419 — Initializing strings with sizes
- nullptr
- By using nullptr, you tell the compiler, "I am definitely dealing with a memory address here." This helps modern static analysis tools catch errors faster and ensures your code is ready for the future of the language.
- Lesson 970 — C23: The `nullptr` constant
- nullptr_t
- Unlike NULL, which is a macro that expands to an integer, nullptr is a reserved keyword with its own special type: nullptr_t.
- Lesson 970 — C23: The `nullptr` constant
- num
- If it reaches the limit (num) without finding it, it returns NULL.
- Lesson 339 — Local scope of parametersLesson 859 — Searching memory bytes with `memchr`
- number_of_tests
- Because one side of the division is now a double, C automatically promotes number_of_tests to a double as well, resulting in a precise calculation.
- Lesson 230 — The `(type)` cast operator
- numbers
- In this snippet, fread looks at the file, grabs enough bytes to fill three integers, and dumps them directly into the numbers array.
- Lesson 471 — Array names as constant pointersLesson 472 — Accessing arrays with pointer notationLesson 474 — Passing arrays to functions as pointersLesson 475 — Array decay explainedLesson 476 — Pointer to the start of an arrayLesson 725 — Writing raw bytes with fwriteLesson 726 — Reading raw bytes with fread
- numbers = &some_other_int
- If you try to do numbers = &some_other_int;, the compiler will throw an error.
- Lesson 471 — Array names as constant pointers
- numbers[0]
- In C, if you use the name numbers without any square brackets, the compiler treats it as the memory address of numbers[0].
- Lesson 472 — Accessing arrays with pointer notationLesson 476 — Pointer to the start of an array
- numbers[1]
- numbers[1] is the same as *(numbers + 1)
- Lesson 472 — Accessing arrays with pointer notation
- numbers[2]
- When you write numbers[2], the compiler is actually performing pointer arithmetic under the hood: it takes the starting address and adds two "steps" of the integer size to find the value.
- Lesson 470 — Navigating memory blocks manuallyLesson 472 — Accessing arrays with pointer notation
- numbers[i]
- While using numbers[i] is often more readable, incrementing a pointer is a fundamental pattern in low-level programming.
- Lesson 477 — Iterating arrays using pointer increments
O
- O_CLOEXEC
- You can set this flag when you first open the file using the O_CLOEXEC flag, or later using fcntl.
- Lesson 1096 — The close-on-exec flag
- O_NONBLOCK
- To do this, we use the fcntl() (file control) function to add the O_NONBLOCK flag to a file descriptor.
- Lesson 1098 — Non-blocking I/O basics
- O(log n)
- When searching for a specific value in a collection, the two most common speeds you will encounter are O(n) and O(log n).
- Lesson 1027 — Searching for a value in BSTLesson 1065 — Time complexity: O(n) vs O(log n)
- O(n)
- When searching for a specific value in a collection, the two most common speeds you will encounter are O(n) and O(log n).
- Lesson 1065 — Time complexity: O(n) vs O(log n)
- O(n²)
- In computer science, we call this O(n²) complexity (pronounced "Big O of n-squared").
- Lesson 1050 — Time complexity of O(n^2) sorts
- Object Code
- During this step, the compiler takes your source code and translates it into Object Code.
- Lesson 803 — From source code to object files
- Object File
- Between your text file (main.c) and your final app (main.exe), there is a crucial middle step: the Object File.
- Lesson 27 — Phase 3: Assembly to Object CodeLesson 29 — Understanding `.o` and `.obj` filesLesson 803 — From source code to object filesLesson 804 — The `-c` flag for compilationLesson 806 — Linking multiple object files
- of
- Think of the dot as the word "of." When you write hero.level, you are telling C: "Look at the level of hero."
- Lesson 350 — Return addresses in memoryLesson 601 — The dot operator for member access
- OFF
- Computers, however, are made of tiny electronic switches that can only be in two states: ON (1) or OFF (0).
- Lesson 167 — Logical NOT `!`Lesson 179 — Understanding binary representation
- Off-By-One
- The most frequent cause of an invalid read is the Off-By-One error.
- Lesson 1166 — Identifying 'Invalid Read' errors
- offset
- Virtual memory is divided into fixed-size pages (usually 4KB), and every address identifies a specific page number and a byte offset within that page.
- Lesson 587 — Resetting an arena in one stepLesson 588 — Arena allocation for frame-based tasksLesson 597 — Virtual memory pages and offsets
- OK
- Because C lacks true namespacing for enums, the names RED, YELLOW, and OK become global constants.
- Lesson 666 — Scoped enum limitations in C
- oldfd
- In plain English, this says: "Make newfd a copy of oldfd." If newfd was already open, the system closes it first to make room for the new connection.
- Lesson 1095 — Redirecting output with dup2()
- ON
- Computers, however, are made of tiny electronic switches that can only be in two states: ON (1) or OFF (0).
- Lesson 167 — Logical NOT `!`Lesson 179 — Understanding binary representation
- on a highlighted function
- By pressing a on a highlighted function, perf will show you your C code side-by-side with the assembly instructions.
- Lesson 1186 — Using `perf` for hardware-level insights
- once
- When you mark a local variable as static, it is initialized only once (when the program starts) and persists for the entire life of the program.
- Lesson 144 — Static local variablesLesson 282 — The three parts of a for loop headerLesson 283 — Initialization, condition, and increment flowLesson 888 — Getting a unique seed with `time(NULL)`Lesson 920 — The `static` keyword inside functions
- one
- They group multiple statements together into a single "block." However, C allows a shorthand that often trips up beginners: if a control structure (like an if statement or a for loop) only needs to execute exactly one statement, the braces are optional.
- Lesson 250 — Curly brace requirements for single vs multi-lineLesson 653 — Defining a union with the union keywordLesson 660 — Initializing a unionLesson 799 — The role of the 'main' fileLesson 1134 — Signaling with pthread_cond_signalLesson 1135 — Broadcasting to all threads
- one apple
- We take the weight of the whole bag and divide it by the weight of one apple.
- Lesson 388 — Calculating array size with `sizeof`
- one byte
- Each cubby is exactly the same size: one byte (8 bits).
- Lesson 447 — Memory as a linear sequence of bytes
- one data type
- Instead, you are telling the computer to move forward by one data type.
- Lesson 468 — Scaling factor in pointer math
- One free() for every malloc()
- The golden rule is: One free() for every malloc(). Think of them as a pair of brackets that must always be closed.
- Lesson 553 — The 'Free after use' rule
- one whole data type
- Instead, you are telling the pointer to move forward by one whole data type.
- Lesson 464 — Adding integers to pointers
- one-quarter
- A common industry standard is the Quarter-Rule: only shrink the capacity by half when the size drops to one-quarter of the capacity.
- Lesson 987 — Popping and shrinking logic
- only if both compared bits are
- The bitwise & operator returns a 1 only if both compared bits are 1, making it perfect for extracting specific bits from a value.
- Lesson 175 — Bitwise AND `&`
- only results in a
- Because & only results in a 1 if both sides are 1, using our mask will zero out everything except the bit we care about.
- Lesson 188 — Common bitwise idioms
- ontiguous
- calloc (short for contiguous allocation) is the more polite version of this request.
- Lesson 543 — Contiguous allocation with calloc
- OOM (Out of Memory) Killer
- When a process "hog" consumes all memory, the operating system may trigger an OOM (Out of Memory) Killer.
- Lesson 556 — Impact of leaks on long-running processes
- op
- Anyone reading your code immediately understands that op belongs to the MathFunc family, making your programs much easier to maintain.
- Lesson 520 — Defining `typedef` for function pointers
- Opaque Types
- In C, we achieve this "sealed case" using Opaque Types.
- Lesson 673 — Opaque types with header files
- open()
- If you open a FIFO to write, the open() function will pause your program until another program opens that same file to read.
- Lesson 1092 — File descriptors vs FILE pointersLesson 1106 — Introduction to named pipes (FIFOs)
- operands
- In programming terminology, we call the numbers being added operands.
- Lesson 150 — The addition operator `+`
- operate
- By defining a standard set of function pointers, you create an Interface: a contract that says "any struct of this type will have a function named operate, but how it operates is up to the specific instance."
- Lesson 675 — Implementing an interface with function pointers in structs
- operation compares the
- In the example above, the & operation compares the input and mask bit-by-bit.
- Lesson 180 — Masking bits with `&`
- operator (like
- While it is tempting to use the - operator (like end - start), the C standard doesn't actually mandate that time_t must be a simple count of seconds.
- Lesson 890 — Measuring intervals with `difftime`
- operator flips a true value to
- The ! operator flips a true value to 0 and any false value (0) to 1.
- Lesson 167 — Logical NOT `!`
- operator flips truth to
- The ! operator flips truth to 0 and falsehood to 1, while !! scales any non-zero value down to a clean 1.
- Lesson 174 — Operator `!` and boolean normalization
- operator on a
- If you try to use the operator on a void , the compiler will throw an error because it doesn't know where the data ends or how to translate the binary 1s and 0s.
- Lesson 508 — Why you can't dereference `void *`
- Operator Precedence
- Instead, C follows the rules of Operator Precedence.
- Lesson 216 — Precedence of `*` over `+`
- Operator Precedence Table
- C follows a similar, but much larger, set of rules called the Operator Precedence Table.
- Lesson 212 — Operator precedence table
- operator returns a
- The bitwise & operator returns a 1 only if both compared bits are 1, making it perfect for extracting specific bits from a value.
- Lesson 175 — Bitwise AND `&`
- operator with
- Use the & operator with scanf to pass a variable's memory address, allowing the function to reach into your computer's storage and update the value directly.
- Lesson 692 — How scanf uses memory addresses
- Optimization Levels
- In C, we give this permission using Optimization Levels.
- Lesson 1188 — Compiler optimization levels (`-O1`, `-O2`, `-O3`)
- or for working with
- For this reason, memset is almost exclusively used for setting memory to 0 or for working with char arrays (strings).
- Lesson 855 — Setting memory blocks with `memset`
- ORANGE
- If you add ORANGE in the middle later, C re-numbers the rest automatically.
- Lesson 664 — Enums vs constant integers
- oranges
- One bucket represents the variable apples and the other represents oranges.
- Lesson 150 — The addition operator `+`
- order
- Think of it like a shipping kit: you have a large Order box, and inside it, there is a smaller Address box.
- Lesson 55 — Argument-specifier matchingLesson 625 — Initializing nested structures
- order matters
- The key rule to remember is order matters.
- Lesson 602 — Initializing structs with brace notation
- Order of Operations
- It doesn't necessarily do the heavy lifting itself, but it dictates the order of operations.
- Lesson 54 — Multiple specifiers in one lineLesson 773 — Why parenthesize macro argumentsLesson 799 — The role of the 'main' file
- original
- When you use x-- in a line of code, C uses the original value of x for whatever calculation is happening right now, and only after that calculation is finished does it subtract one from the variable.
- Lesson 201 — Postfix decrement `x--`Lesson 607 — The syntax of typedef
- Otherwise
- To make a complete system, you need a backup plan: "Otherwise, turn on the fan."
- Lesson 245 — The else clause for alternative paths
- outer loop
- Nested loops work the same way: an inner loop completes its entire run for every single step of the outer loop.
- Lesson 299 — Inner loop vs outer loop execution orderLesson 300 — Using nested loops to print 2D gridsLesson 301 — Nested loops for multiplication tables
- output
- The compiler looks at your constraints, picks two registers, moves the value of input into the second register, runs your assembly, and then moves the result from the first register back into the output variable.
- Lesson 58 — Naming the output with `-o`Lesson 916 — Optimization benefits of `restrict`Lesson 959 — Input and Output operands in assembly
- output[0]
- If I write to output[0], I might be changing the value of input[1]!" To be safe, it would reload input[i] from the slow main memory every single time.
- Lesson 916 — Optimization benefits of `restrict`
- outside
- When you declare an array outside of any function (a global array), C acts like a diligent hotel maid.
- Lesson 395 — Initialization of local vs global arraysLesson 412 — Printing a 2D matrix to the console
- overflow
- In programming, this "mess" is called data loss or overflow.
- Lesson 132 — Safe downcasting techniques
- overwrite
- If you then write a completely different program called goodbye.c and compile that without specifying a name, the compiler will create a new a.out and overwrite the old one.
- Lesson 60 — Understanding the `a.out` default
P
- p1
- When you write struct Player p1; inside a function, that memory is carved out of the "stack." The moment that function finishes, p1 is destroyed.
- Lesson 467 — Pointer comparison with `==` and `<`Lesson 498 — The 'Clockwise/Spiral' rule for declarationsLesson 609 — Creating a shorthand for struct namesLesson 620 — Allocating structs on the heap with malloc
- p1 < p2
- If pointer p1 points to the third house and p2 points to the fifth, p1 < p2 will be true because p1 points to an earlier memory location.
- Lesson 467 — Pointer comparison with `==` and `<`
- p2
- If pointer p1 points to the third house and p2 points to the fifth, p1 < p2 will be true because p1 points to an earlier memory location.
- Lesson 467 — Pointer comparison with `==` and `<`Lesson 498 — The 'Clockwise/Spiral' rule for declarations
- pacman -S mingw-w64-ucrt-x86_64-gcc
- Type this command: pacman -S mingw-w64-ucrt-x86_64-gcc and hit Enter.
- Lesson 11 — Setting up MinGW on Windows
- padding
- However, if the members have different alignment requirements, the compiler will insert invisible, empty bytes called padding to ensure every piece of data sits at a "natural" boundary.
- Lesson 575 — Manual padding in structuresLesson 638 — Understanding memory alignmentLesson 947 — Structure padding and alignment issues
- page fault
- A page fault occurs when your program tries to access an address that is in your virtual map but isn't currently sitting in physical RAM.
- Lesson 598 — Page faults and resident set size
- Page Number
- Virtual memory is divided into fixed-size pages (usually 4KB), and every address identifies a specific page number and a byte offset within that page.
- Lesson 597 — Virtual memory pages and offsets
- Pages
- Virtual memory is divided into fixed-size pages (usually 4KB), and every address identifies a specific page number and a byte offset within that page.
- Lesson 597 — Virtual memory pages and offsetsLesson 598 — Page faults and resident set size
- Pantry
- If you need "Salt" (a standard ingredient), you don't look in your own pockets; you go straight to the Pantry (the System Path).
- Lesson 795 — Standard header search paths
- paper
- When you write paper, the computer performs two distinct moves:
- Lesson 505 — Accessing data through double dereferenceLesson 1128 — Avoiding deadlocks
- Parameter
- Think of the Parameter as a parking spot and the Argument as the car.
- Lesson 335 — Parameters vs. Arguments
- parent
- This new process (the child) gets a copy of the original process's (the parent) variables, file descriptors, and code.
- Lesson 1075 — Process duplication and copy-on-write
- Parent Process
- This "creator" is known as the Parent Process, and its identification number is the PPID (Parent Process ID).
- Lesson 1069 — Parent processes and getppid()
- parent_id
- If you run this program in a standard terminal, parent_id will typically be the PID of your shell (like bash or zsh).
- Lesson 1069 — Parent processes and getppid()
- parent.child.member
- Nest structures to group related data hierarchically, using multiple dots (e.g., parent.child.member) to access the inner values.
- Lesson 623 — Defining a struct inside another struct
- Pareto Principle
- Performance profiling usually reveals the Pareto Principle: roughly 80% of your program's execution time is spent in only 20% of your code.
- Lesson 1183 — Identifying 'Hot Spots' in your code
- partitioning
- Quick Sort is a divide-and-conquer algorithm, but all the heavy lifting happens in a step called partitioning.
- Lesson 1056 — Quick Sort: Partitioning logic
- PascalCase
- Use a consistent naming style like PascalCase or a _t suffix for typedef names to clearly separate type definitions from variable names.
- Lesson 612 — Naming conventions for typedef types
- Pass by Value
- In C, this behavior is called Pass by Value.
- Lesson 343 — Why changing a parameter doesn't affect the caller
- password_protected
- It might overwrite the password_protected variable, changing 'N' to something else and accidentally "unlocking" the program.
- Lesson 1152 — Why `gets()` is strictly forbidden
- Path
- Click Environment Variables, find the Path variable under "System variables," and click Edit.
- Lesson 11 — Setting up MinGW on WindowsLesson 632 — Indexing into a struct array
- path.x[2]
- Remember: path.x[2] would imply that the variable x is an array.
- Lesson 632 — Indexing into a struct array
- path[0].x = 0; path[0].y = 0
- If you have a large array, this method is significantly cleaner than writing path[0].x = 0; path[0].y = 0; over and over.
- Lesson 631 — Initializing arrays of structs
- path[i]
- When you write path[i].x, C evaluates path[i] first, which results in a single struct Point.
- Lesson 632 — Indexing into a struct array
- path[i].x
- When you write path[i].x, C evaluates path[i] first, which results in a single struct Point.
- Lesson 632 — Indexing into a struct array
- pattern rules
- The power of these variables is most obvious when you use pattern rules.
- Lesson 822 — Automatic variables like `$@` and `$<`
- Pause
- The moment GDB attaches, it sends a signal to the program to pause.
- Lesson 831 — Continuing execution with `continue`Lesson 838 — Attaching GDB to a running process
- PAUSED
- At any given moment, the microwave is doing exactly one thing: it’s either IDLE, HEATING, or PAUSED.
- Lesson 668 — Using enums for state machines
- Peek
- The peek function returns the value of the top element without modifying the stack's pointer or removing any data.
- Lesson 1006 — Stack abstract data type conceptLesson 1011 — Implementing the Peek function
- PEMDAS
- In elementary school, you likely learned PEMDAS—the rule that says you must do multiplication before addition.
- Lesson 212 — Operator precedence table
- people
- In the code above, if C evaluated (cookies / people) when people was 0, the program would crash.
- Lesson 170 — Short-circuit evaluation of `&&`
- people == 0
- Because of short-circuiting, the program sees people == 0 is true, decides the whole if is true, and skips the dangerous math on the right side entirely.
- Lesson 254 — Short-circuit evaluation in logical OR
- people > 0
- Because of short-circuiting, the computer sees people > 0 is false, skips the division entirely, and moves straight to the else block.
- Lesson 170 — Short-circuit evaluation of `&&`
- perf
- Unlike simple timers that tell you how long a program took to run, perf looks at "hardware events." It watches the CPU as it executes your instructions and takes snapshots (samples) of what the program is doing thousands of times per second.
- Lesson 1186 — Using `perf` for hardware-level insights
- perf record
- perf record and perf report allow you to pinpoint the exact lines of code where your CPU is spending the most effort.
- Lesson 1186 — Using `perf` for hardware-level insights
- perf record ./my_program
- perf record ./my_program: This runs your code and records performance data into a file named perf.data.
- Lesson 1186 — Using `perf` for hardware-level insights
- perf report
- When you run perf report, you’ll see a list of functions sorted by "Overhead." If a function shows 80.00%, it means the CPU was busy inside that function 80% of the time.
- Lesson 1186 — Using `perf` for hardware-level insights
- perf.data
- perf record ./my_program: This runs your code and records performance data into a file named perf.data.
- Lesson 1186 — Using `perf` for hardware-level insights
- performance
- The primary advantage of an arena is performance.
- Lesson 591 — Trade-offs of arena vs malloc
- permanent lifetime
- A static variable has a limited scope (it can only be seen inside its function) but a permanent lifetime (it stays in memory for the entire duration of the program).
- Lesson 139 — Lifetime vs. Scope
- permanentCount
- In the example above, permanentCount remembers its value because it sits safely in the Data Segment.
- Lesson 149 — Memory segments: Stack vs. Data
- permission
- const is about permission (Can my code change this?), while volatile is about expectation (Can the outside world change this?).
- Lesson 917 — Combining `const` and `volatile`
- Permission Denied
- In C, this is exactly what happens when you encounter a Permission Denied error.
- Lesson 745 — Handling 'Permission Denied' errors
- perror
- Just remember to call perror immediately after the failure occurs, as other successful functions might reset the error code before you get a chance to read it.
- Lesson 741 — Using perror for descriptive errorsLesson 898 — Interpreting errors with `perror`
- perror("custom message")
- Use perror("custom message") to instantly translate system error codes into human-readable descriptions.
- Lesson 898 — Interpreting errors with `perror`
- perror()
- You can then use perror(), a handy function that prints a human-readable description of the last error that occurred.
- Lesson 745 — Handling 'Permission Denied' errors
- Person
- Imagine you have a Person struct that contains a pointer to a Job struct.
- Lesson 629 — Deep vs shallow copies of nested structsLesson 1035 — Hash table insertion
- Person2 = Person1
- If you perform a shallow copy (Person2 = Person1), C simply copies the memory address stored in the pointer.
- Lesson 629 — Deep vs shallow copies of nested structs
- photo[0][2]
- If you were to look at the memory addresses, you would see that photo[0][2] (the end of the first row) is sitting right next to photo[1][0] (the start of the second row).
- Lesson 408 — Memory layout: Row-major order
- photo[1][0]
- When you ask for photo[1][0], the computer calculates the location by saying: "I need to skip exactly one full row of three elements to get to the start of the second row."
- Lesson 408 — Memory layout: Row-major order
- photocopy
- You want your friend to perform a calculation with that number, so you hand them a photocopy of your paper.
- Lesson 339 — Local scope of parametersLesson 343 — Why changing a parameter doesn't affect the callerLesson 345 — Limitations of pass by value
- photos/vacation/beach.jpg
- This is incredibly useful when you need the last occurrence of something, such as finding the file extension in a full file path like photos/vacation/beach.jpg.
- Lesson 851 — Searching for characters with `strchr` and `strrchr`
- physical space
- sizeof tells you how much physical space the array occupies in memory.
- Lesson 847 — Finding string length with `strlen`
- physics_lib.so
- Instead, it leaves a "placeholder" or a note that says, "When this program starts, go find the code for calculate_physics() in physics_lib.so."
- Lesson 813 — What is a shared library `.so` / `.dll`
- physics.c
- If physics.c includes constants.h, and graphics.c includes constants.h, and then main.c includes both physics.h and graphics.h, the contents of constants.h will be pasted into your main file multiple times.
- Lesson 788 — The purpose of header filesLesson 789 — The 'duplicate definition' errorLesson 802 — Dependency graphing in your headLesson 806 — Linking multiple object filesLesson 817 — Why we need build tools
- physics.h
- If physics.c includes constants.h, and graphics.c includes constants.h, and then main.c includes both physics.h and graphics.h, the contents of constants.h will be pasted into your main file multiple times.
- Lesson 379 — Using `#include` with quotesLesson 789 — The 'duplicate definition' errorLesson 1203 — Header guard best practices
- PI
- However, using a constant like PI is better for two reasons:
- Lesson 764 — What the preprocessor actually doesLesson 768 — Defining constants with `#define`Lesson 863 — Trigonometric functions in radians
- pick one and stick to it
- While C traditionally favors snake_case, the most important rule is to pick one and stick to it throughout your entire project.
- Lesson 1197 — Meaningful variable naming conventions
- PID
- The unique ID of the process you want to talk to.
- Lesson 1067 — What is a process ID (PID)Lesson 1068 — Getting PID with getpid()Lesson 1074 — Handling fork() return valuesLesson 1086 — Sending signals with kill()
- pid_t
- When you call it, it reaches out to the system kernel and asks, "What is my ID?" It then returns a value of type pid_t, which is essentially a specialized integer used specifically for process IDs.
- Lesson 1068 — Getting PID with getpid()Lesson 1074 — Handling fork() return values
- Pilot
- If you define the Pilot struct first, the compiler will complain because it hasn't seen the Starship struct yet.
- Lesson 628 — Forward declarations of structs
- pipe
- In systems programming, a pipe is a unidirectional communication channel managed by the operating system kernel.
- Lesson 1100 — Anatomy of a pipeLesson 1101 — Creating pipes with pipe()Lesson 1102 — Unidirectional flow in pipes
- pipe()
- The pipe() function creates a pair of file descriptors—fd[0] for reading and fd[1] for writing—enabling a one-way flow of data between related processes.
- Lesson 1100 — Anatomy of a pipeLesson 1101 — Creating pipes with pipe()Lesson 1103 — Closing unused pipe endsLesson 1104 — Piping data between parent and childLesson 1106 — Introduction to named pipes (FIFOs)
- pipe(fd)
- When we create a pipe using pipe(fd), we get two file descriptors: fd[0] for reading and fd[1] for writing.
- Lesson 1105 — Redirecting stdout to a pipe
- pivot
- You pick one card—let’s say a 7—and call it the pivot.
- Lesson 1056 — Quick Sort: Partitioning logic
- plain text
- It is vital to understand that a source file must be plain text.
- Lesson 15 — The concept of a Source File
- platform
- Instead, the size is often determined by your platform—the combination of your computer’s hardware (CPU) and your operating system.
- Lesson 85 — Platform dependency of sizes
- platform-dependent
- In C, the size of a struct is platform-dependent.
- Lesson 644 — Platform dependency of struct size
- Play
- You want to hit Play and let the movie run normally until the next scene you care about.
- Lesson 831 — Continuing execution with `continue`
- Player
- In your personal life, your name might be "Robert," but in the context of a game, your "type" might be "Player." By using typedef, you are telling the compiler, "Every time I say Player, I really just mean int."
- Lesson 608 — Using typedef with primitive types
- player_age
- If you are setting the player_age and the gravity_constant, keep them on separate lines!
- Lesson 196 — Chained assignments `a = b = c`
- player_attribute_flags
- Using status |= mask instead of status = status | mask makes your code cleaner and reduces the chance of typos, especially when your variable names are long (like player_attribute_flags).
- Lesson 195 — Compound bitwise assignments
- player_experience_points
- When you use -=, you are explicitly saying "I am modifying this specific variable." In complex programs where variable names might be long (like player_experience_points), using -= prevents typos because you only have to write the name once.
- Lesson 193 — Compound subtraction `-=`
- PLAYER_H
- Since PLAYER_H was defined during the first pass, the check fails, and the preprocessor jumps straight to the #endif, effectively ignoring the rest of the file.
- Lesson 790 — Creating basic include guards
- player_health_points
- It eliminates the clutter of repeating the variable name, which reduces the chance of typos—especially when your variable names are long, like player_health_points.
- Lesson 192 — Compound addition `+=`
- player->health
- Because the user’s code only sees the header, they can’t access the struct members directly (e.g., player->health would cause a compiler error).
- Lesson 673 — Opaque types with header files
- player.c
- If global_score is defined in game.h, and both player.c and enemy.c include it, they both end up trying to create their own version of that variable.
- Lesson 146 — The `extern` keyword for multi-file codeLesson 797 — The `extern` keyword for variablesLesson 925 — Common linkage errors and 'multiple definition'
- player.h
- If you accidentally include it twice—perhaps because main.c includes player.h and also includes game.h, which itself includes player.h—the compiler sees the same code twice in a row.
- Lesson 789 — The 'duplicate definition' errorLesson 790 — Creating basic include guardsLesson 791 — How `#pragma once` worksLesson 792 — Forward declarations in headersLesson 1203 — Header guard best practices
- player.o
- Because of $@ and $<, this single rule works for logger.o, math_utils.o, or player.o without you ever having to type those names manually.
- Lesson 822 — Automatic variables like `$@` and `$<`
- player.pos.x
- player.x is easier to read than player.pos.x.
- Lesson 671 — Anonymous unions inside structs
- player.position.coords.x
- Previously, if you nested a struct inside another, you had to give it a name, leading to long, clunky access chains like player.position.coords.x.
- Lesson 967 — C11: Multi-threading and Anonymous structures
- player1
- Start with a letter: You can use numbers inside the name, but never at the start (e.g., player1 is fine, but 1player will cause an error).
- Lesson 75 — The syntax of a declarationLesson 604 — Copying structs with the assignment operatorLesson 630 — Declaring an array of structs
- Player1 500
- But what if your file is a list of high scores, like Player1 500?
- Lesson 719 — Formatted file input with fscanf
- player1_score
- Imagine you are building a game and need to create several variables like player1_score, player2_score, and player3_score.
- Lesson 777 — The token-pasting operator `##`
- player2
- Declaring individual variables like player1, player2, and player3 becomes messy very quickly.
- Lesson 604 — Copying structs with the assignment operatorLesson 630 — Declaring an array of structs
- player2_score
- Imagine you are building a game and need to create several variables like player1_score, player2_score, and player3_score.
- Lesson 777 — The token-pasting operator `##`
- player3
- Declaring individual variables like player1, player2, and player3 becomes messy very quickly.
- Lesson 630 — Declaring an array of structs
- player3_score
- Imagine you are building a game and need to create several variables like player1_score, player2_score, and player3_score.
- Lesson 777 — The token-pasting operator `##`
- playerInventorySpaceRemaining
- Readability: When variables have long names, like playerInventorySpaceRemaining, repeating the name on both sides of the equals sign makes the line cluttered.
- Lesson 194 — Compound multiplication and division
- players
- In the example above, printf sees the %d first, so it grabs players.
- Lesson 54 — Multiple specifiers in one line
- playerScore
- When you tell C to look at playerScore, the computer automatically goes to the correct "locker," opens it, and reads the value inside.
- Lesson 73 — What is a variable?Lesson 75 — The syntax of a declaration
- playerScored
- It simply looks at what is currently inside playerScored (which is 10), makes a copy of it, and drops that copy into totalPoints.
- Lesson 78 — Assigning values with `=`
- PLY_
- By adopting this habit early, you ensure that your "Module A" can never accidentally overwrite a function in "Module B." It also makes your code searchable; if you want to find every function related to the player, you simply search your project for PLY_.
- Lesson 801 — Naming conventions for large projects
- Point
- If your Point struct grows later to include a z coordinate, the nested braces ensure your radius doesn't accidentally get assigned to the wrong field.
- Lesson 609 — Creating a shorthand for struct namesLesson 614 — Improving code readability with typedefLesson 625 — Initializing nested structures
- Point p
- Point p; is much easier to scan visually than struct Point p;.
- Lesson 614 — Improving code readability with typedef
- pointer
- Unlike a manual loop that usually returns an index (like i), bsearch returns a pointer to the element inside the array.
- Lesson 203 — Incrementing pointers (preview)Lesson 239 — Member access `.` and `->`Lesson 427 — Searching for characters with `strchr`Lesson 428 — Searching for substrings with `strstr`Lesson 455 — Declaring pointer variables with `*`Lesson 496 — When to use `const` with pointersLesson 532 — Introduction to the Heap segmentLesson 557 — What is a dangling pointerLesson 617 — Arrow operator vs dot operatorLesson 851 — Searching for characters with `strchr` and `strrchr`Lesson 852 — Finding substrings with `strstr`Lesson 929 — Returning pointers to functions from functionsLesson 1066 — Using C library 'bsearch' function
- pointer arithmetic
- Under the hood, when you write scores[1], C performs pointer arithmetic.
- Lesson 986 — Accessing elements by index
- pointer to a character type
- If you truly need to look at the raw bits of a variable (for example, to send them over a network), the only safe way is to use a pointer to a character type (char or unsigned char) or the memcpy function.
- Lesson 527 — Pointer type-punning dangers
- pointer to a constant
- In C, a pointer to a constant works exactly like that glass.
- Lesson 493 — Pointer to a constant (`const int *p`)
- pointer to a pointer
- A pointer to a pointer (declared as int ptr) is like a locked box that contains a second treasure map.
- Lesson 502 — Visualizing pointer chainsLesson 504 — Dynamic 2D array structures
- pointer to a struct
- In C, a pointer to a struct is that sticky note.
- Lesson 615 — Declaring a pointer to a struct
- pointer to an array
- A pointer to an array is a single pointer variable that points to a whole block of memory formatted as an array.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- pointer to an integer
- If you wrote int *ptr(int, int);, C would think you are declaring a normal function named ptr that returns a pointer to an integer.
- Lesson 514 — Syntax of function pointers
- pointer to the postcard itself
- To let a function change the address on your original postcard, you must give the function a pointer to the postcard itself.
- Lesson 503 — Modifying a pointer inside a function
- pointerB = pointerA
- When you set pointerB = pointerA, you aren't making a copy of the data (secretCode).
- Lesson 460 — Multiple pointers to the same address
- Pointers
- Understanding that functions currently only work with copies is the essential first step toward mastering pointers, which act as those maps.
- Lesson 237 — The Address-of operator `&`Lesson 346 — Preparing for pass by referenceLesson 616 — The arrow operator `->` syntaxLesson 912 — Using `const` in function parametersLesson 1033 — Handling collisions with Chaining
- pointers to those elements
- When qsort compares two elements, it passes pointers to those elements to your comparison function.
- Lesson 878 — Writing a string comparison function for `qsort`
- points
- In the code above, points and Points coexist as two separate variables.
- Lesson 23 — Case sensitivity in C
- points2
- For example, points2 is fine, but 2points is illegal.
- Lesson 74 — Naming rules and identifiers
- Pool
- Instead of asking the "General Store" for a new tiny box every time a bullet is fired, you can buy one giant crate of memory (a Pool) at the start.
- Lesson 578 — Motivation for custom allocators
- pop
- A Stack Underflow occurs when your code calls a pop operation (removing the top item) on a stack that contains no data.
- Lesson 948 — The `#pragma pack` directiveLesson 1006 — Stack abstract data type conceptLesson 1010 — The Pop operationLesson 1011 — Implementing the Peek functionLesson 1013 — Handling Stack Underflow
- Pop calculate
- Pop calculate: calculate uses that value, finishes, and its frame is deleted.
- Lesson 348 — Pushing and popping frames
- POPCNT
- Modern CPUs, however, have a single instruction called POPCNT (population count) that does this instantly.
- Lesson 964 — Compiler intrinsics as an alternative
- Portability
- Environment variables are the gold standard for portability.
- Lesson 948 — The `#pragma pack` directiveLesson 1071 — Environment variables in C
- position
- Even if the data types are the same (both integers), the position determines which value represents the width and which represents the height.
- Lesson 337 — Positional matching of arguments
- positive
- A positive number if the first item comes after the second.
- Lesson 1059 — Using C library 'qsort' function
- Positive Integer
- The Parent: Receives a Positive Integer (the Process ID of the child).
- Lesson 1074 — Handling fork() return values
- Post
- For example, a User struct might need to know about a Post struct, and the Post needs to know who the User is.
- Lesson 794 — Circular dependency issues
- post-it note
- To fix this, we don't put the box inside the box; we put a post-it note inside the box.
- Lesson 627 — Limitations of self-referential definitions
- Post-order
- In Post-order traversal, you visit the Left subtree, then the Right subtree, and finally the Root (L-R-Root).
- Lesson 1026 — Pre-order and Post-order traversal
- post-test
- In programming, we call this post-test logic.
- Lesson 275 — Guaranteed execution: why do-while is different
- post.h
- When the compiler looks at user.h, it tries to resolve post.h first.
- Lesson 794 — Circular dependency issues
- postfix
- Use postfix (i++) only when your logic strictly requires the original value before the increase.
- Lesson 205 — Performance: Prefix vs Postfix
- Postfix (i++)
- Postfix (i++) is like being handed a copy of your old unpaid bill, paying it, and then the shop updates their records later.
- Lesson 205 — Performance: Prefix vs Postfix
- pow()
- A crucial detail to remember is that pow() works with doubles (floating-point numbers).
- Lesson 861 — Basic power and square root: `pow` and `sqrt`
- power of 2
- In binary, each position represents a power of 2, starting from the right.
- Lesson 179 — Understanding binary representation
- PPID
- This "creator" is known as the Parent Process, and its identification number is the PPID (Parent Process ID).
- Lesson 1069 — Parent processes and getppid()
- Pre-order
- Use Pre-order (Root-L-R) to copy or clone a tree, and Post-order (L-R-Root) to safely delete or free a tree.
- Lesson 1026 — Pre-order and Post-order traversal
- precedence
- In previous lessons, we learned about precedence, which is like the "order of operations" in math (multiplication happens before addition).
- Lesson 213 — Left-to-right associativityLesson 215 — Parentheses for clarityLesson 217 — Precedence of assignmentLesson 219 — Common precedence errorsLesson 227 — Order of evaluation vs Precedence
- prefix
- However, it is a "best practice" to default to prefix (++i) unless you specifically need the old value.
- Lesson 205 — Performance: Prefix vs Postfix
- Prefix (++i)
- Prefix (++i) is like paying for your coffee, getting your receipt, and then walking away.
- Lesson 205 — Performance: Prefix vs Postfix
- prefix decrement
- When you place them before the variable name (like --x), it is called a prefix decrement.
- Lesson 200 — Prefix decrement `--x`
- prefix increment
- When you place this operator before the variable name (like ++x), it is called a prefix increment.
- Lesson 198 — Prefix increment `++x`
- prefixes
- If there is only one person named John, you just call him "John." If the town grows and three more Johns move in, you have to start calling them "Baker John," "Fisher John," and "Smith John." In C, we do this using prefixes.
- Lesson 801 — Naming conventions for large projects
- Prefixing
- Since C won't provide the "bedrooms" for us, programmers have developed a convention to stay organized: Prefixing.
- Lesson 666 — Scoped enum limitations in C
- PREMIUM
- Here is a program that behaves differently depending on whether a PREMIUM flag is set during the build:
- Lesson 786 — Feature toggles via command line `-D`
- Preprocessor
- It is an instruction for the preprocessor—a program that processes your code before it is actually compiled.
- Lesson 25 — Phase 1: The PreprocessorLesson 115 — Defining constants with `#define`Lesson 764 — What the preprocessor actually doesLesson 765 — The `#include` directive for standard headersLesson 770 — The danger of semicolon in `#define`
- preprocessor directive
- This is because it is a preprocessor directive, not a standard C statement.
- Lesson 765 — The `#include` directive for standard headers
- preprocessor macros
- To write professional, low-level C, you use preprocessor macros.
- Lesson 963 — Platform-specific assembly (x86 vs ARM)
- prev
- A doubly linked list changes this by giving every node two "hands": one reaching for the next node and one reaching for the prev (previous) node.
- Lesson 996 — Deleting a node by valueLesson 998 — The 'prev' pointer conceptLesson 999 — Updating the node structLesson 1000 — Handling the tail pointerLesson 1001 — Bidirectional traversalLesson 1003 — Deleting without head traversalLesson 1004 — Circular doubly linked listsLesson 1005 — Common pointer update pitfalls
- prev_node
- When you insert a new node (new_node) between two existing nodes (prev_node and next_node), you must update four pointers to maintain the integrity of the chain.
- Lesson 995 — Inserting after a specific nodeLesson 1002 — Inserting in a doubly linked list
- prev_node->next
- If you update prev_node->next before you've saved its value into new_node->next, you lose your connection to the rest of the list—it’s like dropping the hand of the person behind you before the new person has grabbed it.
- Lesson 995 — Inserting after a specific nodeLesson 1002 — Inserting in a doubly linked list
- price
- By looking at the output, you can confirm if price was actually 100 or if it somehow changed to 0 earlier in the code.
- Lesson 72 — Debugging by printingLesson 447 — Memory as a linear sequence of bytesLesson 622 — The importance of NULL checks for struct pointers
- price = 10
- Imagine you are sitting at a desk with a sticky note that says price = 10.
- Lesson 138 — Shadowing: Nested scope name clashes
- price = 5
- Inside that box, you put a new sticky note that also says price = 5.
- Lesson 138 — Shadowing: Nested scope name clashes
- price = items * 1.0825
- But if you write price = items * 1.0825, someone reading your code later (including future you) will have no idea that 1.0825 represents the local sales tax rate for a specific city.
- Lesson 771 — Avoiding magic numbers with macros
- pricePerCookie
- Even though cookies started as a whole number, C recognized that the pricePerCookie held more precise information (decimals).
- Lesson 126 — The 'Usual Arithmetic Conversions'
- prices
- By understanding that prices is just a pointer to prices[0], you unlock the ability to navigate through memory quickly and efficiently.
- Lesson 471 — Array names as constant pointers
- prices[0]
- By understanding that prices is just a pointer to prices[0], you unlock the ability to navigate through memory quickly and efficiently.
- Lesson 471 — Array names as constant pointers
- prices[1]
- You might wonder why we would use *(prices + 1) when prices[1] is easier to read.
- Lesson 472 — Accessing arrays with pointer notation
- primeNumbers[0]
- In this example, primeNumbers[0] becomes 2, primeNumbers[1] becomes 3, and so on.
- Lesson 391 — Initialization with curly braces `{}`
- primeNumbers[1]
- In this example, primeNumbers[0] becomes 2, primeNumbers[1] becomes 3, and so on.
- Lesson 391 — Initialization with curly braces `{}`
- The print command asks the manager what’s inside a locker; the x command lets you walk up to the locker and stare through the mesh wire yourself.
- Lesson 1 — What is a low-level language?Lesson 6 — C as a compiled languageLesson 832 — Checking variable values with `print`Lesson 839 — Examining raw memory with `x`Lesson 977 — Type-based function overloading simulation
- print items - i
- You can even print complex expressions, like print items - i, and GDB will do the math for you based on the current state of the program.
- Lesson 832 — Checking variable values with `print`
- print ptr
- Even though the program is dead, you can type print ptr to see its value at the moment of impact.
- Lesson 837 — Debugging a Segfault from a core dump
- print secret_key
- If you are paused inside process_data, typing print secret_key will result in an error because that variable doesn't exist in the current frame.
- Lesson 834 — Moving between frames with `up` and `down`
- print secret_number
- If you compile the code above with gcc -g, and then open it in GDB, you can type list to see your actual C code or print secret_number to see its value.
- Lesson 825 — Compiling with debug symbols `-g`
- print_float(float x)
- You usually end up writing print_int(int x) and print_float(float x).
- Lesson 977 — Type-based function overloading simulation
- print_int
- It then looks at the _Generic list, finds the int: label, and replaces the macro with the print_int function.
- Lesson 977 — Type-based function overloading simulation
- PRINT_INT(10 + 5)
- If you pass PRINT_INT(10 + 5), the #x will literally become the string "10 + 5".
- Lesson 776 — The stringizing operator `#`
- print_int(int x)
- You usually end up writing print_int(int x) and print_float(float x).
- Lesson 977 — Type-based function overloading simulation
- print_total
- When print_total is called, the computer needs to remember to come back to the "Program continues..." line later.
- Lesson 350 — Return addresses in memory
- print_type(score)
- When the compiler sees print_type(score), it notices score is an int.
- Lesson 973 — Introduction to the `_Generic` keyword
- print_val
- If the print_val macro above wasn't written to handle your custom struct, you cannot use it.
- Lesson 978 — Comparing `_Generic` to C++ templates
- print_value
- Let’s say we want a single name, print_value, that works for both integers and strings.
- Lesson 974 — The syntax of a generic selection
- print()
- We can combine _Generic with a macro to create a universal print() function.
- Lesson 975 — Implementing a generic 'Print' macro
- print(age)
- When the compiler sees print(age), it checks the type of age.
- Lesson 975 — Implementing a generic 'Print' macro
- printf
- It tells the preprocessor: "If you reach this line, stop everything, display a specific message, and fail the build." Unlike a standard printf which happens while your program is running, #error happens while your program is being created.
- Lesson 17 — The 'Hello World' codeLesson 18 — The `#include` directiveLesson 19 — What is a Header File?Lesson 27 — Phase 3: Assembly to Object CodeLesson 28 — Phase 4: The LinkerLesson 30 — Creating an executable binaryLesson 41 — The `stdio.h` libraryLesson 42 — Basic `printf` syntaxLesson 43 — Printing literal stringsLesson 44 — Newline character `\n`Lesson 45 — Horizontal tab `\t`Lesson 46 — Escaping double quotesLesson 47 — Escaping the backslashLesson 49 — Introduction to Format SpecifiersLesson 50 — Printing integers with `%d`Lesson 51 — Printing characters with `%c`Lesson 52 — Printing decimals with `%f`Lesson 53 — The `%s` specifier for stringsLesson 54 — Multiple specifiers in one lineLesson 55 — Argument-specifier matchingLesson 56 — Basic field width formattingLesson 64 — Library linking basicsLesson 65 — Syntax errors vs Logic errorsLesson 66 — Reading compiler error messagesLesson 68 — Warnings vs Fatal errorsLesson 72 — Debugging by printingLesson 82 — Short vs. Long integersLesson 83 — The `long long` typeLesson 94 — Format specifiers for unsigned intsLesson 97 — Single precision `float`Lesson 98 — Double precision `double`Lesson 99 — The `long double` typeLesson 108 — Escape sequences like `\n` and `\t`Lesson 112 — Printing chars with `%c`Lesson 199 — Postfix increment `x++`Lesson 200 — Prefix decrement `--x`Lesson 201 — Postfix decrement `x--`Lesson 202 — Differences in expression resultsLesson 207 — Ternary as an expressionLesson 222 — Sequence points at `;`Lesson 237 — The Address-of operator `&`Lesson 243 — Truthiness: 0 is false, non-zero is trueLesson 263 — Grouping multiple cases into one blockLesson 274 — The do-while syntax and the trailing semicolonLesson 292 — Continue in while vs for loopsLesson 298 — Introduction to loops inside loopsLesson 325 — Writing your first custom functionLesson 372 — The `stdarg.h` libraryLesson 376 — How `printf` works internallyLesson 417 — The Null Terminator `\0` character
- printf("\n")
- Crucially, the printf("\n") sits outside the inner loop but inside the outer loop.
- Lesson 300 — Using nested loops to print 2D gridsLesson 412 — Printing a 2D matrix to the console
- printf("5 + 5")
- If you type printf("5 + 5");, the screen won't show 10; it will show the literal characters 5 + 5.
- Lesson 43 — Printing literal strings
- printf("Battery: 85%")
- If you type printf("Battery: 85%");, the compiler gets confused.
- Lesson 690 — Escaping the percent sign %%
- printf("C:\Windows")
- If you type printf("C:\Windows");, C will see the \W and wonder what secret command you are trying to trigger.
- Lesson 47 — Escaping the backslash
- printf("Hello")
- When you type printf("Hello"), the first quote tells the compiler, "A message is starting," and the second one says, "The message is over."
- Lesson 42 — Basic `printf` syntaxLesson 46 — Escaping double quotes
- printf("Here\n")
- When your code crashes or gives the wrong answer, it’s tempting to sprinkle printf("Here\n"); everywhere.
- Lesson 1157 — Strategic `printf()` debugging
- printf("My age is age")
- If you type printf("My age is age");, the computer will literally print the word "age." To fix this, we use a special placeholder called a format specifier.
- Lesson 50 — Printing integers with `%d`
- printf("Reached point A\n")
- If your program crashes halfway through, you can place "breadcrumbs" (like printf("Reached point A\n");) to find the exact line where it dies.
- Lesson 72 — Debugging by printing
- printf("Your text here")
- Use printf("Your text here"); to send a message to the screen, always remembering to wrap your text in double quotes and end the line with a semicolon.
- Lesson 42 — Basic `printf` syntax
- printf()
- In C programming, the printf() function treats the percent sign (%) as a special "warning flag." When the computer sees a %, it stops reading the text literally and starts looking for a format specifier, like %d for integers or %f for decimals.
- Lesson 43 — Printing literal stringsLesson 48 — The percent sign `%%` literalLesson 50 — Printing integers with `%d`Lesson 87 — Printing integers with `%d` and `%ld`Lesson 371 — Functions with unknown argumentsLesson 372 — The `stdarg.h` libraryLesson 684 — Format specifiers recapLesson 687 — Precision for floating-point numbersLesson 689 — Printing hex and octal valuesLesson 748 — How C buffers I/O for speedLesson 755 — When to use fflush(stdout)Lesson 830 — Stepping through code with `next` and `step`Lesson 1089 — Signal safety and reentrant functionsLesson 1093 — Standard streams (0, 1, 2)Lesson 1105 — Redirecting stdout to a pipeLesson 1157 — Strategic `printf()` debuggingLesson 1158 — Flushing `stdout` for accurate logsLesson 1163 — Inspecting variable values at runtimeLesson 1175 — Separating logic from `main()` for testability
- printf(Hello)
- In C, if you type printf(Hello), the computer looks for a command or a variable named Hello.
- Lesson 42 — Basic `printf` syntax
- printHello
- Like variable names, these should be descriptive verbs, like calculateTax or printHello.
- Lesson 323 — Anatomy of a function definition
- printString(const char *s)
- When you write a function like printString(const char *s), you are promising other programmers (and yourself) that the function will only read the string, not destroy it.
- Lesson 496 — When to use `const` with pointers
- prntf
- Misspelling a keyword (like writing prntf instead of printf).
- Lesson 68 — Warnings vs Fatal errors
- procedural
- Think of the ternary operator as a functional tool and if-else as a procedural tool.
- Lesson 210 — Ternary vs If-Else for assignments
- Process
- When you run a C program, the operating system loads it into memory and turns it into a process.
- Lesson 31 — How the OS runs a programLesson 315 — The Flag Variable patternLesson 1067 — What is a process ID (PID)Lesson 1068 — Getting PID with getpid()Lesson 1116 — Threads vs Processes
- Process ID
- To manage hundreds of processes simultaneously—like your web browser, your music player, and your code—the OS assigns each one a unique identification number called a Process ID, or PID for short.
- Lesson 1067 — What is a process ID (PID)Lesson 1068 — Getting PID with getpid()
- Process ID (PID)
- Every running program on your computer is assigned a unique number called a Process ID (PID).
- Lesson 838 — Attaching GDB to a running process
- Process the data again
- Process the data again. You have now duplicated your last entry.
- Lesson 722 — Why feof inside a loop condition is bad
- process_age(-5)
- When process_age(-5) runs, the program stops and tells you exactly which file and which line failed.
- Lesson 901 — Using `assert` for internal debugging
- process_data
- If you are paused inside process_data, typing print secret_key will result in an error because that variable doesn't exist in the current frame.
- Lesson 833 — Inspecting the call stack with `backtrace`Lesson 834 — Moving between frames with `up` and `down`
- process_data_v2()
- When you work on large-scale projects, you won't remember why you created process_data_v2() six months ago.
- Lesson 1199 — Writing effective Doxygen comments
- processor ticks
- This isn't a measurement of seconds; it’s a count of processor ticks.
- Lesson 896 — Measuring CPU ticks with `clock`
- profiler
- In programming, a profiler is your kitchen stopwatch.
- Lesson 1182 — Introduction to the `gprof` profiler
- profilers
- In C, we use tools called profilers (like gprof or Valgrind's Callgrind) to identify these spots.
- Lesson 1183 — Identifying 'Hot Spots' in your code
- program break
- When you start your program, the fence is set at a specific location called the program break.
- Lesson 592 — Introduction to brk and sbrk
- program.exe
- When you compiled your code, you likely created a file named a.out (the default name on Linux and macOS) or program.exe (on Windows).
- Lesson 28 — Phase 4: The LinkerLesson 31 — How the OS runs a programLesson 32 — Executing from the command line
- Project-Path-Name
- To prevent this, follow the Project-Path-Name pattern.
- Lesson 1203 — Header guard best practices
- PROT_EXEC
- For example, when your program loads a shared library, the actual machine code instructions are mapped as PROT_READ (and PROT_EXEC).
- Lesson 595 — Memory protection constants (PROT_READ)
- PROT_READ
- For example, when your program loads a shared library, the actual machine code instructions are mapped as PROT_READ (and PROT_EXEC).
- Lesson 595 — Memory protection constants (PROT_READ)
- protection constants
- This is done through protection constants.
- Lesson 595 — Memory protection constants (PROT_READ)
- prototype
- In C, a prototype is like a movie trailer—it tells the compiler the title, the stars (parameters), and the genre (return type) before the full feature begins.
- Lesson 330 — Function prototype syntaxLesson 332 — Matching prototypes with definitionsLesson 334 — Common errors with missing prototypes
- pthread
- Using the pthread library, you can spawn a "worker" thread to handle a specific task in another lane while your main program keeps moving.
- Lesson 1117 — Creating threads with pthread_createLesson 1118 — Passing arguments to threadsLesson 1126 — Locking and unlocking mutexesLesson 1130 — Recursive mutexesLesson 1136 — The producer-consumer problem
- pthread_barrier_t
- In POSIX threads (pthreads), we use pthread_barrier_t.
- Lesson 1137 — Thread barriers
- pthread_barrier_wait()
- When a thread reaches the checkpoint, it calls pthread_barrier_wait().
- Lesson 1137 — Thread barriers
- pthread_cond_broadcast
- You use pthread_cond_broadcast when a state change in your program might be relevant to every single thread currently waiting.
- Lesson 1135 — Broadcasting to all threads
- pthread_cond_signal
- The Mutex Matters: You should generally hold the mutex when calling pthread_cond_signal to ensure the "signaler" and the "waiter" don't have a race condition regarding the state change.
- Lesson 1132 — Introduction to condition variablesLesson 1134 — Signaling with pthread_cond_signalLesson 1135 — Broadcasting to all threads
- pthread_cond_wait
- In previous lessons, we learned that pthread_cond_wait puts a thread to sleep while it waits for a specific condition (like a queue filling up).
- Lesson 1132 — Introduction to condition variablesLesson 1133 — Waiting with pthread_cond_waitLesson 1134 — Signaling with pthread_cond_signalLesson 1135 — Broadcasting to all threads
- pthread_create
- Because pthread_create only accepts one argument, if you need to pass multiple pieces of information (like a username and a user ID), you should wrap them in a struct.
- Lesson 1117 — Creating threads with pthread_createLesson 1118 — Passing arguments to threadsLesson 1119 — Waiting for threads with pthread_joinLesson 1120 — Returning values from threadsLesson 1121 — Detaching threads
- pthread_detach
- The main reason to use pthread_detach is to prevent resource leaks.
- Lesson 1121 — Detaching threads
- pthread_detach(thread_id)
- You can detach a thread using pthread_detach(thread_id).
- Lesson 1121 — Detaching threads
- pthread_exit()
- Use pthread_exit() when you have complex logic where a thread needs to stop deep inside a nested function, or when you want the main thread to finish its own work but allow background threads to keep processing in the background.
- Lesson 1123 — The pthread_exit function
- pthread_join
- pthread_join pauses the current thread until the specified thread terminates, ensuring the program doesn't exit prematurely and cleaning up thread resources.
- Lesson 1119 — Waiting for threads with pthread_joinLesson 1120 — Returning values from threadsLesson 1121 — Detaching threads
- pthread_join()
- The pthread_join() function acts as a synchronization point.
- Lesson 1119 — Waiting for threads with pthread_join
- pthread_mutex_destroy()
- Always call pthread_mutex_destroy() on an unlocked mutex when it is no longer needed to free up system resources.
- Lesson 1131 — Cleaning up mutex resources
- pthread_mutex_init
- When you initialize one using pthread_mutex_init, the operating system sets aside a small amount of memory and potentially some kernel-level handles.
- Lesson 1131 — Cleaning up mutex resources
- pthread_mutex_init()
- Before a mutex can protect shared data, it must be initialized using either PTHREAD_MUTEX_INITIALIZER for globals or pthread_mutex_init() for local variables.
- Lesson 1125 — Initializing a pthread_mutex_t
- PTHREAD_MUTEX_INITIALIZER
- Before a mutex can protect shared data, it must be initialized using either PTHREAD_MUTEX_INITIALIZER for globals or pthread_mutex_init() for local variables.
- Lesson 1125 — Initializing a pthread_mutex_t
- pthread_mutex_lock
- Normally, when you call pthread_mutex_lock, your thread is like a person standing in line for a single-occupancy bathroom.
- Lesson 1126 — Locking and unlocking mutexesLesson 1127 — Critical section best practicesLesson 1129 — Using pthread_mutex_trylockLesson 1146 — Lock-free programming concepts
- pthread_mutex_lock()
- pthread_mutex_lock(): The thread attempts to grab the key.
- Lesson 1126 — Locking and unlocking mutexes
- pthread_mutex_t
- If you try to lock a pthread_mutex_t that hasn't been initialized, your program will likely crash or exhibit "undefined behavior." Think of it like trying to turn a key in a lock that hasn't been installed in a door yet; the mechanism simply isn't there to catch the bolt.
- Lesson 1125 — Initializing a pthread_mutex_tLesson 1138 — Read-write locks basics
- pthread_mutex_trylock
- Think of pthread_mutex_trylock as walking up to the door, giving the handle a quick turn, and—if it doesn't open immediately—walking away to do something else rather than standing in the hallway.
- Lesson 1129 — Using pthread_mutex_trylock
- pthread_mutex_unlock
- Use pthread_mutex_lock before accessing shared data and pthread_mutex_unlock immediately after to ensure thread safety.
- Lesson 1126 — Locking and unlocking mutexes
- pthread_mutex_unlock()
- pthread_mutex_unlock(): The thread puts the key back, waking up any other threads that are waiting for it.
- Lesson 1126 — Locking and unlocking mutexes
- pthread_rwlock_t
- A Read-Write Lock (pthread_rwlock_t) distinguishes between reading and writing.
- Lesson 1138 — Read-write locks basics
- pthread_t
- The ID: A variable of type pthread_t to act as the thread's "name tag."
- Lesson 1117 — Creating threads with pthread_create
- pthreads
- Because pthreads is designed to be flexible, it communicates using void * (a generic pointer).
- Lesson 1120 — Returning values from threadsLesson 1137 — Thread barriers
- ptr
- The parentheses force C to treat ptr as a pointer first.
- Lesson 238 — The Indirection operator `*`Lesson 239 — Member access `.` and `->`Lesson 457 — The Dereference operator `*`Lesson 493 — Pointer to a constant (`const int *p`)Lesson 503 — Modifying a pointer inside a functionLesson 514 — Syntax of function pointersLesson 554 — Double-freeing a pointerLesson 555 — Invalid pointer increments before freeLesson 558 — Returning addresses of local variablesLesson 559 — Setting pointers to NULL after freeLesson 596 — The munmap functionLesson 615 — Declaring a pointer to a structLesson 859 — Searching memory bytes with `memchr`Lesson 928 — Declaring pointers to functions
- ptr != NULL
- By checking ptr != NULL, you ensure that the *ptr operation only happens when there is a valid destination to visit.
- Lesson 462 — Checking for NULL before dereferencing
- ptr + (2 * 4 bytes)
- When you work with an int pointer, C treats ptr + 2 as ptr + (2 * 4 bytes).
- Lesson 468 — Scaling factor in pointer math
- ptr + 1
- If you have an integer pointer and you write ptr + 1, C knows that to get to the next integer, it must skip over 4 bytes.
- Lesson 468 — Scaling factor in pointer math
- ptr + 2
- When you work with an int pointer, C treats ptr + 2 as ptr + (2 * 4 bytes).
- Lesson 468 — Scaling factor in pointer math
- ptr + n
- By using ptr++ or ptr + n, you are manually steering through memory.
- Lesson 465 — How data types affect step sizeLesson 470 — Navigating memory blocks manually
- ptr = NULL
- Always follow free(ptr); with ptr = NULL; to ensure you don't accidentally use an address that no longer belongs to you.
- Lesson 559 — Setting pointers to NULL after free
- ptr = numbers
- In the example above, ptr = numbers is perfectly valid.
- Lesson 475 — Array decay explained
- ptr_array
- Here, ptr_array is an array of 5 elements.
- Lesson 927 — Arrays of pointers vs Pointers to arrays
- ptr_as_int
- This often fails because the compiler doesn't expect ptr_as_int to affect my_float.
- Lesson 527 — Pointer type-punning dangers
- ptr->member
- Use ptr->member as a readable shortcut for (*ptr).member when working with pointers to structures.
- Lesson 616 — The arrow operator `->` syntax
- ptr.age
- In C, if you have a pointer ptr, you can’t just say ptr.age because a memory address doesn’t have an age—the folder sitting at that address does.
- Lesson 239 — Member access `.` and `->`
- ptr.speed
- The parentheses are mandatory because, without them, C would try to look for a pointer named ptr.speed, which doesn't exist.
- Lesson 616 — The arrow operator `->` syntax
- ptr[i]
- If you use ptr[i], the base address of ptr stays exactly where it belongs.
- Lesson 555 — Invalid pointer increments before free
- ptr++
- Incrementing a pointer (ptr++) automatically shifts the memory address forward by the size of one data type, allowing you to traverse an array step-by-step.
- Lesson 203 — Incrementing pointers (preview)Lesson 463 — Incrementing pointers with `++`Lesson 465 — How data types affect step sizeLesson 470 — Navigating memory blocks manuallyLesson 477 — Iterating arrays using pointer incrementsLesson 481 — Iterating strings until `\0` with pointers
- ptr1
- It can’t optimize or reorder instructions because it fears that changing data through ptr1 might unexpectedly change the data being read by ptr2.
- Lesson 915 — The `restrict` pointer qualifier
- ptr1 + ptr2
- In C, adding two pointers (like ptr1 + ptr2) is illegal.
- Lesson 469 — Illegal pointer arithmetic operations
- ptr2
- It can’t optimize or reorder instructions because it fears that changing data through ptr1 might unexpectedly change the data being read by ptr2.
- Lesson 915 — The `restrict` pointer qualifier
- ptrdiff_t
- The Result Type: The result of this operation is an integer type called ptrdiff_t.
- Lesson 466 — Subtracting two pointers
- ptrToPtr
- The actual integer value at the final destination (the second hop).
- Lesson 500 — Concept of double indirection
- PUSH
- push, 1: The push command saves your current alignment settings, and 1 tells the compiler to pack members as tightly as possible (no gaps larger than 1 byte).
- Lesson 27 — Phase 3: Assembly to Object CodeLesson 948 — The `#pragma pack` directiveLesson 1006 — Stack abstract data type conceptLesson 1009 — The Push operationLesson 1011 — Implementing the Peek functionLesson 1012 — Handling Stack Overflow
- putchar
- If you are building a system where every byte of memory counts, or if you are writing a loop that processes text one letter at a time (like an animation or a custom text filter), putchar is your best friend.
- Lesson 679 — Basic character output with putchar
- putchar('x')
- Use putchar('x'); to output one single character to the console quickly and efficiently.
- Lesson 679 — Basic character output with putchar
- putchar()
- However, when we perform input/output (I/O) using functions like getchar() or putchar(), you will notice something strange: these functions often deal with int instead of char.
- Lesson 683 — Relationship between char and int in I/O
- puts
- The puts function stands for "put string." Its behavior is very predictable: it takes the string you give it, prints it to the console, and then automatically adds a newline character (\n) at the end.
- Lesson 700 — Printing strings with puts
Q
- qsort
- It’s the language's way of saying, "I’m pointing to something in memory, but I don't know if it's an integer or a character." Inside the function, you tell C what the data is by "casting" it back to an int*, allowing qsort to remain flexible enough to sort anything.
- Lesson 519 — The `qsort` callback mechanismLesson 635 — Sorting an array of structsLesson 876 — The generic signature of `qsort`Lesson 878 — Writing a string comparison function for `qsort`Lesson 879 — Sorting structs by multiple fieldsLesson 880 — Using `bsearch` on sorted arraysLesson 882 — Common pitfalls in comparison function logicLesson 1059 — Using C library 'qsort' functionLesson 1060 — Writing a custom comparator for qsortLesson 1066 — Using C library 'bsearch' function
- qsort()
- Because qsort() is designed to handle any data type (from integers to complex structures), it uses "void pointers" (void *).
- Lesson 877 — Writing an integer comparison functionLesson 879 — Sorting structs by multiple fields
- quadruples
- When you double the amount of data, the time it takes to sort doesn't just double—it quadruples.
- Lesson 1050 — Time complexity of O(n^2) sorts
- quantity
- In the example above, the compiler inserts 3 bytes of empty padding after label so that quantity starts on a memory address that is a multiple of 4.
- Lesson 637 — The sizeof operator on structs
- Quarter-Rule
- A common industry standard is the Quarter-Rule: only shrink the capacity by half when the size drops to one-quarter of the capacity.
- Lesson 987 — Popping and shrinking logic
- Queue
- To keep track of who to visit next without getting lost, BFS uses a Queue (First-In, First-Out).
- Lesson 1014 — Queue abstract data type conceptLesson 1044 — Breadth-First Search (BFS) logic
- queue[front]
- If you try to access queue[front] when no data exists, your program will crash or behave unpredictably.
- Lesson 1017 — Dequeue operation logic
- Quick Sort
- While algorithms like Bubble Sort and Insertion Sort are typically stable, Quick Sort is often unstable because it swaps elements over long distances.
- Lesson 1052 — Stability in sorting algorithms
- quit
- To leave the debugger and return to your normal terminal, type quit or press Ctrl+D.
- Lesson 826 — Starting GDB with an executableLesson 1161 — Starting a program in `gdb` or `lldb`
R
- R-value
- To understand how this works, you need to understand the two "sides" of the operation: the L-value and the R-value.
- Lesson 191 — L-values vs R-values
- Race Condition
- In C programming, this is known as a Race Condition.
- Lesson 763 — Temporary file security risks
- radians
- C's trigonometric functions require angles in radians, so always multiply degrees by (PI / 180.0) before passing them to sin(), cos(), or tan().
- Lesson 863 — Trigonometric functions in radians
- radius radius 3.14159
- Readability: radius radius PI is much clearer to a human than radius radius 3.14159.
- Lesson 768 — Defining constants with `#define`
- radius radius PI
- Readability: radius radius PI is much clearer to a human than radius radius 3.14159.
- Lesson 768 — Defining constants with `#define`
- RAND_MAX
- RAND_MAX defines the upper limit of C’s random number generator, allowing you to scale raw random integers into useful ranges or percentages.
- Lesson 884 — The importance of the `RAND_MAX` constant
- rand()
- In a later lesson, we will learn how to "seed" the generator to start on a different page every time, but for now, focus on how rand() provides the values you need to create variety in your code.
- Lesson 883 — Generating pseudo-random numbers with `rand`Lesson 884 — The importance of the `RAND_MAX` constantLesson 885 — Seeding the generator with `srand`Lesson 886 — Why you should only seed onceLesson 887 — Scaling `rand` results to a specific rangeLesson 888 — Getting a unique seed with `time(NULL)`
- rand() % N
- By using rand() % N, you force the result to stay within the range of 0 to N-1.
- Lesson 887 — Scaling `rand` results to a specific range
- Random access
- You use random access for large databases or complex file formats.
- Lesson 720 — Sequential vs random access concepts
- rank
- The hero variable is instantly populated with its original level, health, and rank as if it never left.
- Lesson 729 — Reading structs back into memory
- rbx
- It often keeps important variables inside CPU registers (like eax or rbx) because accessing registers is faster than accessing RAM.
- Lesson 960 — The 'Clobber' list explained
- reaches
- The inner loop starts and says, "Run until j reaches i." Since i is 1, it runs once and prints one star.
- Lesson 303 — Controlling the inner loop with outer loop variables
- reaches 3
- In this code, when i reaches 3, numbers[3] tries to read memory just outside the allocated block.
- Lesson 1166 — Identifying 'Invalid Read' errors
- read
- The read and write system calls move raw sequences of bytes between file descriptors and memory buffers without any formatting or translation.
- Lesson 386 — Accessing elements with the `[]` operatorLesson 1097 — Reading and writing raw bytesLesson 1101 — Creating pipes with pipe()
- read end
- Imagine a literal physical pipe: you pour water into one end (the write end), and it flows out the other (the read end).
- Lesson 1100 — Anatomy of a pipe
- read-only window
- When you combine them, you create a read-only window into a piece of hardware or a shared memory location.
- Lesson 917 — Combining `const` and `volatile`
- read()
- Non-blocking I/O allows your program to remain responsive by forcing read() and write() to return immediately with a "try again" status instead of pausing execution.
- Lesson 1092 — File descriptors vs FILE pointersLesson 1098 — Non-blocking I/O basicsLesson 1104 — Piping data between parent and childLesson 1106 — Introduction to named pipes (FIFOs)
- readability
- First, readability: you can scan a header file in seconds to see what a library is capable of without scrolling through hundreds of lines of logic.
- Lesson 796 — Splitting code into `.c` and `.h`
- readelf
- If you were to peak inside the resulting my_program file with a tool like readelf, you would see the OS-level headers that turn your simple C logic into a formal, runnable application.
- Lesson 808 — The executable ELF format
- Reader
- A Reader that looks at every character in the original string.
- Lesson 444 — Removing a character from a string
- reading
- A Read-Write Lock (pthread_rwlock_t) distinguishes between reading and writing.
- Lesson 1138 — Read-write locks basics
- realloc
- When you pass a smaller size to realloc, the computer usually keeps the memory block at its current address but marks the trailing end as "free." Your data at the beginning of the block stays exactly where it is, undisturbed.
- Lesson 536 — Header file stdlib.h for allocationLesson 546 — Resizing blocks with reallocLesson 547 — Handling realloc failure safelyLesson 548 — Reallocating to a smaller sizeLesson 549 — Using realloc as malloc or freeLesson 590 — Growing an arena with virtual memoryLesson 870 — Resizing blocks with `realloc`Lesson 984 — Geometric resizing with reallocLesson 985 — Amortized time complexityLesson 987 — Popping and shrinking logicLesson 988 — Freeing the dynamic arrayLesson 1214 — Implementing a dynamic array for storage
- realloc()
- If you forget to update that size variable after a realloc(), your program will likely crash or corrupt memory.
- Lesson 561 — Heap buffer overflowsLesson 981 — Structure for dynamic arrays
- rear
- If your array size is 5 and your rear is at index 4, the next position isn't 5 (which is out of bounds); it’s (4 + 1) % 5, which equals 0.
- Lesson 1015 — Front and Rear pointersLesson 1016 — Enqueue operation logicLesson 1017 — Dequeue operation logicLesson 1018 — Circular array implementationLesson 1020 — Linked list queue implementation
- recipe
- A Makefile consists of "rules." Each rule has a target (what you want to create), a dependency (what is needed to create it), and a recipe (the command to run).
- Lesson 1211 — Writing the Makefile for the project
- recipe book
- Think of your executable file like a recipe book stored on a shelf (the Hard Drive).
- Lesson 31 — How the OS runs a program
- recipes
- A Makefile rule uses targets (the goal), dependencies (the requirements), and recipes (the commands) to automate your build process efficiently.
- Lesson 819 — Targets, dependencies, and recipes
- Record
- If every Record occupies the same number of bytes, we can calculate the memory address of the 100th record with simple math.
- Lesson 1213 — Defining the Record structLesson 1218 — Loading data from a binary file
- Record data[100]
- If we declare a standard array like Record data[100];, we hit a wall the moment the 101st item arrives.
- Lesson 1214 — Implementing a dynamic array for storage
- record_count
- By always checking your record_count against your MAX_RECORDS, you ensure that your data store remains stable.
- Lesson 1216 — Adding and Deleting records safely
- record_count < MAX_RECORDS
- Before adding a record, you must check if record_count < MAX_RECORDS.
- Lesson 1216 — Adding and Deleting records safely
- Records
- In our data store project, we aren't just saving raw bytes; we are saving Records.
- Lesson 1213 — Defining the Record struct
- recursion
- Recursion is like standing on the first step and saying, "To climb this staircase, I will step up once, and then I will perform the 'climb a staircase' task for the remaining steps." Each step creates a new, slightly smaller version of the original problem.
- Lesson 349 — Storage of local variablesLesson 354 — Importance of the Base CaseLesson 358 — Iteration vs. Recursion comparisonLesson 531 — Understanding stack overflowLesson 1055 — Merge Sort: Recursive splittingLesson 1130 — Recursive mutexes
- recursive
- To represent this in C, we need a structure that is recursive.
- Lesson 1022 — Recursive tree node structure
- recursive approach
- In the recursive approach, we treat the problem as a series of identical sub-problems.
- Lesson 1063 — Binary Search: Recursive approach
- recursive function
- While losing a few bytes once might not be noticed, losing those bytes inside a loop or a recursive function creates a compound interest effect that can quickly consume every byte of RAM your computer has available.
- Lesson 552 — Leaking in loops and recursion
- recursive mutex
- A recursive mutex solves this by keeping track of two things:
- Lesson 1130 — Recursive mutexes
- recursive step
- If the base case is the emergency brake that stops a function from running forever, the recursive step is the engine that keeps it moving toward that stop.
- Lesson 355 — The Recursive Step
- recv()
- Use send() to push byte arrays out and recv() to pull them in, always checking the return value to see how much data actually moved.
- Lesson 1115 — Sending and receiving over sockets
- RED
- Debugging: When using a debugger, it will often show the name RED instead of the raw number 0, making it much faster to spot bugs.
- Lesson 661 — Defining an enum typeLesson 662 — Default integer values in enumsLesson 664 — Enums vs constant integersLesson 666 — Scoped enum limitations in CLesson 667 — Type safety concerns with enums
- redefinition of 'struct Player'
- The compiler will stop immediately and throw an error: redefinition of 'struct Player'.
- Lesson 789 — The 'duplicate definition' error
- reentrant
- A reentrant function is one that can be safely interrupted and then "re-entered" by a signal handler without causing errors.
- Lesson 1089 — Signal safety and reentrant functions
- register
- The register keyword was created as a hint to the compiler: "This variable is going to be used constantly (like a loop counter), so please keep it in a CPU register instead of RAM to make the program faster."
- Lesson 147 — Introduction to the `register` keywordLesson 923 — Storage class specifier precedenceLesson 924 — The `register` keyword and its modern relevanceLesson 961 — Direct register access
- registers
- To speed things up, the CPU has a few private drawers right on its desk called registers.
- Lesson 961 — Direct register access
- Registry
- Every Registry and every variable using those types updates automatically.
- Lesson 930 — Complex nested `typedef` structures
- regression testing
- The power of this approach is regression testing.
- Lesson 1178 — Automating tests with a Shell script
- Rehashing
- Once the table hits this limit, it’s time to move to a bigger "closet." This process is called Rehashing.
- Lesson 1037 — Load factor and rehashing
- relational operators
- This is where relational operators come in.
- Lesson 242 — Relational operators: <, <=, >, and >=
- remove
- If you try to delete a file that doesn't exist, remove won't crash your program; it will simply return a non-zero value, allowing you to handle the error gracefully.
- Lesson 757 — Deleting files with remove
- remove("filename")
- Use remove("filename") from <stdio.h> to permanently delete a file, checking for a return value of 0 to confirm success.
- Lesson 757 — Deleting files with remove
- remove()
- Just remember: if you create it, you are responsible for deleting it with remove() before your program exits!
- Lesson 759 — Generating temp filenames with tmpnam
- rename
- Moving Files: You can use rename to move a file across directories on the same disk drive (e.g., from data/old.txt to archive/old.txt).
- Lesson 756 — Renaming files with rename
- requestedIndex
- By checking that requestedIndex is at least 0 and strictly less than the array size, we ensure the program never touches memory it doesn't own.
- Lesson 437 — Checking bounds before array access
- reserved
- By using a reserved or padding field, you achieve two things:
- Lesson 575 — Manual padding in structures
- reserved parking space
- Think of field width as a reserved parking space.
- Lesson 56 — Basic field width formatting
- reserves
- The librarian reserves a long row of 100 tables just for you.
- Lesson 590 — Growing an arena with virtual memory
- Resident Set Size
- The Resident Set Size is the actual amount of physical RAM your program is occupying at this very moment.
- Lesson 598 — Page faults and resident set size
- resource leaks
- The main reason to use pthread_detach is to prevent resource leaks.
- Lesson 1121 — Detaching threads
- restrict
- I better reload a[i] from memory every single loop iteration just in case the last write to result[i] changed it."* With restrict, the compiler can load values much more efficiently, knowing they won't change unexpectedly.
- Lesson 915 — The `restrict` pointer qualifierLesson 916 — Optimization benefits of `restrict`
- result
- In this code, result points to the "c" in "code." When we print %s using that pointer, the computer starts reading from that spot, resulting in the output: `Found it!
- Lesson 315 — The Flag Variable patternLesson 428 — Searching for substrings with `strstr`Lesson 446 — Merging two sorted arraysLesson 822 — Automatic variables like `$@` and `$<`Lesson 915 — The `restrict` pointer qualifierLesson 1127 — Critical section best practices
- result = 10
- In the example above, C doesn't look at result = 10 and stop there.
- Lesson 217 — Precedence of assignment
- result = 5
- In the example above, result = giveMeFive(); eventually becomes result = 5;.
- Lesson 327 — The `return` statement flow
- result = a * b
- You place the operator between two operands, like this: result = a * b;.
- Lesson 152 — Multiplication `*` mechanics
- result = giveMeFive()
- In the example above, result = giveMeFive(); eventually becomes result = 5;.
- Lesson 327 — The `return` statement flow
- result = value >> n
- In C, the syntax looks like this: result = value >> n; where n is how many seats everyone moves.
- Lesson 184 — Right shift `>>` mechanics
- result_a
- It looks at result_a and result_b and insists they be compatible.
- Lesson 209 — Type consistency in ternary branches
- result_b
- It looks at result_a and result_b and insists they be compatible.
- Lesson 209 — Type consistency in ternary branches
- result[i]
- I better reload a[i] from memory every single loop iteration just in case the last write to result[i] changed it."* With restrict, the compiler can load values much more efficiently, knowing they won't change unexpectedly.
- Lesson 915 — The `restrict` pointer qualifier
- return
- Because even though the mistake is technically the missing semicolon on Line 4, the compiler didn't realize anything was truly "wrong" until it moved to the next line and saw the word return instead of the ; it was expecting.
- Lesson 9 — Role of the CompilerLesson 15 — The concept of a Source FileLesson 20 — The `main()` function entry pointLesson 23 — Case sensitivity in CLesson 66 — Reading compiler error messagesLesson 67 — Line number trackingLesson 74 — Naming rules and identifiersLesson 305 — Breaking out of nested loops: the limitation of breakLesson 308 — Why goto is generally discouragedLesson 312 — Function returns as a control flow mechanismLesson 313 — Exiting the program with exit()Lesson 323 — Anatomy of a function definitionLesson 324 — The `void` return typeLesson 327 — The `return` statement flowLesson 328 — Returning values from functionsLesson 345 — Limitations of pass by valueLesson 347 — What is a Stack Frame?Lesson 487 — Passing addresses to functionsLesson 489 — Returning multiple values via pointersLesson 530 — Stack frame lifecycle and local variablesLesson 558 — Returning addresses of local variablesLesson 875 — Cleaning up at exit with `atexit`Lesson 1123 — The pthread_exit functionLesson 1219 — Final memory leak check and cleanup
- return (val1 - val2)
- You will often see a shortcut for this logic: return (val1 - val2);.
- Lesson 877 — Writing an integer comparison function
- return 0
- When you run this code, the computer enters the "Front Door" (main), grabs the "Printer" (stdio), shouts your message to the screen, and then closes the shop (return 0).
- Lesson 17 — The 'Hello World' codeLesson 24 — The `return 0;` statementLesson 313 — Exiting the program with exit()Lesson 1072 — Process termination and exit codesLesson 1077 — Capturing child exit status
- return a - b
- A frequent pitfall is using simple subtraction for comparison, like return a - b;.
- Lesson 882 — Common pitfalls in comparison function logic
- Return Address
- The CPU looks at the Return Address stored in that frame to find its way back to main and continue where it left off.
- Lesson 347 — What is a Stack Frame?Lesson 350 — Return addresses in memory
- return code
- If they come back and say, "We can't make that dish," that is a return code.
- Lesson 903 — When to use `errno` vs return codes
- Return codes
- Return codes are for flow control (did it work?).
- Lesson 903 — When to use `errno` vs return codes
- return n + sum(n - 1)
- In the line return n + sum(n - 1);, the (n - 1) is the magic ingredient.
- Lesson 355 — The Recursive Step
- return value
- Instead of crashing or leaving you guessing, fgets communicates this to you through its return value.
- Lesson 707 — Checking for NULL return in fgetsLesson 1074 — Handling fork() return values
- Return values
- You might wonder: "Why not just provide one number for the total bytes?" While you could technically set size to 1 and count to the total bytes, splitting them provides a major advantage: Return values.
- Lesson 727 — The size and count parameters
- return_type (*name)(args)
- A function pointer's declaration must mirror the target function's return type and arguments, with the pointer name wrapped in parentheses: return_type (*name)(args).
- Lesson 514 — Syntax of function pointers
- return_type (*pointer_name)(parameter_types)
- return_type (*pointer_name)(parameter_types);
- Lesson 514 — Syntax of function pointers
- returns
- The upward slope represents the returns as the functions finish.
- Lesson 363 — Visualizing recursive depth
- reusable
- By separating concerns, you make your code reusable.
- Lesson 1210 — Structuring the project into multiple `.c` files
- reverse order
- You can register multiple functions; they will run in the reverse order they were registered (the last one added is the first one executed).
- Lesson 875 — Cleaning up at exit with `atexit`
- rewind
- If you want to hear that same song again, you don't throw the tape away and buy a new one; you simply hit the rewind button to spin the tape back to the beginning.
- Lesson 723 — Rewinding a file to the start
- rewind()
- For instance, you might read a file once to count how many lines it has, rewind() to the start, and then read it a second time to actually process the content now that you know the size.
- Lesson 723 — Rewinding a file to the startLesson 737 — Resetting with rewindLesson 758 — Creating temporary files with tmpfile
- rewind(file_pointer)
- Use rewind(file_pointer); to instantly reset your position to the beginning of a file and clear any end-of-file errors.
- Lesson 723 — Rewinding a file to the start
- rewind(filePointer)
- Use rewind(filePointer); to instantly jump back to the beginning of a file and clear any end-of-file indicators.
- Lesson 737 — Resetting with rewind
- rewind(fptr)
- When you call rewind(fptr), two important things happen:
- Lesson 723 — Rewinding a file to the start
- right
- When you are standing at a node, the left pointer leads you to a whole new subtree where all the values are smaller, and the right pointer leads to a subtree where all the values are larger.
- Lesson 78 — Assigning values with `=`Lesson 190 — Simple assignment `=`Lesson 1022 — Recursive tree node structureLesson 1026 — Pre-order and Post-order traversal
- right subtree
- In a BST, every single value in the left subtree must be smaller than the Root, and every single value in the right subtree must be larger than the Root.
- Lesson 1023 — Properties of a Binary Search Tree
- right-aligned
- By default, the text is right-aligned (padded on the left).
- Lesson 685 — Specifying field width for alignment
- Right-Left Rule
- To stay sane, we use the Right-Left Rule.
- Lesson 926 — Reading declarations with the 'Right-Left' rule
- right-to-left associativity
- In C, the assignment operator (=) has right-to-left associativity.
- Lesson 196 — Chained assignments `a = b = c`
- Root
- In Post-order traversal, you visit the Left subtree, then the Right subtree, and finally the Root (L-R-Root).
- Lesson 1024 — Recursive insertion logicLesson 1026 — Pre-order and Post-order traversalLesson 1027 — Searching for a value in BSTLesson 1028 — Finding Min and Max nodes
- round()
- Use ceil() to round up, floor() to round down, and round() for standard mathematical rounding.
- Lesson 864 — Rounding with `ceil`, `floor`, and `round`
- row
- The break successfully stopped the col loop for row 2, but the row loop kept right on ticking.
- Lesson 305 — Breaking out of nested loops: the limitation of breakLesson 410 — Accessing elements using `[row][col]`
- row = 2
- The outer loop moves to row = 2, and the process repeats.
- Lesson 298 — Introduction to loops inside loops
- Row 3
- If you run this, you will notice that even after the program finds (2,2) and hits the break, it immediately starts checking Row 3.
- Lesson 305 — Breaking out of nested loops: the limitation of break
- row of five lockers
- Instead, you would ask for a row of five lockers right next to each other.
- Lesson 383 — Declaring an array with `type name[size]`
- row-major order
- C stores multi-dimensional arrays in row-major order, meaning it lays out all elements of the first row, then the second, in one continuous line in memory.
- Lesson 408 — Memory layout: Row-major order
- Rows
- In programming terms, we call these Rows and Columns.
- Lesson 407 — Declaring 2D arrays: Rows and Columns
- rowSum
- By declaring rowSum or colSum inside the outer loop, you ensure each line starts with a clean slate.
- Lesson 413 — Summing rows and columns individually
- run
- If you want to actually begin execution, you would type run at the prompt, but for now, notice that GDB has successfully read the symbols from your file.
- Lesson 826 — Starting GDB with an executableLesson 827 — The `run` and `quit` commandsLesson 829 — Setting breakpoints with `break`Lesson 830 — Stepping through code with `next` and `step`Lesson 835 — Setting conditional breakpointsLesson 1161 — Starting a program in `gdb` or `lldb`
- run input.txt
- If your program requires command-line arguments (like filenames or flags), you provide them directly after the command, like run input.txt.
- Lesson 827 — The `run` and `quit` commands
- rwlock
- You should use them when you have a high "read-to-write ratio." If your threads are writing just as often as they are reading, the extra complexity of the rwlock might actually slow your program down.
- Lesson 1138 — Read-write locks basics
S
- s + 1
- Because according to the C standard, s + 1 is never allowed to overflow, so the compiler assumes it will always be greater than s.
- Lesson 935 — Signed integer overflow vs Unsigned wrap
- s with a single
- This "flips" the mask, creating a row of 1s with a single 0 at our target position.
- Lesson 188 — Common bitwise idioms
- s1
- Think of the dot as "belonging to." If you say s1.age = 20, you are telling C: "Go to the s1 folder and change the age that belongs to it."
- Lesson 239 — Member access `.` and `->`
- s1.age = 20
- Think of the dot as "belonging to." If you say s1.age = 20, you are telling C: "Go to the s1 folder and change the age that belongs to it."
- Lesson 239 — Member access `.` and `->`
- sa_flags
- sa_flags: Special options, like SA_RESTART, which tells the OS to resume interrupted system calls automatically.
- Lesson 1088 — The sigaction struct and function
- sa_handler
- sa_handler: The pointer to your custom function.
- Lesson 1088 — The sigaction struct and function
- sa_mask
- sa_mask: A set of signals to block while your handler is running (to prevent "signal overlap").
- Lesson 1088 — The sigaction struct and function
- SA_RESTART
- sa_flags: Special options, like SA_RESTART, which tells the OS to resume interrupted system calls automatically.
- Lesson 1088 — The sigaction struct and function
- safe
- That key opens a safe containing the gold (the actual data).
- Lesson 505 — Accessing data through double dereference
- safety during teamwork
- The most common reason is safety during teamwork.
- Lesson 493 — Pointer to a constant (`const int *p`)
- SALES_TAX_RATE
- Instead of using 0.07 everywhere, you create a symbol like SALES_TAX_RATE to represent it.
- Lesson 118 — Literal vs. Symbolic constants
- Salt
- You might have one jar labeled Cinnamon and another labeled Salt.
- Lesson 667 — Type safety concerns with enums
- same
- Use memmove whenever you are shifting data around within the same array.
- Lesson 857 — Handling overlapping regions with `memmove`
- same array
- However, this is generally only safe and meaningful when both pointers point to elements within the same array.
- Lesson 467 — Pointer comparison with `==` and `<`
- same starting memory address
- All members of a union share the same starting memory address.
- Lesson 654 — Memory layout of a union
- save.dat
- When you write a struct this way, the resulting file (save.dat) isn't meant to be read by humans in a text editor like Notepad—it will look like gibberish.
- Lesson 728 — Writing entire structs to disk
- saveData()
- Instead, you want one saveData() function that accepts a pointer to anything.
- Lesson 510 — Implicit conversion to `void *`
- saveFloat()
- You don't want to write one function for saveInt(), another for saveFloat(), and another for saveStudent().
- Lesson 510 — Implicit conversion to `void *`
- saveInt()
- You don't want to write one function for saveInt(), another for saveFloat(), and another for saveStudent().
- Lesson 510 — Implicit conversion to `void *`
- saveStudent()
- You don't want to write one function for saveInt(), another for saveFloat(), and another for saveStudent().
- Lesson 510 — Implicit conversion to `void *`
- say_hello
- The compiler looks at main.c, sees that it needs a function called say_hello, finds that function inside greetings.c, and stitches them together.
- Lesson 59 — Compiling multiple source files
- sayHello
- Whether you use sayHello or the explicit "address of" operator &sayHello, C treats them as the same thing: a pointer to the code.
- Lesson 325 — Writing your first custom functionLesson 515 — Taking the address of a function
- sayHi()
- If main() calls greet(), and greet() calls sayHi(), the stack grows upward.
- Lesson 351 — Visualizing the stack during nested calls
- sbrk
- The program break is the boundary of your heap, and brk/sbrk are the system-level tools used to push that boundary forward to claim more memory.
- Lesson 592 — Introduction to brk and sbrk
- sbrk(0)
- When you call sbrk(0), it doesn't move the fence at all; it just tells you where the fence is currently located.
- Lesson 592 — Introduction to brk and sbrk
- sbrk(increment)
- This moves the "fence" by a relative amount. If you call sbrk(1024), you are asking the OS to move the fence 1024 bytes further away, growing your heap.
- Lesson 592 — Introduction to brk and sbrk
- scanf
- While you can limit this by using %19s (telling it to stop after 19 characters to leave room for the null terminator), standard scanf is generally considered unsafe for professional applications where users might enter unpredictable text.
- Lesson 270 — Reading input until EOF with whileLesson 390 — Reading array values from user inputLesson 422 — Scanning strings with `%s` and `scanf` limitationsLesson 438 — Handling the `scanf` buffer overflowLesson 676 — The concept of a stream in CLesson 677 — Introduction to stdin, stdout, and stderrLesson 678 — The header file <stdio.h>Lesson 680 — Basic character input with getcharLesson 692 — How scanf uses memory addressesLesson 693 — Scanning integers and floatsLesson 694 — Reading characters with ' %c' spacingLesson 695 — Limiting string length in scanfLesson 696 — Handling the return value of scanfLesson 697 — How scanf leaves trailing newlinesLesson 698 — Using scansets with %[...]Lesson 701 — Reading safe strings with fgetsLesson 705 — Parsing data from strings with sscanfLesson 719 — Formatted file input with fscanfLesson 760 — Redirecting streams with freopenLesson 761 — Standard stream redirection in shellsLesson 1097 — Reading and writing raw bytes
- scanf("%d")
- While functions like scanf("%d") are smart enough to skip over whitespace to find a number, the character formatter—%c—is different.
- Lesson 694 — Reading characters with ' %c' spacing
- scanf()
- In future lessons, we will use fgets() or scanf() with width limits, both of which allow you to specify the maximum number of characters to read, keeping your "room" safe from overcrowding.
- Lesson 390 — Reading array values from user inputLesson 433 — Safe input reading with `fgets`Lesson 652 — Limitations of bit-field addressesLesson 698 — Using scansets with %[...]Lesson 699 — Why gets is dangerous and deprecatedLesson 1093 — Standard streams (0, 1, 2)Lesson 1153 — Using `fgets()` instead of `scanf()` for stringsLesson 1175 — Separating logic from `main()` for testability
- scansets
- If you try to type "New York," it only captures "New." To fix this without jumping to more complex functions, we use scansets.
- Lesson 698 — Using scansets with %[...]
- Scientific Notation
- In C, floating-point types (float and double) solve this using Scientific Notation.
- Lesson 100 — Scientific notation in C
- scope
- Where you place your declaration determines its scope—the area of code where the function is "visible" and ready to be used.
- Lesson 138 — Shadowing: Nested scope name clashesLesson 306 — Defining labels in C codeLesson 333 — Scope of function declarationsLesson 551 — Losing the last pointer to a block
- scoping control
- The most common reason is scoping control.
- Lesson 769 — Removing definitions with `#undef`
- Score
- If you define a variable named score but try to print Score, the compiler will tell you that Score is "undeclared." It’s like calling a friend named "Bill" by the name "Will"—close doesn't count.
- Lesson 23 — Case sensitivity in CLesson 50 — Printing integers with `%d`Lesson 71 — Common beginner typosLesson 74 — Naming rules and identifiersLesson 75 — The syntax of a declarationLesson 77 — Garbage values and uninitialized variablesLesson 79 — Declaration vs. InitializationLesson 80 — Variables in memory addressesLesson 190 — Simple assignment `=`Lesson 346 — Preparing for pass by referenceLesson 448 — How variables are stored in RAMLesson 457 — The Dereference operator `*`Lesson 602 — Initializing structs with brace notationLesson 604 — Copying structs with the assignment operatorLesson 608 — Using typedef with primitive typesLesson 919 — The `static` keyword in global scopeLesson 973 — Introduction to the `_Generic` keyword
- score += 10
- When you see score += 10;, your brain instantly recognizes that the score is growing.
- Lesson 192 — Compound addition `+=`
- score = 10
- If you want to put the number 10 inside that box, you write score = 10;.
- Lesson 190 — Simple assignment `=`
- score > 10
- If you use score > 10, the player who earns exactly 10 points would be very frustrated to find they haven't won yet!
- Lesson 160 — Greater or equal `>=` and less or equal `<=`
- score >= 10
- These operators are the backbone of "range checking." If you are building a game where a player wins if they have 10 or more points, you use score >= 10.
- Lesson 160 — Greater or equal `>=` and less or equal `<=`
- scores
- When you write scores[1] = 95;, the computer calculates the memory address of the second slot in the scores array and overwrites whatever was there with the number 95.
- Lesson 383 — Declaring an array with `type name[size]`Lesson 387 — Modifying individual array elementsLesson 396 — Assigning values vs initializing arraysLesson 986 — Accessing elements by indexLesson 988 — Freeing the dynamic arrayLesson 1167 — Tracking down 'Use After Free' bugs
- scores = NULL
- Notice the line scores = NULL; after the free command.
- Lesson 988 — Freeing the dynamic array
- scores[0]
- If you accidentally try to access scores[0] later, your program might crash or behave unpredictably.
- Lesson 402 — Finding the maximum value in an arrayLesson 988 — Freeing the dynamic array
- scores[1]
- Under the hood, when you write scores[1], C performs pointer arithmetic.
- Lesson 986 — Accessing elements by index
- scores[1] = 95
- When you write scores[1] = 95;, the computer calculates the memory address of the second slot in the scores array and overwrites whatever was there with the number 95.
- Lesson 387 — Modifying individual array elements
- scores[1][2]
- When you write scores[1][2], the computer does a little mental math.
- Lesson 410 — Accessing elements using `[row][col]`
- scores[3]
- Because the computer knows the elements are in a perfect line, it doesn't have to "search" for scores[3].
- Lesson 384 — Visualizing memory layout of arrays
- scores[5]
- Crucially, the condition i < 5 prevents the program from trying to access scores[5], which doesn't exist.
- Lesson 400 — Printing array elements in a sequenceLesson 405 — Avoiding off-by-one errors in loops
- scores[500]
- Unlike some modern languages, C will not stop you if you try to access scores[500] on an array that only has 3 slots.
- Lesson 986 — Accessing elements by index
- scores[i]
- Think of scores[i] as the box itself, while &scores[i] is the GPS coordinate of that box.
- Lesson 390 — Reading array values from user input
- SCREAMING_SNAKE_CASE
- We use a style called SCREAMING_SNAKE_CASE.
- Lesson 117 — Naming conventions for constants
- SDL
- You might write a perfect program, but because you are using a standard library (like stdio.h) or a graphics library (like SDL), Valgrind might flag memory management patterns inside those pre-compiled files.
- Lesson 570 — Suppressing known tool warnings
- SDL_
- The OpenGL library prefixes everything with gl (e.g., glVertex3f), and the SDL library prefixes everything with SDL_.
- Lesson 801 — Naming conventions for large projects
- search_key
- A robust lookup function will check if the key stored at that index actually matches the search_key you provided.
- Lesson 1036 — Hash table lookup
- second
- The second number [10] tells you how many items are inside each list.
- Lesson 407 — Declaring 2D arrays: Rows and Columns
- SECONDS_IN_A_DAY
- If they see SECONDS_IN_A_DAY, they understand instantly.
- Lesson 115 — Defining constants with `#define`
- secret_number
- Now, when you run this program through a debugger (like GDB or LLDB), the tool can say, "You are currently on line 5, and the variable secret_number is equal to 42."
- Lesson 1075 — Process duplication and copy-on-writeLesson 1160 — Compiling with `-g` for debug symbols
- secret_stuff
- The compiler now has two places to look: the current directory and the secret_stuff directory.
- Lesson 63 — Header search paths
- secretCode
- When you set pointerB = pointerA, you aren't making a copy of the data (secretCode).
- Lesson 460 — Multiple pointers to the same address
- security gate with two locks
- Think of it like a security gate with two locks.
- Lesson 175 — Bitwise AND `&`
- security guard
- This is like a security guard who stays at their post as long as the building is open.
- Lesson 321 — Choosing the right loop for the task
- seed
- If you provide the same starting point—called a seed—using srand(), the formula will spit out the exact same sequence of "random" numbers every time.
- Lesson 886 — Why you should only seed onceLesson 888 — Getting a unique seed with `time(NULL)`
- SEEK_CUR
- SEEK_SET, SEEK_CUR, and SEEK_END define your starting point: the beginning, your current spot, or the end of the file.
- Lesson 733 — Moving the pointer with fseekLesson 734 — The SEEK_SET, SEEK_CUR, SEEK_END constants
- SEEK_END
- Using these named constants makes your code "readable." When another programmer sees SEEK_END, they instantly know you are navigating relative to the end of the file, making your intentions clear without needing a comment.
- Lesson 734 — The SEEK_SET, SEEK_CUR, SEEK_END constantsLesson 736 — Finding file size using seek and tellLesson 739 — Risks of seeking in text mode
- SEEK_SET
- Stick to constants: It is always safe to seek to the very beginning (SEEK_SET with offset 0) or the very end (SEEK_END with offset 0).
- Lesson 733 — Moving the pointer with fseekLesson 734 — The SEEK_SET, SEEK_CUR, SEEK_END constantsLesson 739 — Risks of seeking in text mode
- Segmentation Fault
- In C, if your code tries to assign a new value to a memory address protected by PROT_READ, the OS triggers a Segmentation Fault.
- Lesson 595 — Memory protection constants (PROT_READ)Lesson 1209 — Error handling for missing files
- Segmentation fault (core dumped)
- Once enabled, if your program crashes, you’ll see a message like Segmentation fault (core dumped).
- Lesson 352 — Identifying a Stack OverflowLesson 837 — Debugging a Segfault from a core dump
- self-referential structure
- This leads to a unique C programming concept called a self-referential structure.
- Lesson 989 — Defining the self-referential node struct
- self-referential structures
- In C, we use self-referential structures to do exactly this.
- Lesson 626 — Self-referential structs for linked lists
- Semaphores
- To solve this in C, we use two tools: Mutexes (to ensure only one thread touches the rack at a time) and Semaphores (to track how many spots are full or empty).
- Lesson 1136 — The producer-consumer problem
- semicolon
- When you declare multiple variables on one line, you state the data type once, followed by your chosen names separated by commas, and ending with a single semicolon.
- Lesson 75 — The syntax of a declarationLesson 76 — Multiple declarations in one lineLesson 221 — Sequence point definition
- send()
- Use send() to push byte arrays out and recv() to pull them in, always checking the return value to see how much data actually moved.
- Lesson 1115 — Sending and receiving over sockets
- Sensor
- The rest of your program, which just passes the Sensor struct around, doesn't need to change at all.
- Lesson 674 — Information hiding using void pointers
- sensor.c
- We tell the compiler: "When building the test, don't use the real sensor.c file; use my mock_sensor.c file instead."
- Lesson 1176 — Mocking simple dependencies
- sequence point
- It discards the result of the left expression, moves past a sequence point, and evaluates the expression on the right.
- Lesson 222 — Sequence points at `;`Lesson 223 — Sequence points in logic `&&` and `||`Lesson 224 — The comma operator `,`Lesson 226 — Function call sequence points
- sequence points
- To keep things sane, the language uses sequence points.
- Lesson 937 — Sequence point violations
- Sequential access
- You use sequential access for most tasks, such as reading a configuration file or processing a list of names.
- Lesson 720 — Sequential vs random access concepts
- SERVER_ERROR
- In the example above, because SERVER_ERROR was set to 500, the compiler automatically assigned UNKNOWN the next integer in sequence: 501.
- Lesson 663 — Explicitly assigning enum values
- server_fd
- You can keep the client_fd in a list of active customers while your main loop goes back to accept() on the server_fd to wait for the next person in line.
- Lesson 1113 — Accepting client connections
- setbuf
- What you'll learn: How to use the simplified setbuf function to quickly toggle between fully buffered and unbuffered output.
- Lesson 753 — The setbuf shorthand
- setup()
- Safety: You can reuse common names like setup() or clean_up() in every single file of your project without them ever bumping into each other.
- Lesson 798 — Static functions for file scoping
- setvbuf
- Alternatively, if you were writing a massive 1GB file, you might create a large char array of 64KB and pass it to setvbuf with _IOFBF to make the process much faster by reducing the number of hardware writes.
- Lesson 752 — Setting custom buffers with setvbufLesson 753 — The setbuf shorthand
- seven days
- If you are printing a calendar, the outer loop moves through the weeks, and for every week, the inner loop moves through the seven days.
- Lesson 299 — Inner loop vs outer loop execution order
- shallow copy
- If you perform a shallow copy (Person2 = Person1), C simply copies the memory address stored in the pointer.
- Lesson 604 — Copying structs with the assignment operatorLesson 629 — Deep vs shallow copies of nested structs
- shared global variables
- Use volatile whenever you are dealing with memory-mapped I/O, interrupt service routines, or shared global variables in multi-threaded applications where a value might change without the compiler seeing it happen in the current code block.
- Lesson 914 — How `volatile` prevents compiler optimization
- shared libraries
- This is fine for a standalone program, but it creates a massive headache for shared libraries.
- Lesson 814 — Position Independent Code `-fPIC`
- shared library
- Unlike a static library, which gets physically shoved inside your program's executable file, a shared library stays separate.
- Lesson 813 — What is a shared library `.so` / `.dll`
- Shared memory
- Shared memory accessed by multiple processors.
- Lesson 913 — The `volatile` qualifier for hardware mapping
- shared_cookies
- Only after that change does it assign the value to shared_cookies.
- Lesson 198 — Prefix increment `++x`
- Shifting (<< or >>)
- Shifting (<< or >>): To move that byte to its new position.
- Lesson 953 — Manual byte swapping techniques
- short
- You would use a short if you are writing a program for a device with very little memory—like a microwave controller—or if you have a massive list of small numbers, like the ages of a million students.
- Lesson 82 — Short vs. Long integersLesson 89 — The `signed` keywordLesson 92 — Understanding Integer OverflowLesson 122 — Integer promotion rulesLesson 125 — Risks of narrowing conversionsLesson 132 — Safe downcasting techniquesLesson 228 — Implicit promotion to `int`Lesson 229 — Usual arithmetic conversionsLesson 233 — Promotion of `char` and `short`Lesson 526 — Misaligned pointer accessLesson 641 — Reordering members to reduce paddingLesson 643 — Alignment requirements for different types
- short-circuit evaluation
- This "stopping early" is what we call short-circuit evaluation.
- Lesson 171 — Short-circuit evaluation of `||`Lesson 253 — Short-circuit evaluation in logical ANDLesson 254 — Short-circuit evaluation in logical OR
- should never happen
- You use assert to check for things that should never happen if your logic is correct.
- Lesson 901 — Using `assert` for internal debugging
- SHRT_MIN
- C provides these limits in a library called <limits.h>, which gives us nicknames like INT_MAX (the largest possible int) or SHRT_MIN (the smallest possible short).
- Lesson 132 — Safe downcasting techniques
- side effect
- This change to the environment is called a side effect.
- Lesson 220 — Definition of a side effect
- side effects
- It guarantees that all side effects (like increments or assignments) from the left side are fully completed and saved to memory before it even looks at the right side (B).
- Lesson 223 — Sequence points in logic `&&` and `||`Lesson 227 — Order of evaluation vs PrecedenceLesson 775 — Side effects in macro arguments
- sig
- The signal constant (like SIGTERM to ask it to stop, or SIGUSR1 for a custom message).
- Lesson 1086 — Sending signals with kill()
- SIG_BLOCK
- How: Usually SIG_BLOCK (to add to the current mask) or SIG_UNBLOCK (to remove).
- Lesson 1090 — Blocking signals with sigprocmask()
- SIG_UNBLOCK
- How: Usually SIG_BLOCK (to add to the current mask) or SIG_UNBLOCK (to remove).
- Lesson 1090 — Blocking signals with sigprocmask()
- sigaction
- The sigaction struct provides a portable and reliable way to define complex signal-handling behavior that won't reset or glitch under pressure.
- Lesson 1088 — The sigaction struct and function
- sigaction()
- To use it, you create the struct, fill it with your preferences, and pass it to the sigaction() function.
- Lesson 1088 — The sigaction struct and function
- SIGALRM
- When you call alarm(5), you are telling the Operating System: "Hey, let me go back to my work, but please poke me in exactly five seconds." When the time is up, the OS sends a SIGALRM signal to your process.
- Lesson 1091 — Handling alarms with alarm()
- SIGFPE
- The system detecting a math error, like dividing by zero (SIGFPE).
- Lesson 1084 — What are Unix signals
- SIGINT
- The Registration: By calling signal(SIGINT, handle_sigint), you are telling the kernel: "If you send me a SIGINT, don't kill me immediately.
- Lesson 1084 — What are Unix signalsLesson 1085 — Common signals: SIGINT, SIGTERM, SIGKILLLesson 1087 — Basic signal handling with signal()Lesson 1090 — Blocking signals with sigprocmask()
- SIGKILL
- Use SIGINT and SIGTERM for graceful shutdowns, and reserve SIGKILL for emergencies when a process refuses to die.
- Lesson 1085 — Common signals: SIGINT, SIGTERM, SIGKILL
- sign and the type specifier (like
- To set a field width, you place a number between the % sign and the type specifier (like d for integers).
- Lesson 56 — Basic field width formatting
- signal
- If you have ten threads waiting for a "Go!" signal and you use signal, nine of them will keep sleeping while the winner starts working.
- Lesson 1084 — What are Unix signalsLesson 1135 — Broadcasting to all threads
- signal = 0
- Readability: signal = RED is much easier to understand than signal = 0.
- Lesson 664 — Enums vs constant integers
- signal = RED
- Readability: signal = RED is much easier to understand than signal = 0.
- Lesson 664 — Enums vs constant integers
- Signal Name
- To send a signal, you need two pieces of information: the PID (Process ID) of the target and the Signal Name (the type of message).
- Lesson 1086 — Sending signals with kill()
- signal()
- The signal() function allows you to redirect system interrupts to custom functions, giving your program a chance to respond to events rather than simply being terminated.
- Lesson 1087 — Basic signal handling with signal()Lesson 1088 — The sigaction struct and function
- signals
- It is simply the primary tool used to send signals—small notifications—between processes.
- Lesson 1086 — Sending signals with kill()Lesson 1087 — Basic signal handling with signal()
- signature
- To point to a function, your pointer must exactly match the function's signature (its return type and its parameters).
- Lesson 514 — Syntax of function pointers
- signed
- If you are writing a program where some numbers must be positive (unsigned) and others must allow negatives, using the signed keyword side-by-side with unsigned makes your code much easier to read and less prone to mistakes.
- Lesson 89 — The `signed` keywordLesson 94 — Format specifiers for unsigned intsLesson 111 — Signed vs. Unsigned charsLesson 649 — Signed vs unsigned bit-fieldsLesson 846 — The importance of casting to `unsigned char` in `ctype` functionsLesson 945 — The significance of `char` signness
- signed char
- Magnitude Overflow: If you try to force a large number into a type that physically cannot hold a value that high, the bits "wrap around." For example, trying to fit the number 300 into a signed char (which usually only goes up to 127) will result in a weird, often negative number.
- Lesson 111 — Signed vs. Unsigned charsLesson 125 — Risks of narrowing conversionsLesson 157 — Basic arithmetic overflowLesson 945 — The significance of `char` signness
- signed int
- However, if you declare it as a signed int, C uses the leftmost bit as a "sign bit" to track whether the number is positive or negative.
- Lesson 89 — The `signed` keywordLesson 646 — Syntax for declaring bit-fieldsLesson 647 — Restrictions on bit-field typesLesson 649 — Signed vs unsigned bit-fields
- signed integer
- Think of a signed integer like a thermometer.
- Lesson 95 — When to choose unsigned over signed
- Signed integers
- Signed integers (like a standard int) are different.
- Lesson 935 — Signed integer overflow vs Unsigned wrap
- signpost
- Instead of building a house, you have created a signpost.
- Lesson 484 — Memory layout of string pointers
- sigprocmask
- Once sigprocmask unblocks the signal, the kernel checks for pending signals and triggers the handler immediately.
- Lesson 1090 — Blocking signals with sigprocmask()
- sigprocmask()
- Use sigprocmask() to protect sensitive code from interruptions by putting signals on hold until your work is done.
- Lesson 1090 — Blocking signals with sigprocmask()
- SIGSEGV
- The program trying to access memory it doesn't own (SIGSEGV).
- Lesson 1084 — What are Unix signals
- sigset_t
- To block signals, we use a sigset_t variable to hold a list of signals we want to mask.
- Lesson 1090 — Blocking signals with sigprocmask()
- SIGTERM
- Use SIGINT and SIGTERM for graceful shutdowns, and reserve SIGKILL for emergencies when a process refuses to die.
- Lesson 1084 — What are Unix signalsLesson 1085 — Common signals: SIGINT, SIGTERM, SIGKILL
- silk shirt
- If you later decide to shove a silk shirt into that same tiny space, the boots are tossed out.
- Lesson 659 — The danger of reading the wrong union member
- sin
- What you'll learn: How to use the sin, cos, and tan functions from the math library and why you must convert degrees to radians first.
- Lesson 863 — Trigonometric functions in radians
- sin_addr
- In this example, sin_family, sin_port, and sin_addr are the specific fields within the structure.
- Lesson 1109 — The sockaddr_in structure
- sin_family
- In this example, sin_family, sin_port, and sin_addr are the specific fields within the structure.
- Lesson 1109 — The sockaddr_in structure
- sin_port
- In this example, sin_family, sin_port, and sin_addr are the specific fields within the structure.
- Lesson 1109 — The sockaddr_in structure
- sin()
- C's trigonometric functions require angles in radians, so always multiply degrees by (PI / 180.0) before passing them to sin(), cos(), or tan().
- Lesson 863 — Trigonometric functions in radians
- sin(90)
- If you try to calculate the sine of 90 degrees by writing sin(90), C won't give you 1.0.
- Lesson 863 — Trigonometric functions in radians
- single
- Single quotes ('A') are for a single character.
- Lesson 416 — Defining strings with double quotes
- single character
- %c: Used for a single character (like 'A' or '$').
- Lesson 49 — Introduction to Format Specifiers
- single marble
- Think of a single character literal (using single quotes) as a single marble.
- Lesson 418 — Difference between `'a'` and `"a"`
- single quotes
- When you want to assign a character to a variable, you must wrap it in single quotes (' ').
- Lesson 51 — Printing characters with `%c`Lesson 105 — The `char` typeLesson 416 — Defining strings with double quotesLesson 679 — Basic character output with putchar
- Singly Linked List
- In a Singly Linked List, those doors are one-way turnstiles.
- Lesson 999 — Updating the node struct
- size
- To declare an array in C, you need three specific pieces of information: the type of data you are storing, a name for the array, and the size (how many slots you need) inside square brackets.
- Lesson 383 — Declaring an array with `type name[size]`Lesson 420 — Length vs Size of a string arrayLesson 423 — Getting length with `strlen`Lesson 572 — The alignof operatorLesson 576 — The aligned_alloc functionLesson 624 — Accessing members of nested structsLesson 634 — Passing struct arrays to functionsLesson 706 — The buffer size argument in fgetsLesson 727 — The size and count parametersLesson 876 — The generic signature of `qsort`Lesson 981 — Structure for dynamic arraysLesson 983 — Pushing elements and capacity checksLesson 984 — Geometric resizing with realloc
- Size - 1
- To traverse an array backwards, initialize your loop at size - 1, decrement the index, and continue until you have processed index 0.
- Lesson 386 — Accessing elements with the `[]` operatorLesson 401 — Reverse traversal of an array
- Size (sizeof)
- Size (sizeof): This tells you how much memory the array occupies.
- Lesson 423 — Getting length with `strlen`
- size < capacity
- Always verify that size < capacity before adding an element; if they are equal, you must resize the array to prevent memory corruption.
- Lesson 983 — Pushing elements and capacity checks
- size <= 1
- In our doll example, the base case is size <= 1.
- Lesson 353 — Concept of self-calling functions
- size == capacity
- When you need to resize the array, you can check if size == capacity.
- Lesson 981 — Structure for dynamic arrays
- size_t
- Always use size_t for memory sizes and uintptr_t for pointer-to-integer conversions to ensure your code runs safely on both 32-bit and 64-bit systems.
- Lesson 423 — Getting length with `strlen`Lesson 511 — Generic functions in CLesson 513 — Implementing a generic swap functionLesson 537 — The malloc function signatureLesson 612 — Naming conventions for typedef typesLesson 731 — Verifying bytes read vs expectedLesson 847 — Finding string length with `strlen`Lesson 949 — Writing code for 32-bit vs 64-bit
- size_t offset
- In an arena allocator, you typically have a large char buffer and a size_t offset that tracks where the next allocation starts.
- Lesson 589 — Handling alignment within an arena
- size_t size
- The input, size_t size, is the only information malloc asks for.
- Lesson 537 — The malloc function signature
- sizeof
- By using sizeof on the variable itself, your code becomes "portable." This means if you move your code from a small smartwatch to a powerful desktop, sizeof will automatically adjust to the correct measurements of that specific system, ensuring your program stays stable and efficient.
- Lesson 84 — Using the `sizeof` operatorLesson 235 — The `sizeof` operator with typesLesson 236 — The `sizeof` operator with variablesLesson 388 — Calculating array size with `sizeof`Lesson 389 — The relationship between array size and memoryLesson 452 — The size of a pointer variableLesson 465 — How data types affect step sizeLesson 475 — Array decay explainedLesson 538 — Calculating size with sizeofLesson 572 — The alignof operatorLesson 620 — Allocating structs on the heap with mallocLesson 637 — The sizeof operator on structsLesson 658 — Size of a union vs size of a structLesson 728 — Writing entire structs to diskLesson 729 — Reading structs back into memoryLesson 847 — Finding string length with `strlen`Lesson 856 — Copying memory with `memcpy`Lesson 868 — Allocating memory with `malloc` and `free`Lesson 876 — The generic signature of `qsort`Lesson 931 — The `sizeof` operator with complex typesLesson 944 — Sizes of `int` across different architecturesLesson 982 — Initial memory allocation with mallocLesson 1217 — Saving the data store to a binary file
- sizeof myVariable
- You might see some programmers use sizeof without parentheses when they are measuring a variable (like sizeof myVariable).
- Lesson 235 — The `sizeof` operator with types
- sizeof()
- Never assume the size of a struct is simply the sum of its parts; always use sizeof() to let the compiler tell you the truth for that specific architecture.
- Lesson 85 — Platform dependency of sizesLesson 420 — Length vs Size of a string arrayLesson 644 — Platform dependency of struct sizeLesson 647 — Restrictions on bit-field typesLesson 949 — Writing code for 32-bit vs 64-bit
- sizeof(age)
- In this code, sizeof(age) looks at the variable age, sees that it is an integer, and returns the number of bytes your system uses for integers (usually 4).
- Lesson 236 — The `sizeof` operator with variables
- sizeof(arr) / sizeof(arr[0])
- To find the number of elements in an array, divide the total size of the array by the size of its first element: sizeof(arr) / sizeof(arr[0]).
- Lesson 388 — Calculating array size with `sizeof`
- sizeof(array) / sizeof(array[0])
- By using the sizeof(array) / sizeof(array[0]) formula, your code stays flexible.
- Lesson 388 — Calculating array size with `sizeof`
- sizeof(city)
- In this example, sizeof(city) will be 20, because that is how much room you requested.
- Lesson 420 — Length vs Size of a string array
- sizeof(destination) - strlen(destination) - 1
- Always calculate your limit as sizeof(destination) - strlen(destination) - 1.
- Lesson 436 — Using `strncat` for safer concatenation
- sizeof(int)
- In C, if you want to save an array of 5 integers to a file, the "size" is the size of one integer (sizeof(int)), and the "count" is 5.
- Lesson 235 — The `sizeof` operator with typesLesson 537 — The malloc function signatureLesson 725 — Writing raw bytes with fwriteLesson 727 — The size and count parameters
- sizeof(matrix)
- If you have int matrix[5][10], sizeof(matrix) will not return 50 (the total number of integers).
- Lesson 931 — The `sizeof` operator with complex types
- sizeof(name)
- The maximum capacity: sizeof(name) tells C to read no more than 19 characters (leaving 1 spot for the null terminator \0).
- Lesson 433 — Safe input reading with `fgets`
- sizeof(numbers)
- When used with the sizeof operator: sizeof(numbers) returns the size of the entire block, not the size of a pointer.
- Lesson 475 — Array decay explained
- sizeof(Resource)
- Even though a char is 1 byte and an int is 4 bytes, sizeof(Resource) will likely return 8 bytes, not 5.
- Lesson 573 — Struct padding for alignment
- sizeof(struct Data)
- However, if you run sizeof(struct Data), you will likely see 12 bytes.
- Lesson 638 — Understanding memory alignment
- sizeof(struct FastFood)
- Even though you only defined 6 bytes of data (1 + 4 + 1), sizeof(struct FastFood) will likely return 12 bytes.
- Lesson 640 — Structure holes and performance
- sizeof(struct Node)
- Use malloc with sizeof(struct Node) to carve out space in memory for each new link in your list.
- Lesson 991 — Allocating a new node in memory
- sizeof(struct Player)
- By passing sizeof(struct Player) as the size, you tell C exactly how big one "unit" of data is.
- Lesson 727 — The size and count parameters
- sizeof(struct YourStruct)
- Use malloc with sizeof(struct YourStruct) to create persistent data on the heap, and always access its members using the arrow (->) operator.
- Lesson 620 — Allocating structs on the heap with malloc
- sizeof(struct)
- You don't usually have to manage alignment manually, but understanding it explains why sizeof(struct) is often larger than the sum of its parts.
- Lesson 643 — Alignment requirements for different typesLesson 947 — Structure padding and alignment issues
- sizeof(type)
- By using void*, we tell the compiler: "I'm going to give you a memory address, but don't worry about what type of data is stored there yet." By passing sizeof(type), we tell the function exactly how many bytes to grab.
- Lesson 235 — The `sizeof` operator with typesLesson 513 — Implementing a generic swap functionLesson 538 — Calculating size with sizeof
- sizeof(username)
- In the example above, sizeof(username) would be 20 because the array was declared with 20 slots.
- Lesson 423 — Getting length with `strlen`
- sketchbook
- Think of this like writing in a sketchbook.
- Lesson 480 — Mutable vs immutable string memory
- sleep
- After the sleep command—during which the parent has already exited—the second call to getppid() will typically return 1.
- Lesson 1079 — Handling orphaned processes
- sleep(100)
- If you removed the wait(NULL) line and told the parent to sleep(100), the child would remain a zombie for 100 seconds.
- Lesson 1078 — Preventing zombie processes
- sleep(5)
- If you put a sleep(5) command in the middle of that code, the Wall Time would increase by five seconds, but the cpu_time_used would remain almost exactly the same.
- Lesson 1184 — Understanding CPU cycles vs. Wall time
- slip of paper
- You have a slip of paper (the double pointer).
- Lesson 505 — Accessing data through double dereference
- smallBox
- Even worse, because a short usually only goes up to 32,767, assigning 40000 to it causes an overflow, resulting in smallBox becoming -25536.
- Lesson 125 — Risks of narrowing conversions
- smaller
- Right Scout: Starts at the end and moves left until it finds a value smaller than the pivot.
- Lesson 1056 — Quick Sort: Partitioning logic
- smart_print(age)
- In the code above, the compiler looks at smart_print(age).
- Lesson 977 — Type-based function overloading simulation
- snake_case
- In C, the two most common styles are snake_case (all lowercase with underscores) and camelCase (capitalizing the first letter of each word except the first).
- Lesson 74 — Naming rules and identifiersLesson 1197 — Meaningful variable naming conventions
- snprintf
- If the formatted text is too long, snprintf simply cuts it off (truncates it) and ensures the string still ends with a proper null terminator (\0).
- Lesson 704 — Safe string formatting with snprintf
- so that
- Rather than letting b start at byte 1 (which is "misaligned"), it adds three invisible bytes after a so that b starts at byte 4.
- Lesson 639 — Why the compiler adds padding bytes
- SOCK_DGRAM
- By changing AF_INET to AF_UNIX or SOCK_STREAM to SOCK_DGRAM, you completely change how your program interacts with the world without changing the rest of your logic.
- Lesson 1108 — Socket domains and typesLesson 1110 — Creating a socket with socket()
- SOCK_DGRAM (UDP)
- Think of this like sending postcards. Each packet (datagram) is independent. They might arrive out of order, or not at all. It is incredibly fast, making it perfect for video streaming or gaming where speed matters more than perfect reliability.
- Lesson 1108 — Socket domains and types
- SOCK_STREAM
- By changing AF_INET to AF_UNIX or SOCK_STREAM to SOCK_DGRAM, you completely change how your program interacts with the world without changing the rest of your logic.
- Lesson 1108 — Socket domains and typesLesson 1110 — Creating a socket with socket()
- SOCK_STREAM (TCP)
- Think of this like a phone call. You establish a dedicated connection, and data arrives in the exact order it was sent. If a packet gets lost, the system automatically asks for a retry. It is reliable but has a little bit of overhead.
- Lesson 1108 — Socket domains and types
- sockaddr
- While the operating system uses a generic structure called sockaddr for all types of communication (like Bluetooth or internal files), we use the specialized sockaddr_in specifically for IPv4 internet networking.
- Lesson 1109 — The sockaddr_in structure
- sockaddr_in
- While the operating system uses a generic structure called sockaddr for all types of communication (like Bluetooth or internal files), we use the specialized sockaddr_in specifically for IPv4 internet networking.
- Lesson 1109 — The sockaddr_in structureLesson 1111 — Binding to a port with bind()
- socket file descriptor
- Both functions require three main ingredients: the socket file descriptor (the ID of your connection), a buffer (the actual data), and the length of that data.
- Lesson 1115 — Sending and receiving over sockets
- socket()
- The socket() function initializes a network endpoint and returns a file descriptor that you will use for all future networking tasks.
- Lesson 1108 — Socket domains and typesLesson 1110 — Creating a socket with socket()Lesson 1111 — Binding to a port with bind()
- sort<T>
- They allow you to write a single function, like sort<T>, and the compiler automatically generates a new version for every data type you use.
- Lesson 978 — Comparing `_Generic` to C++ templates
- sorted
- It treats the array as two parts: a sorted section on the left and an unsorted section on the right.
- Lesson 1048 — Selection Sort: Finding the minimumLesson 1064 — Importance of sorted data
- sorting algorithms
- This is the secret sauce behind advanced C features like sorting algorithms.
- Lesson 518 — Passing functions as arguments
- source
- The function takes two arguments: the destination (where the text is going) and the source (where the text is coming from).
- Lesson 424 — Copying strings with `strcpy`
- Source Code
- The Source Code is your English recipe (your .c file).
- Lesson 6 — C as a compiled languageLesson 9 — Role of the Compiler
- Source File
- The source file (ending in .c) is the kitchen; it contains the definitions, which is the actual logic and code that performs the work.
- Lesson 15 — The concept of a Source FileLesson 382 — Sharing functions across modulesLesson 788 — The purpose of header filesLesson 824 — Incremental builds and file timestamps
- Source file (.c)
- The Source file (.c) is the chef in the kitchen.
- Lesson 796 — Splitting code into `.c` and `.h`
- Source Files
- To stay organized, C programmers split code into two specific types of files: Source files (.c) and Header files (.h).
- Lesson 378 — Separating interface from implementationLesson 796 — Splitting code into `.c` and `.h`
- spaghetti code
- This is why programmers call messy, unorganized logic spaghetti code.
- Lesson 311 — The dangers of 'spaghetti code'
- specifier (like
- Add a number inside your % specifier (like %10d) to set a minimum width, creating "invisible columns" for clean, professional output.
- Lesson 685 — Specifying field width for alignment
- speed
- In the example above, if emergency_system() runs, every other function using speed is suddenly affected.
- Lesson 142 — The dangers of global variablesLesson 583 — Allocation strategies: First-fit
- sprintf
- sprintf allows you to format text and store the result in a string variable for later use, rather than sending it directly to the output console.
- Lesson 703 — Formatting strings in memory with sprintfLesson 704 — Safe string formatting with snprintf
- sqrt
- Before calling a library function (like strtol or sqrt), wipe the slate clean.
- Lesson 900 — Resetting `errno` before library calls
- sqrt()
- If you try to pass a negative value to sqrt(), your program might return "NaN" (Not a Number).
- Lesson 861 — Basic power and square root: `pow` and `sqrt`
- sqrt(16.0)
- It asks the question: "What number, multiplied by itself, gives me this value?" For example, sqrt(16.0) will return 4.0.
- Lesson 861 — Basic power and square root: `pow` and `sqrt`
- sqrt(x)
- Use pow(x, y) for exponents and sqrt(x) for square roots, ensuring you include <math.h> and use double data types for precision.
- Lesson 861 — Basic power and square root: `pow` and `sqrt`
- square
- It feels like extra work now, but unit tests are your "safety net." If you decide to optimize your square function later to make it faster, you can re-run your tests instantly.
- Lesson 347 — What is a Stack Frame?Lesson 348 — Pushing and popping framesLesson 1172 — Principles of Unit Testing
- square_double()
- You end up writing square_int(), square_float(), and square_double().
- Lesson 973 — Introduction to the `_Generic` keyword
- square_float()
- You end up writing square_int(), square_float(), and square_double().
- Lesson 973 — Introduction to the `_Generic` keyword
- square_int()
- You end up writing square_int(), square_float(), and square_double().
- Lesson 973 — Introduction to the `_Generic` keyword
- square()
- Once square() finishes, its frame—and every variable inside it—is "popped" and gone forever.
- Lesson 348 — Pushing and popping frames
- SQUARE(++i)
- If you pass it something weird—like a variable with a side effect (SQUARE(++i))—the stamp repeats that side effect twice, often breaking your logic.
- Lesson 778 — Macros vs inline functions
- SQUARE(2 + 2)
- Because macros are just text substitution, they can be "tricky." If you defined it as #define SQUARE(x) x x and then wrote SQUARE(2 + 2), the preprocessor would give you 2 + 2 2 + 2.
- Lesson 772 — Defining function-like macros
- SQUARE(a++)
- However, the preprocessor expands SQUARE(a++) into ((a++) * (a++)).
- Lesson 775 — Side effects in macro arguments
- square(x)
- When square(x) is called, the computer pauses main and creates a new frame for square.
- Lesson 347 — What is a Stack Frame?
- srand()
- If we give srand() a different number every time the program starts, rand() will start at a different point in its list, giving us a different result.
- Lesson 885 — Seeding the generator with `srand`Lesson 886 — Why you should only seed onceLesson 888 — Getting a unique seed with `time(NULL)`
- srand(1)
- If you write srand(1);, your game or simulation will be identical every single time it starts.
- Lesson 888 — Getting a unique seed with `time(NULL)`
- srand(time(NULL))
- When you call srand(time(NULL)), you are telling the computer: "Look at the clock, take the current second, and use that number to scramble the starting point of your random formula."
- Lesson 885 — Seeding the generator with `srand`Lesson 886 — Why you should only seed onceLesson 888 — Getting a unique seed with `time(NULL)`
- src
- You might have a src folder for your code and an include folder for your headers.
- Lesson 63 — Header search paths
- src/main.c
- Here is how the top of src/main.c would look:
- Lesson 800 — Organizing /src and /include folders
- sscanf
- A common "best practice" is to read an entire line of input into a string first (using a function like fgets), validate that the string isn't empty or broken, and then use sscanf to parse the actual data.
- Lesson 705 — Parsing data from strings with sscanf
- St
- The name stands for Standard Input/Output, and the .h indicates it is a "header" file.
- Lesson 18 — The `#include` directiveLesson 678 — The header file <stdio.h>
- ST_RED
- Now the "living room" has a TL_RED lamp and an ST_RED lamp, and the compiler can easily tell them apart.
- Lesson 666 — Scoped enum limitations in C
- stability
- For professional developers, C17 is actually one of the most important versions because it represents stability.
- Lesson 968 — C17: The bug-fix standard
- stable
- A stable sorting algorithm guarantees that if two items have the same key (the value you are sorting by), their relative order remains unchanged.
- Lesson 1052 — Stability in sorting algorithms
- Stack
- An interesting feature of this layout is that the Stack and the Heap usually grow toward each other from opposite ends of the available memory space.
- Lesson 149 — Memory segments: Stack vs. DataLesson 529 — Automatic storage duration on the stackLesson 530 — Stack frame lifecycle and local variablesLesson 531 — Understanding stack overflowLesson 532 — Introduction to the Heap segmentLesson 534 — Scope of heap-allocated dataLesson 535 — Stack pointers vs Heap pointersLesson 1006 — Stack abstract data type conceptLesson 1070 — The process memory layoutLesson 1192 — Preferring stack allocation over heap
- Stack Frame
- When a function is called, C carves out a tiny, temporary slice of memory called a Stack Frame.
- Lesson 342 — Memory allocation for parametersLesson 349 — Storage of local variablesLesson 454 — Introduction to the stack frameLesson 530 — Stack frame lifecycle and local variables
- Stack Overflow
- In programming, this "spill" is a Stack Overflow, and it almost always results in your program crashing instantly with a "Segmentation Fault."
- Lesson 352 — Identifying a Stack OverflowLesson 358 — Iteration vs. Recursion comparisonLesson 359 — The call stack in recursionLesson 362 — Tail call optimization basicsLesson 364 — When to avoid recursionLesson 531 — Understanding stack overflowLesson 1012 — Handling Stack Overflow
- stack trace
- Below that, Valgrind provides a stack trace, showing the specific function and line number where the trespass occurred.
- Lesson 568 — Finding invalid reads and writes
- Stack Underflow
- A Stack Underflow occurs when your code calls a pop operation (removing the top item) on a stack that contains no data.
- Lesson 1013 — Handling Stack Underflow
- stack[-1]
- Without the if (isEmpty()) check, the line stack[top] would try to access stack[-1].
- Lesson 1013 — Handling Stack Underflow
- stack[top]
- Without the if (isEmpty()) check, the line stack[top] would try to access stack[-1].
- Lesson 1013 — Handling Stack Underflow
- Standard Headers
- When we want to use tools that are built into the C language itself (like the ability to print text to the screen), we use Standard Headers.
- Lesson 765 — The `#include` directive for standard headersLesson 795 — Standard header search paths
- Standard Input
- The name stands for "get character." It is the simplest way to interact with the Standard Input (stdin), which is usually your keyboard.
- Lesson 680 — Basic character input with getchar
- Standard Input and Output
- The name looks a bit cryptic, but it is just shorthand for Standard Input and Output.
- Lesson 41 — The `stdio.h` library
- Standard Libraries
- The Linker searches through Standard Libraries (pre-written collections of code) to find the implementation of printf.
- Lesson 28 — Phase 4: The Linker
- standard output
- The name putchar stands for "put character." It takes exactly one character and sends it to the standard output (usually your monitor).
- Lesson 679 — Basic character output with putchar
- Standards
- In programming, these updates are called Standards.
- Lesson 4 — Standards: ANSI C vs C99 vs C11
- Starship
- If you define the Pilot struct first, the compiler will complain because it hasn't seen the Starship struct yet.
- Lesson 628 — Forward declarations of structs
- start
- We swap the characters at these positions using a temporary variable, increment start, decrement end, and repeat until they cross paths.
- Lesson 20 — The `main()` function entry pointLesson 440 — Reversing an array in placeLesson 441 — Reversing a string in placeLesson 836 — Using `watch` for memory changes
- start < end
- In the code above, the condition start < end is vital.
- Lesson 442 — Checking if a string is a palindrome
- Start at the identifier
- Start at the identifier and say its name.
- Lesson 926 — Reading declarations with the 'Right-Left' rule
- starting rule
- While sizeof tells you the size, alignof tells you the starting rule.
- Lesson 572 — The alignof operator
- State
- Instead, think of printf() as leaving a trail of breadcrumbs that tell you two specific things: State and Flow.
- Lesson 1157 — Strategic `printf()` debugging
- statement
- In programming terms, we call a single instruction a statement.
- Lesson 22 — Semicolons as statement terminators
- statement would look for a
- Without the !, the if statement would look for a true value and skip the warning.
- Lesson 249 — Logical NOT (!) for inversion
- static
- Usually, if a function is meant to be private, we use other tools (like the static keyword), but understanding scope helps you debug why the compiler might insist a function doesn't exist even though you clearly wrote it elsewhere!
- Lesson 139 — Lifetime vs. ScopeLesson 144 — Static local variablesLesson 145 — Persisting data between function callsLesson 148 — Default initialization of static variablesLesson 149 — Memory segments: Stack vs. DataLesson 333 — Scope of function declarationsLesson 368 — Inline functions in header filesLesson 529 — Automatic storage duration on the stackLesson 580 — Managing a static memory poolLesson 798 — Static functions for file scopingLesson 809 — Symbol tables and visibilityLesson 918 — Internal vs external linkage basicsLesson 919 — The `static` keyword in global scopeLesson 920 — The `static` keyword inside functionsLesson 923 — Storage class specifier precedenceLesson 924 — The `register` keyword and its modern relevanceLesson 1070 — The process memory layout
- static char
- static char becomes '\0' (the null character)
- Lesson 148 — Default initialization of static variables
- static inline
- If you put a massive, complex function as a static inline in a header, your final program size will bloat because that massive code block is being duplicated everywhere you use it.
- Lesson 368 — Inline functions in header files
- static library
- In C programming, a static library (ending in .a for "archive" on Linux/macOS or .lib on Windows) is that toolbox.
- Lesson 810 — What is a static library `.a`Lesson 812 — Linking with static librariesLesson 813 — What is a shared library `.so` / `.dll`
- static memory pool
- A static memory pool is like a buffet tray already sitting on your table.
- Lesson 580 — Managing a static memory pool
- statically typed
- C is a statically typed language, which means it is very picky about the "shape" of the data you pass in.
- Lesson 338 — Type checking in function calls
- status
- If we removed volatile from the code above, a high-level optimization might see while (status == 0) and think: "Since status is 0 and nothing in this loop changes it, I'll just treat this as while (true)." Your program would then hang forever, even if the memory at the status address changed to 1.
- Lesson 165 — Common pitfall: `=` vs `==`Lesson 914 — How `volatile` prevents compiler optimizationLesson 1197 — Meaningful variable naming conventions
- status = status | mask
- Using status |= mask instead of status = status | mask makes your code cleaner and reduces the chance of typos, especially when your variable names are long (like player_attribute_flags).
- Lesson 195 — Compound bitwise assignments
- status |= mask
- Using status |= mask instead of status = status | mask makes your code cleaner and reduces the chance of typos, especially when your variable names are long (like player_attribute_flags).
- Lesson 195 — Compound bitwise assignments
- status.dayOfWeek
- You can treat status.dayOfWeek just like a normal variable in your code, but if you try to assign the number 10 to it, it will overflow because 10 (binary 1010) requires 4 bits, and you only allocated 3.
- Lesson 648 — The colon operator and bit width
- std::vector
- When you use a dynamic array (like a std::vector in C++ or your own malloc implementation), you eventually run out of space.
- Lesson 985 — Amortized time complexity
- stdarg.h
- Variadic functions use ... and the stdarg.h library to accept any number of arguments, provided you have at least one fixed parameter to start the process.
- Lesson 371 — Functions with unknown argumentsLesson 372 — The `stdarg.h` libraryLesson 376 — How `printf` works internally
- stderr
- C uses stdin for input, stdout for normal output, and stderr for error messages to keep communication organized and separable.
- Lesson 677 — Introduction to stdin, stdout, and stderrLesson 750 — Unbuffered output (stderr)Lesson 761 — Standard stream redirection in shells
- STDERR_FILENO
- In C, these streams are represented by the constants STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO.
- Lesson 1093 — Standard streams (0, 1, 2)
- stdin
- The freopen function redirects a standard stream (like stdin or stdout) to a file, allowing standard functions like scanf and printf to read from or write to files automatically.
- Lesson 433 — Safe input reading with `fgets`Lesson 677 — Introduction to stdin, stdout, and stderrLesson 701 — Reading safe strings with fgetsLesson 760 — Redirecting streams with freopenLesson 761 — Standard stream redirection in shells
- STDIN_FILENO
- In C, these streams are represented by the constants STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO.
- Lesson 1093 — Standard streams (0, 1, 2)
- stdint.h
- Use limits.h to check the boundaries of standard types and stdint.h to define variables with specific size requirements, ensuring your code runs safely on everything from a toaster to a supercomputer.
- Lesson 942 — Limits of `limits.h` and `stdint.h`
- stdio
- When you run this code, the computer enters the "Front Door" (main), grabs the "Printer" (stdio), shouts your message to the screen, and then closes the shop (return 0).
- Lesson 17 — The 'Hello World' code
- stdio.h
- You might write a perfect program, but because you are using a standard library (like stdio.h) or a graphics library (like SDL), Valgrind might flag memory management patterns inside those pre-compiled files.
- Lesson 19 — What is a Header File?Lesson 25 — Phase 1: The PreprocessorLesson 41 — The `stdio.h` libraryLesson 382 — Sharing functions across modulesLesson 570 — Suppressing known tool warningsLesson 764 — What the preprocessor actually doesLesson 765 — The `#include` directive for standard headersLesson 767 — How `gcc -E` shows preprocessor output
- stdlib.h
- The functions defined in stdlib.h—primarily malloc, calloc, realloc, and free—act as the bridge between your code and the computer's Operating System.
- Lesson 536 — Header file stdlib.h for allocation
- stdout
- While it also points to your terminal screen by default, it is kept separate from stdout so that you can record your program’s actual results to a file while still seeing error messages pop up on the screen.
- Lesson 676 — The concept of a stream in CLesson 677 — Introduction to stdin, stdout, and stderrLesson 748 — How C buffers I/O for speedLesson 749 — Full buffering vs Line bufferingLesson 750 — Unbuffered output (stderr)Lesson 751 — Forcing a write with fflushLesson 753 — The setbuf shorthandLesson 755 — When to use fflush(stdout)Lesson 760 — Redirecting streams with freopenLesson 761 — Standard stream redirection in shellsLesson 1093 — Standard streams (0, 1, 2)Lesson 1158 — Flushing `stdout` for accurate logs
- STDOUT_FILENO
- In C, these streams are represented by the constants STDIN_FILENO, STDOUT_FILENO, and STDERR_FILENO.
- Lesson 1093 — Standard streams (0, 1, 2)
- step
- Using the recipe analogy, if the instruction says "Make the secret sauce," and you use step, you are now looking at a separate page that explains how to mix the mayo, mustard, and spices.
- Lesson 830 — Stepping through code with `next` and `step`
- Step Over
- Click Step Over, and you’ll see sum instantly change to 1.
- Lesson 1162 — Setting breakpoints and stepping through code
- sticky note
- When you open an envelope and follow that address, you find a sticky note with a word written on it (that’s the second pointer, leading to a character).
- Lesson 506 — Command line arguments `char **argv`
- stone tablet
- A const variable is more like a stone tablet.
- Lesson 910 — The `const` qualifier on variables
- str
- mem functions outperform str functions because they skip the "null-terminator check" and allow the CPU to move data in large, optimized chunks.
- Lesson 847 — Finding string length with `strlen`Lesson 860 — Performance differences between `str` and `mem` functions
- str_utils.c
- Let's say you have two utility files, math_utils.c and str_utils.c.
- Lesson 811 — Creating archives with the `ar` tool
- str2 = str1
- If you have char str1[] = "Hello"; and char str2[10];, writing str2 = str1; will cause a compiler error.
- Lesson 424 — Copying strings with `strcpy`
- strcat
- What you'll learn: How to join two strings together by appending the contents of one to the end of another using the strcat function.
- Lesson 425 — Concatenating strings with `strcat`Lesson 436 — Using `strncat` for safer concatenationLesson 849 — Concatenating strings with `strncat`
- strchr
- Use strchr to find the memory address of the first occurrence of a character, returning NULL if the character doesn't exist.
- Lesson 427 — Searching for characters with `strchr`Lesson 851 — Searching for characters with `strchr` and `strrchr`Lesson 859 — Searching memory bytes with `memchr`
- strcmp
- This is because strcmp expects to receive the strings themselves, but qsort is stubbornly handing it the address where the string pointer is stored.
- Lesson 426 — Comparing strings with `strcmp`Lesson 850 — Lexicographical comparison with `strcmp`Lesson 854 — Understanding the `strcoll` and `strxfrm` locale functionsLesson 858 — Comparing memory blocks with `memcmp`Lesson 860 — Performance differences between `str` and `mem` functionsLesson 878 — Writing a string comparison function for `qsort`Lesson 879 — Sorting structs by multiple fieldsLesson 1208 — Adding command line flags (e.g., `-i` for case)Lesson 1215 — Writing the Search function
- strcmp()
- When searching for strings instead of integers, remember to use strcmp() from the <string.h> library rather than ==, but the logic of looping through the array remains identical.
- Lesson 636 — Searching through struct arrays
- strcoll
- Use strcoll for accurate, language-sensitive comparisons, and use strxfrm to pre-process strings for high-performance sorting in global applications.
- Lesson 854 — Understanding the `strcoll` and `strxfrm` locale functions
- strcpy
- If the source is too long, strcpy will keep writing data into memory it doesn't own, causing a "buffer overflow." This often leads to program crashes or serious security vulnerabilities.
- Lesson 424 — Copying strings with `strcpy`Lesson 435 — Using `strncpy` for safer copyingLesson 561 — Heap buffer overflowsLesson 848 — Copying strings safely with `strncpy`Lesson 860 — Performance differences between `str` and `mem` functions
- strcspn
- If the user types a very long string that fills the buffer without a newline, strcspn will simply return the index of the existing null terminator, and you'll be replacing a \0 with a \0—which does no harm!
- Lesson 434 — Removing newlines from `fgets` resultsLesson 702 — Removing the newline from fgets
- strdup
- However, if your struct contains pointers to other blocks of memory (like a string created with strdup or another dynamic array), the struct becomes like a Russian nesting doll.
- Lesson 621 — Freeing dynamically allocated structs
- streams
- In C, these pathways are called streams.
- Lesson 677 — Introduction to stdin, stdout, and stderr
- street address for a recipe
- Think of a function name as a street address for a recipe.
- Lesson 515 — Taking the address of a function
- strength
- When levelUp(heroStrength) is called, the value 50 is plucked out of main's memory and pasted into a new memory location labeled strength inside levelUp.
- Lesson 344 — Visualizing the stack frame copy
- strerror
- Just read it, print it, or copy it if you need to save it for later, as subsequent calls to strerror might overwrite the buffer in some implementations.
- Lesson 740 — Introduction to errnoLesson 742 — The strerror functionLesson 899 — Getting error strings with `strerror`
- strerror(errno)
- Use strerror(errno) to turn confusing numeric system errors into readable strings that tell you exactly what went wrong.
- Lesson 742 — The strerror functionLesson 899 — Getting error strings with `strerror`
- strftime
- Instead of building strings by hand, we use strftime (short for "string format time"), which works much like printf but uses specific codes for dates.
- Lesson 894 — Formatting time strings with `strftime`
- Strict Aliasing
- Modern C compilers use a rule called Strict Aliasing.
- Lesson 527 — Pointer type-punning dangers
- Strict Aliasing Rule
- In C, the Strict Aliasing Rule is that same assumption for the compiler.
- Lesson 936 — Strict aliasing rule violations
- Strict Weak Ordering
- To keep the "scale" balanced, your logic must follow Strict Weak Ordering.
- Lesson 882 — Common pitfalls in comparison function logic
- string
- You might be tempted to switch on a float (like 3.14) or a string (like "Apple").
- Lesson 53 — The `%s` specifier for stringsLesson 262 — Switch restrictions: integral types onlyLesson 613 — Typedef vs. #define macrosLesson 705 — Parsing data from strings with sscanfLesson 1204 — Project scope: A custom `grep` clone
- string literal
- To make life easier, C provides a shorthand: the string literal.
- Lesson 416 — Defining strings with double quotes
- string manipulation
- By limiting the scope to an array of structs, you focus on the most important C concepts: string manipulation (copying names into the keys), looping (searching for a specific key), and memory layout.
- Lesson 1212 — Project scope: A simple Key-Value store
- string_utils.c
- When you write code, you often split functions into different files (e.g., math_utils.c, string_utils.c).
- Lesson 810 — What is a static library `.a`
- string.h
- Use strstr() from string.h to quickly locate a substring within a larger string, checking for NULL to determine if the search failed.
- Lesson 1207 — Implementing string pattern matching
- string[0]
- The Risk: If your logic assumes string[0] is always a letter, or if you use a loop that skips the check for the null terminator, your program might read past the end of the intended memory.
- Lesson 1179 — Edge case testing: Empty strings and zeros
- strings
- Double quotes are used for strings (sequences of characters).
- Lesson 107 — Single quotes vs. double quotes
- strlen
- It is important to remember one crucial rule: strlen does not count the null terminator. If your string is "Cat", strlen returns 3, even though the computer is technically using 4 bytes of memory to store it (C, a, t, and \0).
- Lesson 423 — Getting length with `strlen`Lesson 847 — Finding string length with `strlen`Lesson 1193 — Avoiding redundant calculations in loops
- strlen()
- Use strlen() from <string.h> to find the number of visible characters in a string, excluding the null terminator.
- Lesson 420 — Length vs Size of a string arrayLesson 423 — Getting length with `strlen`
- strlen(city)
- However, strlen(city) will be 5, because "Tokyo" only occupies five slots.
- Lesson 420 — Length vs Size of a string array
- strncat
- To use strncat safely, you must tell it exactly how many slots are remaining in your array, minus one (to leave room for the invisible \0 null terminator that marks the end of a string).
- Lesson 436 — Using `strncat` for safer concatenationLesson 849 — Concatenating strings with `strncat`
- strncpy
- The strncpy function has a specific quirk you must remember: if the source string is longer than the limit you set, strncpy will fill the destination buffer but will not add the null terminator (\0) at the end.
- Lesson 435 — Using `strncpy` for safer copyingLesson 848 — Copying strings safely with `strncpy`
- strrchr
- The strrchr function (the extra 'r' stands for "reverse") works identically, but it starts scanning from the end of the string and moves backward.
- Lesson 851 — Searching for characters with `strchr` and `strrchr`
- strstr
- Whether you are filtering a list of names, checking if an email address contains an "@" symbol, or scanning a file for a specific keyword, strstr is your primary tool for scanning text data efficiently.
- Lesson 428 — Searching for substrings with `strstr`Lesson 852 — Finding substrings with `strstr`Lesson 1204 — Project scope: A custom `grep` clone
- strstr()
- Use strstr() from string.h to quickly locate a substring within a larger string, checking for NULL to determine if the search failed.
- Lesson 1207 — Implementing string pattern matching
- strtod
- Imagine a librarian reading a sentence: "The price is 49.99 dollars." If you ask them to find the number, they stop at the "d" in "dollars." strtod gives you that exact location so you can check if the conversion actually finished the whole string or got stuck on garbage text.
- Lesson 873 — Converting strings to doubles with `strtod`
- strtok
- When strtok finds that character, it replaces it with a null terminator (\0), effectively ending the string right there and returning a pointer to the start of that "token."
- Lesson 429 — Tokenizing strings with `strtok`Lesson 853 — Tokenizing strings with `strtok`
- strtol
- By setting errno = 0 right before strtol, you guarantee that if errno is non-zero afterward, it was definitely caused by that specific line of code.
- Lesson 872 — Robust string-to-number conversion with `strtol`Lesson 900 — Resetting `errno` before library calls
- struct
- To make a struct refer to itself, we have to use a "struct tag." Usually, we might use typedef to skip writing the word struct, but because the compiler needs to know about the pointer inside the definition, we must name the struct explicitly.
- Lesson 491 — Efficiency of passing large structs by pointerLesson 509 — Casting `void *` to specific typesLesson 511 — Generic functions in CLesson 512 — The `memcpy` function signatureLesson 567 — Identifying 'indirectly lost' memoryLesson 573 — Struct padding for alignmentLesson 577 — Using __attribute__((packed))Lesson 593 — Using mmap for large allocationsLesson 599 — Defining a struct with the struct keywordLesson 600 — Declaring struct variablesLesson 601 — The dot operator for member accessLesson 602 — Initializing structs with brace notationLesson 606 — Returning a struct from a functionLesson 607 — The syntax of typedefLesson 609 — Creating a shorthand for struct namesLesson 610 — Combining struct definition and typedefLesson 611 — Anonymous structs with typedefLesson 614 — Improving code readability with typedefLesson 615 — Declaring a pointer to a structLesson 618 — Passing struct pointers to functionsLesson 619 — Modifying struct members via pointersLesson 623 — Defining a struct inside another structLesson 626 — Self-referential structs for linked listsLesson 627 — Limitations of self-referential definitionsLesson 630 — Declaring an array of structsLesson 631 — Initializing arrays of structsLesson 636 — Searching through struct arraysLesson 637 — The sizeof operator on structsLesson 638 — Understanding memory alignmentLesson 640 — Structure holes and performanceLesson 641 — Reordering members to reduce paddingLesson 643 — Alignment requirements for different typesLesson 644 — Platform dependency of struct sizeLesson 645 — Purpose of bit-fields in memory-constrained systemsLesson 646 — Syntax for declaring bit-fieldsLesson 648 — The colon operator and bit widthLesson 653 — Defining a union with the union keywordLesson 654 — Memory layout of a unionLesson 655 — Accessing union membersLesson 656 — Overlapping memory in unionsLesson 658 — Size of a union vs size of a structLesson 669 — Tagged unions for type safetyLesson 670 — Combining structs and unionsLesson 729 — Reading structs back into memoryLesson 789 — The 'duplicate definition' errorLesson 947 — Structure padding and alignment issuesLesson 948 — The `#pragma pack` directiveLesson 949 — Writing code for 32-bit vs 64-bitLesson 954 — Bit-fields in structures and portabilityLesson 976 — Handling the `default` case in `_Generic`
- struct Enemy
- You cannot assign a struct Enemy to a struct Player, even if they have the same internal members.
- Lesson 604 — Copying structs with the assignment operator
- struct Name
- To create a forward declaration, you simply write struct Name; on its own line before your actual definitions.
- Lesson 609 — Creating a shorthand for struct namesLesson 628 — Forward declarations of structs
- struct NavigationSatellite
- If you defined a struct NavigationSatellite, you would have to type struct NavigationSatellite mySat; to declare a variable.
- Lesson 614 — Improving code readability with typedef
- struct NavigationSatellite mySat
- If you defined a struct NavigationSatellite, you would have to type struct NavigationSatellite mySat; to declare a variable.
- Lesson 614 — Improving code readability with typedef
- struct Node
- If a struct Node contains a struct Node member, the compiler calculates the size as: "Size of an integer + Size of a Node." But to find the size of that "Node," it needs to add "Size of an integer + Size of a Node" again.
- Lesson 567 — Identifying 'indirectly lost' memoryLesson 627 — Limitations of self-referential definitionsLesson 989 — Defining the self-referential node structLesson 1022 — Recursive tree node structure
- struct Node *next
- In this example, struct Node *next is the magic ingredient.
- Lesson 626 — Self-referential structs for linked lists
- struct Node*
- Notice the struct Node* syntax inside the definition.
- Lesson 1022 — Recursive tree node structure
- struct Node* head
- Declaring struct Node* head; without setting it to NULL is dangerous.
- Lesson 990 — Creating the head pointer
- struct Node* prev
- Adding struct Node* prev; might seem like a small change, but it is powerful.
- Lesson 999 — Updating the node struct
- struct Player
- When you use a standard struct name (like struct Player), you are telling the compiler about a "tag." When you use typedef, you are creating a new name in the global type list.
- Lesson 599 — Defining a struct with the struct keywordLesson 600 — Declaring struct variablesLesson 604 — Copying structs with the assignment operatorLesson 611 — Anonymous structs with typedefLesson 615 — Declaring a pointer to a structLesson 791 — How `#pragma once` works
- struct Player *ptr
- In the code above, struct Player *ptr tells the compiler: "I am creating a variable named ptr that is designed to point to a memory location where a struct Player is stored."
- Lesson 615 — Declaring a pointer to a struct
- struct Player hero = {'B'}
- For example, if you wrote struct Player hero = {'B'};, the grade becomes 'B', but the score and health are automatically set to 0 and 0.0.
- Lesson 602 — Initializing structs with brace notation
- struct Player p1
- When you write struct Player p1; inside a function, that memory is carved out of the "stack." The moment that function finishes, p1 is destroyed.
- Lesson 620 — Allocating structs on the heap with malloc
- struct Player player1
- If you declare struct Player player1; inside the main() function, only main can see it.
- Lesson 600 — Declaring struct variables
- struct Player*
- It is the ultimate shapeshifter; C allows it to be automatically converted into any other pointer type (like int or struct Player) without a complaint from the compiler.
- Lesson 540 — Casting malloc return in C vs C++
- struct Point
- When we combine typedef with a struct, we tell C: "From now on, whenever I say Point, I mean struct Point."
- Lesson 609 — Creating a shorthand for struct namesLesson 632 — Indexing into a struct array
- struct Point p
- Point p; is much easier to scan visually than struct Point p;.
- Lesson 614 — Improving code readability with typedef
- struct Point p1
- In the previous lesson, you learned that every time you want to use a struct, you have to lug around the struct keyword, like writing struct Point p1;.
- Lesson 611 — Anonymous structs with typedef
- struct Point path[] =
- Furthermore, if you leave the array size empty (e.g., struct Point path[] = ...), C will automatically count the number of initialized blocks you provided and set the array size for you.
- Lesson 631 — Initializing arrays of structs
- struct SpaceShip
- Because qsort doesn't know if you are sorting ints or struct SpaceShips, it treats your array as a raw block of memory.
- Lesson 876 — The generic signature of `qsort`
- struct Starship *ship
- Because a pointer (like struct Starship *ship) is always the same size in memory regardless of what it points to, the compiler doesn't need the full details of the struct to proceed—it just needs to know that the name represents a structure.
- Lesson 628 — Forward declarations of structs
- struct Student
- Inside that function, we cast those pointers back to struct Student so we can access the .grade member.
- Lesson 635 — Sorting an array of structs
- struct Student classroom[100]
- When you declare struct Student classroom[100], C sets aside a large "apartment building" of memory.
- Lesson 630 — Declaring an array of structs
- struct Task
- That function takes an int and returns a pointer to a struct Task.
- Lesson 930 — Complex nested `typedef` structures
- struct Task (ptr)(int)
- Self-documentation: The name Handler tells the next programmer what that function's purpose is, which the raw syntax struct Task (ptr)(int) fails to do.
- Lesson 930 — Complex nested `typedef` structures
- struct tm
- The localtime() function is your "sorter." It takes that raw number and breaks it down into a struct tm, which contains separate variables for years, months, days, hours, and minutes.
- Lesson 891 — Breaking down time with `struct tm`Lesson 892 — Converting `time_t` to local time with `localtime`Lesson 893 — Converting `time_t` to UTC with `gmtime`Lesson 894 — Formatting time strings with `strftime`Lesson 895 — Converting `struct tm` back to `time_t` with `mktime`
- struct TransactionRecord
- Writing struct UserNode or struct TransactionRecord repeatedly adds "visual noise" to your code.
- Lesson 610 — Combining struct definition and typedef
- struct User user1
- Normally, every time you want to create a variable from a structure, you have to type the word struct before the name (e.g., struct User user1;).
- Lesson 607 — The syntax of typedef
- struct UserNode
- Writing struct UserNode or struct TransactionRecord repeatedly adds "visual noise" to your code.
- Lesson 610 — Combining struct definition and typedef
- structs
- Imagine your data store is a long shelf of identical boxes (an array of structs).
- Lesson 1217 — Saving the data store to a binary file
- structured parking lot
- Think of a 2D char array as a structured parking lot.
- Lesson 483 — Array of strings vs 2D char array
- strxfrm
- Use strcoll for accurate, language-sensitive comparisons, and use strxfrm to pre-process strings for high-performance sorting in global applications.
- Lesson 854 — Understanding the `strcoll` and `strxfrm` locale functions
- Student
- You aren't limited to numbers; you can write comparators that sort a list of Student structs by GPA, or sort strings by their length rather than their alphabetical order.
- Lesson 239 — Member access `.` and `->`Lesson 630 — Declaring an array of structsLesson 632 — Indexing into a struct arrayLesson 635 — Sorting an array of structsLesson 1060 — Writing a custom comparator for qsort
- Student s1
- If you have a variable Student s1;, you are holding the physical folder.
- Lesson 239 — Member access `.` and `->`
- studentA
- If the function returns a negative number, studentA comes first.
- Lesson 635 — Sorting an array of structs
- studentB
- If it returns a positive number, studentB comes first.
- Lesson 635 — Sorting an array of structs
- students[2]
- Identify the item: Use the index (e.g., students[2]) to pick which specific struct you want to talk to.
- Lesson 632 — Indexing into a struct array
- style guide
- A style guide is simply a shared agreement on how the "house" should be organized.
- Lesson 40 — C coding style guides
- suffix
- To use a long double, you need to pay attention to two specific details: the suffix and the format specifier.
- Lesson 99 — The `long double` type
- sum
- If the sum jumped from 10 to 1000 unexpectedly, you would know the error happened exactly during that iteration.
- Lesson 403 — Calculating the sum and averageLesson 1162 — Setting breakpoints and stepping through codeLesson 1163 — Inspecting variable values at runtime
- sum += i
- If your output is unexpected, you can set a breakpoint on the sum += i; line.
- Lesson 1162 — Setting breakpoints and stepping through code
- SUNDAY
- For instance, if you have an enum for MONDAY through SUNDAY, MONDAY will be 0 and SUNDAY will be 6.
- Lesson 662 — Default integer values in enums
- suppression file
- Valgrind allows you to create a "hush list" called a suppression file (usually ending in .supp).
- Lesson 570 — Suppressing known tool warnings
- swap
- Without pointers, the swap function would only swap copies of x and y.
- Lesson 490 — Swapping two numbers using pointers
- switch
- While you could use a series of if statements, the switch tells anyone reading your code: "I am looking for one specific value among these known constants." It makes your logic organized, readable, and slightly more efficient for the computer to process.
- Lesson 210 — Ternary vs If-Else for assignmentsLesson 258 — Basic switch syntax and casesLesson 259 — The role of the break statement in switchLesson 260 — The default case for unhandled valuesLesson 261 — Fall-through behavior: intentional and accidentalLesson 262 — Switch restrictions: integral types onlyLesson 263 — Grouping multiple cases into one blockLesson 264 — Comparing switch-case vs else-if laddersLesson 265 — Switch statement best practicesLesson 517 — Arrays of function pointersLesson 665 — Using enums in switch statementsLesson 668 — Using enums for state machinesLesson 973 — Introduction to the `_Generic` keywordLesson 974 — The syntax of a generic selectionLesson 976 — Handling the `default` case in `_Generic`Lesson 1151 — Handling the 'Default' case in switch statements
- switch statement
- You should use a switch statement when you are comparing one single variable against a list of constant values (like integers or characters).
- Lesson 264 — Comparing switch-case vs else-if ladders
- switch(gear)
- The Expression: Inside switch(gear), C looks at the value stored in the variable.
- Lesson 258 — Basic switch syntax and cases
- symbol table
- During this process, the compiler creates a symbol table.
- Lesson 809 — Symbol tables and visibility
- Symbolic Constant
- A Symbolic Constant is a way to give that literal value a meaningful name.
- Lesson 118 — Literal vs. Symbolic constants
- symbolic constants
- We call these macros or symbolic constants.
- Lesson 768 — Defining constants with `#define`
- System Call
- This is called a System Call, and it is "expensive" in terms of time and processing power.
- Lesson 754 — Performance: Single char vs block I/O
- System Paths
- #include <stdio.h>: The angle brackets tell the compiler to look in System Paths (the "Standard Library" section of the library).
- Lesson 63 — Header search paths
- system("clear")
- If you are writing a library that opens a database connection or a log file, you don't want a user's random system("clear") call to inherit your private database handle.
- Lesson 1096 — The close-on-exec flag
- system("dir")
- First, it is "platform dependent"—a program using system("dir") will crash or fail on a Mac, which expects ls.
- Lesson 874 — Communicating with the OS using `system`
- system()
- The system() function is a quick way to run terminal commands from your code, acting as a bridge between your program and the operating system.
- Lesson 874 — Communicating with the OS using `system`
- systemd
- The child becomes an "orphan." In modern systems, the system adopts these orphans, usually reassigning them to a special system process (like systemd or init) which has a PID of 1.
- Lesson 1069 — Parent processes and getppid()
T
- Tab
- But when you want to indent a line or create a list of data that lines up vertically, you reach for the Tab key on the left side of your keyboard.
- Lesson 45 — Horizontal tab `\t`Lesson 61 — Introduction to `make` and MakefilesLesson 108 — Escape sequences like `\n` and `\t`Lesson 818 — Structure of a Makefile RuleLesson 819 — Targets, dependencies, and recipes
- Tab character
- Make requires that every line in a recipe begins with a Tab character.
- Lesson 820 — The importance of Tab characters
- tab-indented command
- A Makefile rule consists of a target to create, dependencies it requires, and a tab-indented command to perform the build.
- Lesson 818 — Structure of a Makefile Rule
- tag
- In code, this means we omit the tag (the name that usually follows the word struct) and provide the alias at the very end.
- Lesson 611 — Anonymous structs with typedef
- tagged union
- In the example below, we use a struct to hold the "Label" of our data, and a nested union to hold the "Value." This is often called a tagged union because the type variable tells us which part of the union is currently active.
- Lesson 669 — Tagged unions for type safetyLesson 670 — Combining structs and unions
- tail
- Because every node in a doubly linked list has a prev pointer, having a tail pointer transforms the list into a two-way street.
- Lesson 1000 — Handling the tail pointerLesson 1001 — Bidirectional traversal
- tail call
- A tail call happens when a function's very last action is returning the result of another function call.
- Lesson 362 — Tail call optimization basics
- Tail Call Optimization (TCO)
- Tail Call Optimization (TCO) is a trick used by compilers.
- Lesson 362 — Tail call optimization basics
- tail_factorial
- Since tail_factorial has nothing left to do but pass the result along, the compiler turns the recursion into a simple loop behind the scenes.
- Lesson 362 — Tail call optimization basics
- tail->next
- In a standard doubly linked list, the head->prev and tail->next pointers both point to NULL.
- Lesson 1004 — Circular doubly linked lists
- tan
- What you'll learn: How to use the sin, cos, and tan functions from the math library and why you must convert degrees to radians first.
- Lesson 863 — Trigonometric functions in radians
- tan()
- C's trigonometric functions require angles in radians, so always multiply degrees by (PI / 180.0) before passing them to sin(), cos(), or tan().
- Lesson 863 — Trigonometric functions in radians
- tape recorder for your terminal
- Think of a Shell script as a tape recorder for your terminal.
- Lesson 1178 — Automating tests with a Shell script
- target
- In the code example above, GDB would stop on the line items[i] = 0; the moment i reached 3, revealing a buffer overflow that accidentally overwrote the target variable.
- Lesson 818 — Structure of a Makefile RuleLesson 821 — Using variables in MakefilesLesson 822 — Automatic variables like `$@` and `$<`Lesson 836 — Using `watch` for memory changesLesson 1211 — Writing the Makefile for the project
- target->health
- You only need to perform the actual #include "enemy.h" inside your .c source file, where you finally need to access the enemy's specific fields (like target->health).
- Lesson 792 — Forward declarations in headers
- target->next
- However, there is a small catch: if the node you are deleting is the Head, you must still update your Head pointer variable in your main program to point to target->next, otherwise your program will try to start the list at a memory location that no longer exists.
- Lesson 1003 — Deleting without head traversal
- Targets
- A Makefile rule uses targets (the goal), dependencies (the requirements), and recipes (the commands) to automate your build process efficiently.
- Lesson 61 — Introduction to `make` and MakefilesLesson 819 — Targets, dependencies, and recipes
- tax
- The program returns to main, and the memory previously used by tax and total is now considered "junk" or empty space.
- Lesson 530 — Stack frame lifecycle and local variables
- tells
- The first % tells printf, "Get ready, something special is coming." The second % clarifies, "The special thing I want is actually just a regular percent sign."
- Lesson 690 — Escaping the percent sign %%
- temp
- To prevent this, we use a temporary variable (often called temp) to hold the data from the first spot while we move the second piece of data into it.
- Lesson 439 — Swapping elements in an arrayLesson 440 — Reversing an array in placeLesson 490 — Swapping two numbers using pointersLesson 555 — Invalid pointer increments before freeLesson 870 — Resizing blocks with `realloc`Lesson 996 — Deleting a node by valueLesson 1051 — In-place sorting vs extra memory
- temp_log.txt
- For example, if your program creates a temporary log, you might check if temp_log.txt already exists.
- Lesson 762 — Checking if a file exists
- temp.txt
- You might wonder, "Why not just create a regular file named temp.txt?"
- Lesson 758 — Creating temporary files with tmpfile
- temperature
- When bake_cake finishes, the memory it used for temperature is instantly freed up for the next function call.
- Lesson 255 — Common mistake: assignment (=) vs equality (==)Lesson 349 — Storage of local variables
- temporary
- The most important thing to remember about a.out is that it is temporary.
- Lesson 60 — Understanding the `a.out` default
- temporary container
- To prevent this, we use a temporary container.
- Lesson 1047 — Bubble Sort: The swap logic
- temporary_value
- If you tried to access temporary_value from outside that function, the compiler would get confused because that variable’s life is tied strictly to the "automatic" scope of the function block.
- Lesson 143 — The `auto` keyword
- temporaryCount
- However, temporaryCount is wiped from the Stack every time the function ends, so it resets to zero every single time the function is called.
- Lesson 149 — Memory segments: Stack vs. Data
- ternary operator
- The ternary operator (? :) is C’s only operator that takes three parts.
- Lesson 206 — Syntax of `? :`Lesson 210 — Ternary vs If-Else for assignmentsLesson 252 — The ternary operator (?:) as a shortcut
- test_main.c
- When you compile your test, you simply link logic.c and test_main.c with your mock_sensor.c instead of the real hardware driver.
- Lesson 1176 — Mocking simple dependencies
- test.sh
- You can create a file named test.sh like this:
- Lesson 1178 — Automating tests with a Shell script
- testing phase
- But during the testing phase, crashing is a gift.
- Lesson 1173 — Writing a simple `assert()` check
- tests_failed == 0
- By returning tests_failed == 0 at the end of main, your program communicates with your computer.
- Lesson 1174 — Building a minimal custom test harness
- Text Editor
- A Text Editor is like a manual transmission—you have to shift the gears yourself, but you learn exactly how the engine behaves.
- Lesson 13 — Using a Text Editor vs IDE
- Text mode
- This distinguishes between Text mode (the default) and Binary mode (using the b flag).
- Lesson 724 — Text mode vs Binary mode (b flag)Lesson 946 — Handling line endings across OSs
- The "at" line
- The "at" line confirms malloc was the source.
- Lesson 566 — Reading 'definitely lost' reports
- the code block
- Normally, the guard checks your ID (the condition) and then lets you through to the courtyard (the code block) to do some work.
- Lesson 272 — Common error: semicolon after while header
- the condition
- Normally, the guard checks your ID (the condition) and then lets you through to the courtyard (the code block) to do some work.
- Lesson 272 — Common error: semicolon after while header
- The first "by" line
- The first "by" line is the "smoking gun." It points to example.c:5.
- Lesson 566 — Reading 'definitely lost' reports
- The first element (argv[0])
- The first element (argv[0]) should traditionally be the name of the program itself.
- Lesson 1082 — Passing arguments to execv()
- The Hand-off
- The Hand-off: When we call updateMessage(&myMessage), we aren't passing the NULL value; we are passing the location of the box itself.
- Lesson 503 — Modifying a pointer inside a function
- The Modification
- The Modification: Inside the function, ptrToPtr means "go to the box located at this address." The assignment ptrToPtr = secretMessage puts a new address inside that box.
- Lesson 503 — Modifying a pointer inside a function
- The Setup
- The Setup: char *myMessage is a box that holds a memory address.
- Lesson 503 — Modifying a pointer inside a function
- The Struct
- The Struct: Inside the "packed" zone, every member follows the previous one immediately.
- Lesson 948 — The `#pragma pack` directive
- The top line
- The top line tells you how much memory was leaked (40 bytes).
- Lesson 566 — Reading 'definitely lost' reports
- the very first time
- In the example above, counter is guaranteed to be 0 the very first time checkStatic() is called.
- Lesson 148 — Default initialization of static variables
- thrd_create
- C11 provides thrd_create to start a task and mtx_init for "mutexes" (locks), which ensure two chefs don't try to use the same knife at the exact same time.
- Lesson 967 — C11: Multi-threading and Anonymous structures
- Thread
- A Thread is like hiring an extra chef to work in your current kitchen.
- Lesson 1116 — Threads vs Processes
- through
- If an array has a size of 10, the valid slots are 0 through 9.
- Lesson 319 — The Fencepost problem (off-by-one errors)
- time_t
- It always returns a double, which is helpful because time calculations often require the precision of floating-point numbers, even if time_t itself is an integer.
- Lesson 889 — Getting system time with `time_t`Lesson 890 — Measuring intervals with `difftime`Lesson 892 — Converting `time_t` to local time with `localtime`Lesson 893 — Converting `time_t` to UTC with `gmtime`Lesson 895 — Converting `struct tm` back to `time_t` with `mktime`
- time()
- When you want to see how fast a piece of code runs, you might be tempted to look at a wall clock or use basic functions like time().
- Lesson 888 — Getting a unique seed with `time(NULL)`Lesson 889 — Getting system time with `time_t`Lesson 1181 — Precise timing with `clock_gettime()`
- time(NULL)
- Because the time is always moving forward, the value returned by time(NULL) will be different every time you hit the "Run" button on your code.
- Lesson 886 — Why you should only seed onceLesson 888 — Getting a unique seed with `time(NULL)`Lesson 889 — Getting system time with `time_t`
- timespec
- It doesn't just return an integer; it fills a special structure called timespec that tracks two things: seconds and nanoseconds.
- Lesson 1181 — Precise timing with `clock_gettime()`
- timestamps
- Instead, it looks at the timestamps—the date and time recorded by your operating system showing when a file was last modified.
- Lesson 824 — Incremental builds and file timestamps
- TL_RED
- Now the "living room" has a TL_RED lamp and an ST_RED lamp, and the compiler can easily tell them apart.
- Lesson 666 — Scoped enum limitations in C
- tm
- The tm struct translates a single raw timestamp into a readable format by separating time into logical components like hours, days, and years.
- Lesson 891 — Breaking down time with `struct tm`Lesson 894 — Formatting time strings with `strftime`
- tm_mon
- Offset values: The tm_year field counts years since 1900 (so 2024 is stored as 124), and tm_mon is zero-indexed (January is 0, not 1).
- Lesson 891 — Breaking down time with `struct tm`Lesson 892 — Converting `time_t` to local time with `localtime`Lesson 893 — Converting `time_t` to UTC with `gmtime`
- tm_wday
- It also fills in the tm_wday (day of the week) automatically, which is a great way to find out what day a specific date falls on.
- Lesson 895 — Converting `struct tm` back to `time_t` with `mktime`
- tm_year
- Offset values: The tm_year field counts years since 1900 (so 2024 is stored as 124), and tm_mon is zero-indexed (January is 0, not 1).
- Lesson 891 — Breaking down time with `struct tm`Lesson 892 — Converting `time_t` to local time with `localtime`Lesson 893 — Converting `time_t` to UTC with `gmtime`
- tmpfile()
- Because tmpfile() handles the filename and location for you, you cannot "find" this file in your file explorer while the program is running—it is often hidden or stored in a restricted system directory.
- Lesson 758 — Creating temporary files with tmpfile
- tmpnam
- Because tmpnam only gives you a name and doesn't lock the file, there is a tiny window of time between getting the name and calling fopen where another program could theoretically grab that same name.
- Lesson 759 — Generating temp filenames with tmpnam
- tmpnam()
- Older C functions like tmpnam() or mktemp() are dangerous because they only suggest a filename.
- Lesson 763 — Temporary file security risks
- tmpnam(filename)
- When you call tmpnam(filename), the function fills your character array with a string like /tmp/fileA3bZ.
- Lesson 759 — Generating temp filenames with tmpnam
- to
- Even though we added 1 to both pointers, the intPtr address increased by 4 (e.g., ending in ...A0 to ...A4), while the charPtr only increased by 1.
- Lesson 196 — Chained assignments `a = b = c`Lesson 320 — Floating point precision issues in loop conditionsLesson 336 — Defining multiple parametersLesson 404 — Linear search for a specific valueLesson 465 — How data types affect step sizeLesson 843 — Distinguishing `ispunct` and `isgraph`Lesson 887 — Scaling `rand` results to a specific rangeLesson 905 — Using `INT_MAX` and `INT_MIN` for overflow checksLesson 1042 — Adding edges in directed graphs
- to 0 and
- Initialization (i = 0, j = max): Before the loop starts, we set i to 0 and j to 5 at the same time.
- Lesson 240 — The comma operator in `for` loops
- to a
- If you want to bring the code back to life, you simply change the 0 to a 1.
- Lesson 785 — Temporary code disabling with `#if 0`
- to an
- If an int takes up 4 bytes of memory, adding 1 to an int pointer actually shifts the address forward by 4 bytes.
- Lesson 464 — Adding integers to pointers
- to assign a value and
- Use = to assign a value and == to compare two values.
- Lesson 165 — Common pitfall: `=` vs `==`
- to decimals for
- Add an f to decimals for float variables and an L for long double variables to ensure your data fits its container perfectly.
- Lesson 120 — Floating-point suffixes (f, L)
- to find the "ceiling." If
- In this code, we subtract b from INT_MAX to find the "ceiling." If a is already higher than that ceiling, adding b is guaranteed to overflow.
- Lesson 1154 — Safe integer arithmetic and overflow checks
- to literals and using the
- Use long double for maximum decimal precision by appending an L to literals and using the %Lf specifier for input and output.
- Lesson 99 — The `long double` type
- to node
- When we add an edge from node A to node B, we only perform one operation: we add B to A's list.
- Lesson 1042 — Adding edges in directed graphs
- to RED
- If you define enum Colors {RED, GREEN, BLUE};, the compiler assigns 0 to RED, 1 to GREEN, and 2 to BLUE.
- Lesson 663 — Explicitly assigning enum values
- to turn bits on and
- Bitwise flags allow you to store multiple boolean states in one variable by using | to turn bits on and & to check their status.
- Lesson 189 — Using bitwise operators for flags
- tokenizing
- In C, the process of breaking this sequence into individual pieces is called tokenizing, and the strtok function is your primary tool for the job.
- Lesson 853 — Tokenizing strings with `strtok`
- tolower()
- When you use the functions in <ctype.h>, such as isalpha(), isdigit(), or tolower(), you might assume they accept a standard char.
- Lesson 443 — Counting vowels and consonantsLesson 845 — Converting case with `toupper` and `tolower`Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- tools.c
- You can give your tools.h and tools.c to a teammate, and they can use your functions without ever needing to read your complex internal logic.
- Lesson 382 — Sharing functions across modules
- tools.h
- You can give your tools.h and tools.c to a teammate, and they can use your functions without ever needing to read your complex internal logic.
- Lesson 382 — Sharing functions across modules
- top
- A linked list stack uses a head pointer as the top, allowing the stack to grow and shrink dynamically by adding or removing nodes from the front of the list.
- Lesson 348 — Pushing and popping framesLesson 587 — Resetting an arena in one stepLesson 1007 — Array-based stack implementationLesson 1008 — Linked list-based stack implementationLesson 1009 — The Push operationLesson 1011 — Implementing the Peek functionLesson 1012 — Handling Stack OverflowLesson 1015 — Front and Rear pointers
- total
- For example, if you write int total = 10 + 5;, C first calculates 15 and then stores that final number into the variable named total.
- Lesson 101 — Precision loss and rounding errorsLesson 150 — The addition operator `+`Lesson 530 — Stack frame lifecycle and local variables
- total * 0.07
- If a new programmer looks at your code and sees total * 0.07, they might wonder: "Is this a tax rate?
- Lesson 118 — Literal vs. Symbolic constants
- total = total - 500
- In the example above, the computer behaves as if the line total = total - 500; doesn't exist.
- Lesson 38 — Commenting out code for testing
- Total $ Amount
- While you might be tempted to name a variable Total $ Amount or 2nd_Place, the C compiler will throw an error.
- Lesson 74 — Naming rules and identifiers
- total_points
- You have two integers: total_points (15) and number_of_tests (2).
- Lesson 230 — The `(type)` cast operator
- totalFruit
- The + operator is the act of pouring both buckets into a new, larger bucket called totalFruit.
- Lesson 150 — The addition operator `+`
- totalItems
- You aren't just letting the computer handle the math; you are explicitly stating that for this specific calculation, you want totalItems treated as a decimal.
- Lesson 135 — Readability and intent in casting
- totalPoints
- It simply looks at what is currently inside playerScored (which is 10), makes a copy of it, and drops that copy into totalPoints.
- Lesson 78 — Assigning values with `=`
- totalPoints = playerScored
- In the example above, totalPoints = playerScored doesn’t link the two variables forever.
- Lesson 78 — Assigning values with `=`
- toupper
- What you'll learn: Why you must cast arguments to (unsigned char) when using functions like isdigit or toupper to prevent program crashes.
- Lesson 846 — The importance of casting to `unsigned char` in `ctype` functions
- toupper()
- Think of these as automated "gates." If you send a lowercase 'b' through the toupper() gate, it comes out as a capital 'B'.
- Lesson 845 — Converting case with `toupper` and `tolower`
- track coach
- Think of it like a track coach telling an athlete to run exactly 10 laps.
- Lesson 321 — Choosing the right loop for the task
- translation
- When you open a file in text mode ("r" or "w"), C performs a little bit of magic behind the scenes called translation.
- Lesson 739 — Risks of seeking in text mode
- Treasure (the actual data)
- Inside that Drawer is a Map that tells you exactly where the Treasure (the actual data) is hidden.
- Lesson 500 — Concept of double indirection
- True
- If you write if (s + 1 > s), and s is a signed integer, the compiler might simplify that entire expression to true and remove the check entirely.
- Lesson 162 — The inequality operator `!=`Lesson 163 — Truthiness: 0 vs non-zeroLesson 167 — Logical NOT `!`Lesson 171 — Short-circuit evaluation of `||`Lesson 173 — Logical vs Bitwise distinctionLesson 242 — Relational operators: <, <=, >, and >=Lesson 243 — Truthiness: 0 is false, non-zero is trueLesson 249 — Logical NOT (!) for inversionLesson 277 — Using do-while for input re-promptingLesson 667 — Type safety concerns with enumsLesson 935 — Signed integer overflow vs Unsigned wrapLesson 966 — C99: Variable declarations and `bool`Lesson 969 — C23: The `bool`, `true`, and `false` keywords
- trunc
- Use trunc to discard decimals without rounding, and use fmod as the floating-point version of the modulo (%) operator.
- Lesson 865 — Truncation and remainder: `trunc` and `fmod`
- trunc()
- The trunc() function is the simplest way to turn a decimal into a whole number.
- Lesson 865 — Truncation and remainder: `trunc` and `fmod`
- Try to read again
- Try to read again. The read fails, but the variables still hold the data from the previous step.
- Lesson 722 — Why feof inside a loop condition is bad
- trylock
- It can use trylock to see if the data is available; if not, it can skip the update for one frame or draw a loading icon instead of hanging the entire application.
- Lesson 1129 — Using pthread_mutex_trylock
- tv.channel = 5
- In C, this is like using the dot operator (tv.channel = 5).
- Lesson 619 — Modifying struct members via pointers
- twice
- The most mind-bending part of fork() is that it is called once, but it returns twice: once in the parent and once in the child.
- Lesson 775 — Side effects in macro argumentsLesson 1073 — Introduction to the fork() system call
- two
- If you want two processes to talk back and forth (bidirectional communication), you actually need to create two separate pipes—one for each direction.
- Lesson 1102 — Unidirectional flow in pipes
- Two-Pointer technique
- The most efficient way to do this is the Two-Pointer technique.
- Lesson 441 — Reversing a string in place
- Two’s Complement
- They can't store a "dash." To solve this, C uses a system called Two’s Complement.
- Lesson 91 — How bits represent negative numbers
- type
- In the example below, we use a struct to hold the "Label" of our data, and a nested union to hold the "Value." This is often called a tagged union because the type variable tells us which part of the union is currently active.
- Lesson 55 — Argument-specifier matchingLesson 383 — Declaring an array with `type name[size]`Lesson 456 — The difference between `int *p` and `*p`Lesson 463 — Incrementing pointers with `++`Lesson 470 — Navigating memory blocks manuallyLesson 670 — Combining structs and unionsLesson 671 — Anonymous unions inside structsLesson 929 — Returning pointers to functions from functionsLesson 931 — The `sizeof` operator with complex typesLesson 973 — Introduction to the `_Generic` keywordLesson 975 — Implementing a generic 'Print' macroLesson 979 — Mathematical macros using `_Generic`Lesson 980 — Limitations of C generics
- type cast
- However, C provides a "hammer" called a type cast.
- Lesson 499 — Casting away `const` volatility
- type declaration
- The magic happens because of the pointer's type declaration.
- Lesson 465 — How data types affect step size
- type name
- When you see int *ptr, the asterisk is just part of the type name, telling C that this variable is a pointer.
- Lesson 457 — The Dereference operator `*`
- type name[]
- A flexible array member (type name[]) must be the last element in a struct and allows you to allocate a single, continuous block of memory for both a header and a variable-length payload.
- Lesson 672 — Flexible array members in C99
- type name[rows][columns]
- A 2D array is declared using type name[rows][columns], creating a grid-based coordinate system for your data.
- Lesson 407 — Declaring 2D arrays: Rows and Columns
- type name[size]
- An array declaration type name[size] tells C to reserve a fixed, side-by-side sequence of memory slots for a specific data type.
- Lesson 383 — Declaring an array with `type name[size]`
- type promotion
- Instead, it follows a rule called Type Promotion.
- Lesson 121 — What is type promotion?Lesson 158 — Mixing int and float in arithmetic
- type punning
- Normally, we use this to save space, but advanced programmers use it for type punning: looking at the raw bits of one data type as if they were another.
- Lesson 657 — Using unions for type punningLesson 659 — The danger of reading the wrong union member
- type_size_t
- The names follow a simple pattern: type_size_t.
- Lesson 86 — Fixed-width types from `<stdint.h>`
- typedef
- To make a struct refer to itself, we have to use a "struct tag." Usually, we might use typedef to skip writing the word struct, but because the compiler needs to know about the pointer inside the definition, we must name the struct explicitly.
- Lesson 520 — Defining `typedef` for function pointersLesson 607 — The syntax of typedefLesson 608 — Using typedef with primitive typesLesson 609 — Creating a shorthand for struct namesLesson 610 — Combining struct definition and typedefLesson 611 — Anonymous structs with typedefLesson 612 — Naming conventions for typedef typesLesson 613 — Typedef vs. #define macrosLesson 614 — Improving code readability with typedefLesson 626 — Self-referential structs for linked listsLesson 923 — Storage class specifier precedenceLesson 930 — Complex nested `typedef` structures
- typedef [existing type] [new name]
- The syntax follows a simple pattern: typedef [existing type] [new name];.
- Lesson 608 — Using typedef with primitive types
- typedef [original type] [new name]
- Use typedef [original type] [new name]; to create a shorter alias for complex types to make your code more readable.
- Lesson 607 — The syntax of typedef
- typedef struct { ... } Name
- Use typedef struct { ... } Name; to define a structure and its shorthand alias simultaneously, keeping your code concise and professional.
- Lesson 610 — Combining struct definition and typedef
- typedefs
- Nested typedefs transform unreadable, complex declarations into a logical hierarchy of named types that are easier to maintain and debug.
- Lesson 930 — Complex nested `typedef` structures
- typeof
- C23 introduces typeof, which acts like a "rubber stamp." Instead of looking up a type, you tell the compiler: "Whatever type this specific thing is, make my new variable the same."
- Lesson 932 — Using `typeof` in C23
- types
- Before you can send data over a network, you have to decide two things: "Where is this going?" and "How should the data behave?" In C, we define these using Domains and Types.
- Lesson 332 — Matching prototypes with definitionsLesson 1108 — Socket domains and types
U
- u.decimal
- When you assigned 3.14f to u.decimal, the program went to the union's memory address and wrote the binary pattern for that float.
- Lesson 655 — Accessing union members
- u.integer
- If you try to read u.integer while the float is there, C won't stop you, but it will try to interpret the float’s binary bits as an integer.
- Lesson 655 — Accessing union members
- UCHAR_MAX
- This header defines constants like INT_MAX, CHAR_BIT, and UCHAR_MAX.
- Lesson 942 — Limits of `limits.h` and `stdint.h`
- UI_
- Use unique, module-specific prefixes (like UI_ or NET_) for all public functions and global variables to prevent naming conflicts in large projects.
- Lesson 801 — Naming conventions for large projects
- ui.c
- This means if you define int global_score = 100; in game.c, you can access that exact same memory location in ui.c by using the extern keyword.
- Lesson 146 — The `extern` keyword for multi-file codeLesson 918 — Internal vs external linkage basics
- UINT_MAX
- The largest possible unsigned int (the minimum is always 0).
- Lesson 96 — The `<limits.h>` header file
- uint32_t
- Here is how you can manually reverse the bytes of a uint32_t.
- Lesson 612 — Naming conventions for typedef typesLesson 953 — Manual byte swapping techniques
- uint8_t
- Use <stdint.h> types like int32_t or uint8_t when you need guaranteed, consistent variable sizes across different computers.
- Lesson 86 — Fixed-width types from `<stdint.h>`Lesson 945 — The significance of `char` signness
- uintptr_t
- Always use size_t for memory sizes and uintptr_t for pointer-to-integer conversions to ensure your code runs safely on both 32-bit and 64-bit systems.
- Lesson 949 — Writing code for 32-bit vs 64-bit
- ulimit -c unlimited
- To tell Linux you want them, you usually run ulimit -c unlimited in your terminal.
- Lesson 837 — Debugging a Segfault from a core dump
- unaligned access
- In programming, this "extra trip" is exactly what happens with unaligned access.
- Lesson 574 — Performance cost of unaligned access
- unary operators
- Right-to-left associativity is also found in unary operators (operators that act on a single thing, like ++ or - for negative numbers).
- Lesson 214 — Right-to-left associativity
- unbuffered
- It is unbuffered, meaning it bypasses the waiting bin and hits the screen the exact millisecond the command is executed.
- Lesson 750 — Unbuffered output (stderr)
- Undefined
- If you push a signed integer past its maximum limit, the C standard does not say "it wraps around." Instead, it says the behavior is Undefined.
- Lesson 935 — Signed integer overflow vs Unsigned wrap
- Undefined Behavior
- If you try to modify a variable and read it (or modify it again) in the same statement, you enter the territory of Undefined Behavior.
- Lesson 204 — Common increment pitfallsLesson 915 — The `restrict` pointer qualifier
- Undefined Behavior (UB)
- Instead, it categorizes "weird" code into two main buckets: Implementation-defined behavior and Undefined Behavior (UB).
- Lesson 225 — Undefined behavior: `i = i++`Lesson 934 — What 'Undefined Behavior' actually meansLesson 938 — Accessing out-of-bounds memoryLesson 939 — Using uninitialized variablesLesson 943 — Implementation-defined behavior vs UB
- undefined reference
- An undefined reference means you promised a function existed, but you failed to provide the actual code for it.
- Lesson 28 — Phase 4: The LinkerLesson 64 — Library linking basicsLesson 70 — The 'undefined reference' linker error
- underscores
- Always name your files in lowercase, use underscores instead of spaces, and ensure they end in a lowercase .c.
- Lesson 16 — Naming conventions for .c files
- undirected
- Edges can be undirected (like a two-way street where both people are friends) or directed (like a one-way street or a "follower" relationship on Twitter).
- Lesson 1039 — Vertices and Edges definition
- unidirectional
- The most important rule to remember is that pipes are unidirectional.
- Lesson 1102 — Unidirectional flow in pipes
- uninitialized variable
- When you declare a variable but do not assign it a value, it is called an uninitialized variable.
- Lesson 77 — Garbage values and uninitialized variables
- union
- If you truly need to view the same bytes as two different types, use a union or memcpy, which are specifically designed to tell the compiler: "Heads up, this memory is being shared!"
- Lesson 653 — Defining a union with the union keywordLesson 654 — Memory layout of a unionLesson 656 — Overlapping memory in unionsLesson 657 — Using unions for type punningLesson 658 — Size of a union vs size of a structLesson 669 — Tagged unions for type safetyLesson 670 — Combining structs and unionsLesson 936 — Strict aliasing rule violations
- unique name
- A declaration consists of a data type, a unique name, and a semicolon.
- Lesson 75 — The syntax of a declaration
- unistd.h
- To find out the "passport number" of your own program while it is running, you use a simple function from the unistd.h library called getpid().
- Lesson 1068 — Getting PID with getpid()Lesson 1069 — Parent processes and getppid()
- Unit Testing
- In C, Unit Testing is the practice of checking the smallest "units" of your code—usually individual functions—before they become part of the whole.
- Lesson 1172 — Principles of Unit TestingLesson 1177 — Integration testing vs. Unit testing
- Units
- In the example above, Units behaves exactly like an unsigned int.
- Lesson 608 — Using typedef with primitive types
- universal remote control
- Using a function pointer is like using a universal remote control.
- Lesson 516 — Calling a function via a pointer
- Unix timestamp
- C provides a function called time() (found in the <time.h> header) that returns the Unix timestamp.
- Lesson 888 — Getting a unique seed with `time(NULL)`
- UNKNOWN
- In the example above, because SERVER_ERROR was set to 500, the compiler automatically assigned UNKNOWN the next integer in sequence: 501.
- Lesson 663 — Explicitly assigning enum values
- unlock
- To fully unlock the mutex, the thread must call unlock the exact same number of times it called lock.
- Lesson 1126 — Locking and unlocking mutexesLesson 1130 — Recursive mutexes
- unlocked
- If the mutex is unlocked, the thread locks it and the function returns 0.
- Lesson 1129 — Using pthread_mutex_trylock
- unnamed bit-fields
- This is where unnamed bit-fields come in.
- Lesson 650 — Unnamed bit-fields for padding
- unsigned
- If you are writing a program where some numbers must be positive (unsigned) and others must allow negatives, using the signed keyword side-by-side with unsigned makes your code much easier to read and less prone to mistakes.
- Lesson 89 — The `signed` keywordLesson 90 — The `unsigned` keywordLesson 92 — Understanding Integer OverflowLesson 93 — Underflow in unsigned typesLesson 94 — Format specifiers for unsigned intsLesson 95 — When to choose unsigned over signedLesson 111 — Signed vs. Unsigned charsLesson 184 — Right shift `>>` mechanicsLesson 185 — Logical vs Arithmetic shiftsLesson 646 — Syntax for declaring bit-fieldsLesson 649 — Signed vs unsigned bit-fieldsLesson 945 — The significance of `char` signness
- unsigned char
- There is a historical trap here: these functions are only defined to handle values that can be represented as an unsigned char (0 to 255), plus one special value: EOF (usually -1).
- Lesson 111 — Signed vs. Unsigned charsLesson 683 — Relationship between char and int in I/OLesson 846 — The importance of casting to `unsigned char` in `ctype` functionsLesson 935 — Signed integer overflow vs Unsigned wrapLesson 945 — The significance of `char` signness
- unsigned char*
- If you truly need to look at the raw bits of a variable (for example, to send them over a network), the only safe way is to use a pointer to a character type (char or unsigned char) or the memcpy function.
- Lesson 527 — Pointer type-punning dangers
- unsigned int
- While this is great for saving memory, there are times when you need a specific member to start fresh at the beginning of the next "unit" (the underlying storage type, like an unsigned int).
- Lesson 93 — Underflow in unsigned typesLesson 94 — Format specifiers for unsigned intsLesson 95 — When to choose unsigned over signedLesson 127 — Mixing signed and unsigned in mathLesson 232 — Signed to unsigned conversionLesson 608 — Using typedef with primitive typesLesson 646 — Syntax for declaring bit-fieldsLesson 647 — Restrictions on bit-field typesLesson 649 — Signed vs unsigned bit-fieldsLesson 651 — Zero-width bit-fields for alignmentLesson 945 — The significance of `char` signness
- unsigned int : 0
- A zero-width bit-field is a special syntax—unsigned int : 0;—that tells the compiler: "Stop packing bits into the current unit.
- Lesson 651 — Zero-width bit-fields for alignment
- unsigned integer
- Think of an unsigned integer like a tape measure.
- Lesson 95 — When to choose unsigned over signed
- unsigned integers
- In C, unsigned integers work exactly like this.
- Lesson 935 — Signed integer overflow vs Unsigned wrap
- unsigned short
- On most systems, an unsigned short maxes out at 65,535.
- Lesson 92 — Understanding Integer Overflow
- Unsigned wins
- Instead, it follows a rule called "Usual Arithmetic Conversions." The most important rule to remember is: Unsigned wins.
- Lesson 127 — Mixing signed and unsigned in math
- unsorted
- It treats the array as two parts: a sorted section on the left and an unsorted section on the right.
- Lesson 1048 — Selection Sort: Finding the minimumLesson 1064 — Importance of sorted data
- unstable
- If you use an unstable sort, the 5 of Spades might end up first.
- Lesson 1052 — Stability in sorting algorithms
- up
- Use up to inspect the variables of the function that called your current position, and down to return toward the active line of code.
- Lesson 834 — Moving between frames with `up` and `down`Lesson 864 — Rounding with `ceil`, `floor`, and `round`
- up 2
- You can move multiple steps by typing up 2 or go back to the start by typing down.
- Lesson 834 — Moving between frames with `up` and `down`
- update expression
- The third part of the for loop declaration is the update expression.
- Lesson 287 — Using non-unit increments (e.g., i += 2)
- update statement
- To prevent this, you must include an update statement inside the loop body.
- Lesson 268 — Updating the loop variable to avoid infinite loops
- update()
- If both files define a global variable or function named update(), the compiler will get confused, and the linker will throw a "multiple definition" error.
- Lesson 801 — Naming conventions for large projects
- updateMessage(&myMessage)
- The Hand-off: When we call updateMessage(&myMessage), we aren't passing the NULL value; we are passing the location of the box itself.
- Lesson 503 — Modifying a pointer inside a function
- updateScore
- The updateScore function was just playing with a clone.
- Lesson 345 — Limitations of pass by value
- Use After Free (UAF)
- In C, a Use After Free (UAF) happens when you call free() on a pointer, but then try to read from or write to that pointer later in the program.
- Lesson 1167 — Tracking down 'Use After Free' bugs
- Use Extra Memory
- Use Extra Memory when speed is the absolute priority and you have plenty of RAM to spare, as these algorithms often handle large datasets more efficiently.
- Lesson 1051 — In-place sorting vs extra memory
- Use In-place
- Use In-place when memory is tight or when you want to avoid the overhead of allocating and freeing new memory buffers.
- Lesson 1051 — In-place sorting vs extra memory
- use_battery(50)
- In this code, when use_battery(50) runs, the function creates its own local version of energy and sets it to 50.
- Lesson 340 — Shadowing variables in functions
- user
- By nesting the Address inside the User, you tell the compiler (and other programmers) that this specific address format is intrinsically tied to the user.
- Lesson 612 — Naming conventions for typedef typesLesson 622 — The importance of NULL checks for struct pointersLesson 623 — Defining a struct inside another structLesson 794 — Circular dependency issuesLesson 801 — Naming conventions for large projectsLesson 1215 — Writing the Search function
- User Headers
- Double Quotes "filename.h": These are for User Headers.
- Lesson 795 — Standard header search paths
- User user1
- By using typedef, you can hide that requirement and treat your structure just like a standard type (e.g., User user1;).
- Lesson 607 — The syntax of typedef
- user_age
- Other variables: Suddenly, your user_age variable changes to 9999 because a nearby pointer leaked into its space.
- Lesson 40 — C coding style guidesLesson 524 — Buffer overflows via pointers
- user_input.c
- Level 2 (The Middle): Logic modules like physics.c or user_input.c.
- Lesson 802 — Dependency graphing in your head
- user_input()
- In C, this means testing how different modules or files interact—for example, checking if your database_save() function correctly handles the data passed to it by your user_input() function.
- Lesson 1177 — Integration testing vs. Unit testing
- user.h
- When the compiler looks at user.h, it tries to resolve post.h first.
- Lesson 794 — Circular dependency issues
- User*
- Returning a pointer (User*) is more efficient than returning the entire struct.
- Lesson 1215 — Writing the Search function
- USER=alice
- They are key-value pairs (like USER=alice) that exist outside your program's source code, allowing you to change a program’s behavior without recompiling it.
- Lesson 1071 — Environment variables in C
- userAge
- It tells the debugger: "Hey, this chunk of machine code at address 0x7ffe actually belongs to the variable userAge on line 12 of main.c."
- Lesson 37 — Readability best practicesLesson 40 — C coding style guidesLesson 825 — Compiling with debug symbols `-g`
- userGuess != secretPin
- However, userGuess != secretPin evaluates to true, so the "Access denied" message will appear on the screen.
- Lesson 241 — Relational operators: == and !=
- userGuess == secretPin
- In the code above, userGuess == secretPin evaluates to false because 5555 is not 1234.
- Lesson 241 — Relational operators: == and !=
- username
- In the first example, username is a container that can hold 10 characters.
- Lesson 415 — Declaring arrays of type `char`Lesson 561 — Heap buffer overflows
- using an
- For example, instead of counting by 0.1, count from 1 to 10 using an int, then divide the result by 10.0.
- Lesson 320 — Floating point precision issues in loop conditions
- Usual Arithmetic Conversions
- Since the computer’s CPU prefers to perform math on two values of the exact same type, C uses a set of behind-the-scenes rules called the Usual Arithmetic Conversions.
- Lesson 126 — The 'Usual Arithmetic Conversions'Lesson 229 — Usual arithmetic conversions
- UTC
- Specifically, gmtime converts the time to UTC (Greenwich Mean Time), which is the global scientific standard, ignoring local time zones or daylight savings.
- Lesson 893 — Converting `time_t` to UTC with `gmtime`
- utils.c
- This means if you change a small helper function in utils.c, you don't necessarily have to rethink how the entire main.c is written; you just ensure the connections stay the same.
- Lesson 824 — Incremental builds and file timestampsLesson 1210 — Structuring the project into multiple `.c` filesLesson 1211 — Writing the Makefile for the project
- utils.h
- If your project grows, you might end up with two different utils.h files in different folders, leading to a "collision" where one file accidentally blocks the other from loading.
- Lesson 1203 — Header guard best practices
V
- va_arg
- If you tried to use va_arg after that line, the program would fail, which is exactly what we want—it prevents us from accidentally reaching into memory where we don't belong.
- Lesson 371 — Functions with unknown argumentsLesson 372 — The `stdarg.h` libraryLesson 374 — Extracting arguments with `va_arg`Lesson 375 — Cleaning up with `va_end`Lesson 376 — How `printf` works internally
- va_end
- On certain hardware architectures or specific compilers, failing to call va_end can lead to "undefined behavior"—a fancy way of saying your program might crash, corrupt memory, or act unpredictably.
- Lesson 372 — The `stdarg.h` libraryLesson 375 — Cleaning up with `va_end`
- va_end(args)
- In the example above, va_end(args) invalidates the pointer.
- Lesson 375 — Cleaning up with `va_end`
- va_list
- By passing the last known fixed argument (like count in the example above) to va_start, you are telling C: "Look at the memory address of this variable, skip over it, and start reading right after that." Without at least one fixed argument to act as a lighthouse, va_list would be lost at sea.
- Lesson 371 — Functions with unknown argumentsLesson 372 — The `stdarg.h` libraryLesson 373 — Using `va_list` and `va_start`Lesson 374 — Extracting arguments with `va_arg`Lesson 375 — Cleaning up with `va_end`Lesson 376 — How `printf` works internally
- va_start
- By passing the last known fixed argument (like count in the example above) to va_start, you are telling C: "Look at the memory address of this variable, skip over it, and start reading right after that." Without at least one fixed argument to act as a lighthouse, va_list would be lost at sea.
- Lesson 371 — Functions with unknown argumentsLesson 372 — The `stdarg.h` libraryLesson 373 — Using `va_list` and `va_start`Lesson 374 — Extracting arguments with `va_arg`Lesson 375 — Cleaning up with `va_end`Lesson 376 — How `printf` works internally
- val1
- If val1 is 5 and val2 is 10, the result is -5 (negative), placing 5 first.
- Lesson 877 — Writing an integer comparison function
- val2
- If val1 is 5 and val2 is 10, the result is -5 (negative), placing 5 first.
- Lesson 877 — Writing an integer comparison function
- val2 - val1
- By changing just the logic inside compare_ints (for example, returning val2 - val1), you can flip the entire sorting order to descending without ever touching the complex sorting algorithm itself.
- Lesson 519 — The `qsort` callback mechanism
- Valgrind
- Tools like Valgrind act like a private investigator, tracking every key you've been issued to make sure you returned them all to the front desk before the program ended.
- Lesson 564 — Installing Valgrind MemcheckLesson 1164 — What is a memory leak?Lesson 1185 — Profiling memory allocation frequencyLesson 1219 — Final memory leak check and cleanup
- valgrind --leak-check=full ./my_program
- When you run this through Valgrind with the command valgrind --leak-check=full ./my_program, the tool tracks the address returned by malloc().
- Lesson 528 — Tools for pointer debugging (Valgrind)Lesson 1170 — Cleaning up heap memory before exit
- valgrind --leak-check=full ./your_program
- By running valgrind --leak-check=full ./your_program, the computer tracks every single byte.
- Lesson 1219 — Final memory leak check and cleanup
- valgrind --version
- Once installed, you can check if it's ready by typing valgrind --version.
- Lesson 1165 — Installing and running `valgrind`
- valgrind ./my_program
- When you run your program through Valgrind using valgrind ./my_program, it acts like a security guard watching your every move.
- Lesson 568 — Finding invalid reads and writesLesson 569 — Detecting uninitialized value usageLesson 1167 — Tracking down 'Use After Free' bugsLesson 1168 — Detecting uninitialized memory reads
- valgrind ./your_program
- Run valgrind ./your_program on code compiled with the -g flag to catch hidden memory leaks before they crash your software.
- Lesson 565 — Running a program under ValgrindLesson 1165 — Installing and running `valgrind`
- valgrind-3.18.1
- If you see a version number (like valgrind-3.18.1), you are ready to go.
- Lesson 564 — Installing Valgrind Memcheck
- Valgrind's Callgrind
- In C, we use tools called profilers (like gprof or Valgrind's Callgrind) to identify these spots.
- Lesson 1183 — Identifying 'Hot Spots' in your code
- validate()
- You might have a helper function called validate() that is specific to your math logic and shouldn't clash with a validate() function in your networking logic.
- Lesson 918 — Internal vs external linkage basics
- value
- Each locker has a Key (the unique number etched on the metal tag) and a Value (the bag or shoes stored inside).
- Lesson 79 — Declaration vs. InitializationLesson 859 — Searching memory bytes with `memchr`Lesson 873 — Converting strings to doubles with `strtod`Lesson 911 — Difference between `const int *` and `int * const`Lesson 973 — Introduction to the `_Generic` keywordLesson 1031 — Key-Value pair concept
- value > 10
- value > 10 is false (10 is not strictly bigger than 10).
- Lesson 242 — Relational operators: <, <=, >, and >=
- value >= 10
- value >= 10 is true (10 is equal to 10).
- Lesson 242 — Relational operators: <, <=, >, and >=
- varargs
- The function uses varargs (variable arguments).
- Lesson 367 — Compiler discretion with inlining
- variable
- A variable is like putting a Post-it note label on one of those lockers.
- Lesson 50 — Printing integers with `%d`Lesson 73 — What is a variable?
- variable += value
- Use variable += value; as a shorthand to add a number to an existing variable and save the result instantly.
- Lesson 192 — Compound addition `+=`
- Variable Values
- To trace a loop, draw three columns: Iteration Number, Variable Values, and Condition Check (True/False).
- Lesson 273 — Tracing while loop execution on paper
- variable.member
- Use the dot operator (variable.member) to access or modify specific pieces of data stored inside a structure.
- Lesson 601 — The dot operator for member access
- variables and an
- Add an f to decimals for float variables and an L for long double variables to ensure your data fits its container perfectly.
- Lesson 120 — Floating-point suffixes (f, L)
- variadic arguments
- Most functions require a fixed number of inputs, but printf uses a feature called variadic arguments.
- Lesson 376 — How `printf` works internally
- variadic functions
- To do this in C, we use variadic functions powered by the <stdarg.h> header.
- Lesson 372 — The `stdarg.h` library
- Variant
- When you pass a Variant struct to a function, that function doesn't have to guess what's inside.
- Lesson 669 — Tagged unions for type safety
- vending machine
- Think of it like a vending machine: you enter your selection first, and then the machine checks if you have enough credit.
- Lesson 321 — Choosing the right loop for the taskLesson 328 — Returning values from functions
- VERBOSE
- Debug Modes: Running specific logs only when DEBUG is on and VERBOSE is also enabled.
- Lesson 782 — The `defined()` operator
- VERSION
- In the example above, because VERSION is defined as 2, the preprocessor will keep the "Pro Version" line and literally erase the "Free Version" line.
- Lesson 781 — Basic logic with `#if` and `#else`
- Vertex
- A Vertex (plural: Vertices) is a single data point in your graph.
- Lesson 1039 — Vertices and Edges definition
- Vertices
- A Graph is a collection of Vertices (the data points) connected by Edges (the relationships between them).
- Lesson 1039 — Vertices and Edges definition
- very first one
- If you have ten errors, always focus on the very first one.
- Lesson 66 — Reading compiler error messages
- virtual address space
- We ask the OS for a huge range of virtual address space (Reserving).
- Lesson 590 — Growing an arena with virtual memory
- VirtualAlloc
- On modern systems, we can do this using mmap (Unix) or VirtualAlloc (Windows).
- Lesson 590 — Growing an arena with virtual memory
- Visit
- Visit a node and mark it so you don't visit it twice.
- Lesson 1044 — Breadth-First Search (BFS) logic
- visited
- We typically use a visited array—an array of booleans where visited[i] is true if we have already processed node i.
- Lesson 1045 — Depth-First Search (DFS) recursion
- visited[i]
- We typically use a visited array—an array of booleans where visited[i] is true if we have already processed node i.
- Lesson 1045 — Depth-First Search (DFS) recursion
- visitor_count
- In the code above, every time greet() is called, the variable visitor_count is born, assigned the value 1, incremented to 2, and then deleted from existence.
- Lesson 140 — Automatic duration variables
- void
- Because it is a void pointer, it doesn't care if you were storing integers, characters, or complex structures; it just needs the starting address of the block you originally received from malloc.
- Lesson 323 — Anatomy of a function definitionLesson 324 — The `void` return typeLesson 325 — Writing your first custom functionLesson 328 — Returning values from functionsLesson 489 — Returning multiple values via pointersLesson 509 — Casting `void *` to specific typesLesson 511 — Generic functions in CLesson 512 — The `memcpy` function signatureLesson 541 — The free function signatureLesson 635 — Sorting an array of structsLesson 875 — Cleaning up at exit with `atexit`Lesson 1120 — Returning values from threads
- void *
- It allows you to perform "low-level" tricks, such as inspecting the individual bytes of a large structure or working with void * (a "generic" pointer that doesn't have a type yet).
- Lesson 134 — Casting pointers (Introductory look)Lesson 461 — Implicit vs explicit pointer typesLesson 507 — The `void *` generic typeLesson 508 — Why you can't dereference `void *`Lesson 509 — Casting `void *` to specific typesLesson 510 — Implicit conversion to `void *`Lesson 511 — Generic functions in CLesson 635 — Sorting an array of structsLesson 674 — Information hiding using void pointersLesson 877 — Writing an integer comparison functionLesson 878 — Writing a string comparison function for `qsort`Lesson 1060 — Writing a custom comparator for qsortLesson 1117 — Creating threads with pthread_createLesson 1118 — Passing arguments to threadsLesson 1120 — Returning values from threads
- void *base
- void base*: This is a pointer to the start of your array.
- Lesson 876 — The generic signature of `qsort`
- void calculate(int age)
- When you define a function like void calculate(int age), that age variable is "local" to the function's curly braces {}.
- Lesson 141 — Function parameters as local scope
- void celebrate_success(int count)
- Simply writing void celebrate_success(int count); (a function prototype) acts as an implicit extern.
- Lesson 922 — Using `extern` with functions
- void greet()
- When you write a function like void greet(), the compiler translates those lines of code into a series of machine instructions.
- Lesson 515 — Taking the address of a function
- void myFunction(int *arr)
- void myFunction(int *arr) — The explicit pointer way.
- Lesson 474 — Passing arrays to functions as pointers
- void myFunction(int arr[])
- void myFunction(int arr[]) — The "array-style" way (which the compiler turns into a pointer anyway).
- Lesson 474 — Passing arrays to functions as pointers
- void process_data(char *str)
- If they see void process_data(char str), they have to wonder: Does this function modify my string?
- Lesson 1198 — The role of `const` in documentation
- void*
- By using void*, we tell the compiler: "I'm going to give you a memory address, but don't worry about what type of data is stored there yet." By passing sizeof(type), we tell the function exactly how many bytes to grab.
- Lesson 512 — The `memcpy` function signatureLesson 513 — Implementing a generic swap functionLesson 537 — The malloc function signatureLesson 540 — Casting malloc return in C vs C++Lesson 620 — Allocating structs on the heap with mallocLesson 876 — The generic signature of `qsort`Lesson 881 — Handling the `void*` return of `bsearch`Lesson 980 — Limitations of C generics
- volatile
- If we removed volatile from the code above, a high-level optimization might see while (status == 0) and think: "Since status is 0 and nothing in this loop changes it, I'll just treat this as while (true)." Your program would then hang forever, even if the memory at the status address changed to 1.
- Lesson 913 — The `volatile` qualifier for hardware mappingLesson 914 — How `volatile` prevents compiler optimizationLesson 917 — Combining `const` and `volatile`Lesson 957 — The `asm` keyword syntaxLesson 958 — The basic `volatile` asm blockLesson 1147 — Volatile vs Atomic
- volatile sig_atomic_t
- When writing handlers, keep them "small and simple." The best practice is often to just set a global flag of type volatile sig_atomic_t and handle the actual logic back in your main loop.
- Lesson 1089 — Signal safety and reentrant functions
- VS Code
- If you want simplicity and speed, start with a text editor like VS Code.
- Lesson 13 — Using a Text Editor vs IDE
W
- wait()
- If your parent process needs a file that the child is currently writing, wait() ensures the parent doesn't try to open that file until the child is officially finished.
- Lesson 1076 — Waiting for children with wait()Lesson 1077 — Capturing child exit statusLesson 1078 — Preventing zombie processesLesson 1083 — Combining fork() and exec()
- wait(&status)
- Use wait(&status) to collect a child's exit info, then use WIFEXITED and WEXITSTATUS to decode how the child finished.
- Lesson 1077 — Capturing child exit status
- wait(NULL)
- If you removed the wait(NULL) line and told the parent to sleep(100), the child would remain a zombie for 100 seconds.
- Lesson 1078 — Preventing zombie processes
- waiter_take_order()
- The waiter_take_order() function is public—customers need to interact with it.
- Lesson 798 — Static functions for file scoping
- warning: implicit declaration of function 'calculate_area'
- warning: implicit declaration of function 'calculate_area'
- Lesson 334 — Common errors with missing prototypes
- wash_dishes()
- The customers don't need to know it exists, and two different restaurants can both have a wash_dishes() routine without interfering with each other.
- Lesson 798 — Static functions for file scoping
- watch
- In GDB, the watch command sets a "watchpoint." Unlike a breakpoint (which stops at a specific line of code), a watchpoint stops the program whenever the value of a specific expression or variable changes.
- Lesson 836 — Using `watch` for memory changes
- watch <variable>
- Use watch <variable> in GDB to automatically pause execution the instant a variable’s value is modified.
- Lesson 836 — Using `watch` for memory changes
- WatchStatus
- In this example, the entire WatchStatus structure could fit into just 4 bits of a single byte.
- Lesson 645 — Purpose of bit-fields in memory-constrained systems
- wb
- Because we used "write binary" mode (wb), C copies the actual bits and bytes from your RAM into the file.
- Lesson 725 — Writing raw bytes with fwrite
- wb+
- The file is automatically opened in wb+ mode (binary read/write).
- Lesson 758 — Creating temporary files with tmpfile
- weeks
- If you are printing a calendar, the outer loop moves through the weeks, and for every week, the inner loop moves through the seven days.
- Lesson 299 — Inner loop vs outer loop execution order
- weight
- It will return 1, leaving the weight variable untouched.
- Lesson 696 — Handling the return value of scanf
- WEXITSTATUS
- Use wait(&status) to collect a child's exit info, then use WIFEXITED and WEXITSTATUS to decode how the child finished.
- Lesson 1077 — Capturing child exit status
- WEXITSTATUS(status)
- WEXITSTATUS(status): Extracts the actual return value (the 0 or 1) from the child.
- Lesson 1077 — Capturing child exit status
- what
- The .h file defines what a tool does, while the .c file defines how it does it.
- Lesson 377 — Role of the `.h` fileLesson 508 — Why you can't dereference `void *`
- when they mean
- The most common mistake for beginners is using = when they mean == inside an if statement.
- Lesson 161 — The equality operator `==`Lesson 255 — Common mistake: assignment (=) vs equality (==)
- wherever you typed
- When you run this code, the output will only show a single \ wherever you typed \\.
- Lesson 47 — Escaping the backslash
- which
- You must tell C which structure you are talking about before you can ask for a member inside it.
- Lesson 633 — Combining array indexing and member access
- while
- Think of it like a car journey: a for loop is saying "drive exactly 50 miles," whereas a while loop is saying "keep driving as long as the gas tank isn't empty." You don't know the exact mileage, but you know the condition that keeps you moving.
- Lesson 1 — What is a low-level language?Lesson 266 — The while loop syntax and execution flowLesson 267 — The loop condition: when to stopLesson 268 — Updating the loop variable to avoid infinite loopsLesson 269 — Using while for indeterminate iterationsLesson 270 — Reading input until EOF with whileLesson 271 — Infinite loops: while(1) and while(true)Lesson 272 — Common error: semicolon after while headerLesson 273 — Tracing while loop execution on paperLesson 274 — The do-while syntax and the trailing semicolonLesson 275 — Guaranteed execution: why do-while is differentLesson 276 — Using do-while for menu-driven programsLesson 277 — Using do-while for input re-promptingLesson 278 — Converting a while loop to a do-whileLesson 279 — Comparing while vs do-while use casesLesson 280 — Scope of variables declared inside do-whileLesson 281 — Pitfall: condition check occurs after executionLesson 292 — Continue in while vs for loopsLesson 296 — Readability: when to avoid excessive breaksLesson 308 — Why goto is generally discouragedLesson 311 — The dangers of 'spaghetti code'Lesson 314 — The Sentinel Value patternLesson 321 — Choosing the right loop for the taskLesson 352 — Identifying a Stack OverflowLesson 353 — Concept of self-calling functionsLesson 358 — Iteration vs. Recursion comparisonLesson 364 — When to avoid recursionLesson 429 — Tokenizing strings with `strtok`Lesson 441 — Reversing a string in placeLesson 446 — Merging two sorted arraysLesson 482 — Pointer-based `strcpy` implementationLesson 682 — Using while loops with getcharLesson 707 — Checking for NULL return in fgetsLesson 721 — Detecting the end of a file with feofLesson 722 — Why feof inside a loop condition is badLesson 992 — Traversing the list with a while loopLesson 1003 — Deleting without head traversalLesson 1028 — Finding Min and Max nodesLesson 1049 — Insertion Sort: Shifting elementsLesson 1062 — Binary Search: Iterative approachLesson 1063 — Binary Search: Recursive approachLesson 1084 — What are Unix signalsLesson 1132 — Introduction to condition variablesLesson 1133 — Waiting with pthread_cond_waitLesson 1134 — Signaling with pthread_cond_signalLesson 1196 — Consistency: K&R vs. Allman styleLesson 1206 — Opening and reading files line-by-line
- while (!feof(file))
- When you use while (!feof(file)), you are asking: "Have I already hit the end?" The problem is that the "end of file" status is only set after a failed read attempt.
- Lesson 722 — Why feof inside a loop condition is bad
- while (*ptr != '\0')
- By using while (*ptr != '\0'), you can process strings of any length without needing to know the size of the array beforehand.
- Lesson 481 — Iterating strings until `\0` with pointers
- while (*ptr)
- Experienced C programmers often shorten this to while (*ptr).
- Lesson 481 — Iterating strings until `\0` with pointers
- while (1)
- Instead of trying to force a complex condition into the while(...) parenthesis, you can run a simple while (1) and put a break right after the line where you read the user's input.
- Lesson 293 — Using break to exit infinite loops on condition
- while (age < 0)
- The Logic Check: Once the user hits enter, the program reaches the while (age < 0); line at the bottom.
- Lesson 277 — Using do-while for input re-prompting
- while (choice != 3)
- Once the user types a number, the while (choice != 3) at the bottom evaluates the situation.
- Lesson 276 — Using do-while for menu-driven programs
- while (condition)
- By avoiding these jumps, you ensure that the loop header while (condition) tells the whole truth.
- Lesson 297 — Alternative patterns to avoid break and continue
- while (cookies > 0)
- Here is why: The computer sees while (cookies > 0); as a complete instruction.
- Lesson 272 — Common error: semicolon after while header
- while (current != NULL)
- To traverse a list, initialize a temporary pointer to the head and use current = current->next inside a while (current != NULL) loop to move from node to node.
- Lesson 992 — Traversing the list with a while loop
- while (last->next != NULL)
- Unlike an array where you can jump to array[last_index], a linked list requires a "walk." The while (last->next != NULL) loop is the heartbeat of this process.
- Lesson 994 — Appending nodes to the tail
- while (scanf(...) != EOF)
- Use while (scanf(...) != EOF) to process data continuously until the user or a file signals that there is nothing left to read.
- Lesson 270 — Reading input until EOF with while
- while (status == 0)
- If we removed volatile from the code above, a high-level optimization might see while (status == 0) and think: "Since status is 0 and nothing in this loop changes it, I'll just treat this as while (true)." Your program would then hang forever, even if the memory at the status address changed to 1.
- Lesson 914 — How `volatile` prevents compiler optimization
- while (true)
- If we removed volatile from the code above, a high-level optimization might see while (status == 0) and think: "Since status is 0 and nothing in this loop changes it, I'll just treat this as while (true)." Your program would then hang forever, even if the memory at the status address changed to 1.
- Lesson 914 — How `volatile` prevents compiler optimization
- while (x < 10)
- While we usually give loops a condition to check at the very start (like while (x < 10)), sometimes we don't know exactly when a loop should end until we are halfway through the code inside it.
- Lesson 293 — Using break to exit infinite loops on condition
- while( )
- In a standard do-while loop, the code inside the braces executes first, and then the condition inside the while( ) parentheses is checked.
- Lesson 280 — Scope of variables declared inside do-while
- while(...)
- Instead of trying to force a complex condition into the while(...) parenthesis, you can run a simple while (1) and put a break right after the line where you read the user's input.
- Lesson 266 — The while loop syntax and execution flowLesson 293 — Using break to exit infinite loops on condition
- while(1)
- An infinite loop created with while(1) or while(true) runs its code block repeatedly until the program is manually stopped or an internal "break" command is triggered.
- Lesson 271 — Infinite loops: while(1) and while(true)Lesson 296 — Readability: when to avoid excessive breaks
- while(condition)
- Take the while(condition) statement and move it to the very end of the code block.
- Lesson 278 — Converting a while loop to a do-while
- while(temp != NULL)
- When working with these lists, a while(temp != NULL) loop will cause an infinite loop because NULL no longer exists!
- Lesson 1004 — Circular doubly linked lists
- while(true)
- An infinite loop created with while(1) or while(true) runs its code block repeatedly until the program is manually stopped or an internal "break" command is triggered.
- Lesson 271 — Infinite loops: while(1) and while(true)Lesson 296 — Readability: when to avoid excessive breaks
- whiteboard
- Think of a normal variable like a whiteboard in a meeting room that gets erased every time the meeting ends.
- Lesson 910 — The `const` qualifier on variablesLesson 920 — The `static` keyword inside functions
- whitespace
- In C, the %s specifier reads characters until it encounters whitespace—this includes spaces, tabs, or new lines.
- Lesson 422 — Scanning strings with `%s` and `scanf` limitations
- whole bag
- We take the weight of the whole bag and divide it by the weight of one apple.
- Lesson 388 — Calculating array size with `sizeof`
- wholeNumber
- Even the wholeNumber of 10.0 gets the full treatment, appearing as 10.000000.
- Lesson 52 — Printing decimals with `%f`
- width
- If you have three variables representing the dimensions of a box (length, width, height), putting them on one line makes it clear they belong together.
- Lesson 76 — Multiple declarations in one lineLesson 624 — Accessing members of nested structs
- WIFEXITED
- Use wait(&status) to collect a child's exit info, then use WIFEXITED and WEXITSTATUS to decode how the child finished.
- Lesson 1077 — Capturing child exit status
- WIFEXITED(status)
- WIFEXITED(status): Returns true if the child terminated normally (e.g., return 0 or exit()).
- Lesson 1077 — Capturing child exit status
- wild pointer
- If you declare a pointer using int *ptr; without giving it an address, it becomes a wild pointer.
- Lesson 459 — Initializing pointers to NULL
- will force the result to be
- Any position in the mask that is 0 will force the result to be 0 (the "blocked" part of the stencil).
- Lesson 180 — Masking bits with `&`
- will not
- The strncpy function has a specific quirk you must remember: if the source string is longer than the limit you set, strncpy will fill the destination buffer but will not add the null terminator (\0) at the end.
- Lesson 848 — Copying strings safely with `strncpy`
- Windows
- On Windows, you press Ctrl+Z and then hit Enter.
- Lesson 270 — Reading input until EOF with whileLesson 681 — EOF (End Of File) explained
- with signed integers (the standard
- One quirk you will notice when using ~ with signed integers (the standard int) is that the result often looks like a completely different negative number.
- Lesson 178 — Bitwise NOT `~` (Complement)
- with the
- If we simply swapped the 7 with the 12, our array would become {2, 5, 8, 7, 12}.
- Lesson 1049 — Insertion Sort: Shifting elements
- word
- In reality, the CPU reads memory in "chunks"—usually 4 or 8 bytes at a time (called a word).
- Lesson 337 — Positional matching of argumentsLesson 574 — Performance cost of unaligned access
- words
- In reality, the CPU has "large hands." It doesn't pick up one byte at a time; it grabs memory in fixed-size blocks called words.
- Lesson 571 — CPU word size and alignment
- Work from the inside out
- To safely free a dynamically allocated struct, you must follow a simple rule: Work from the inside out. You must free every pointer member inside the struct before you free the pointer to the struct itself.
- Lesson 621 — Freeing dynamically allocated structs
- write
- The read and write system calls move raw sequences of bytes between file descriptors and memory buffers without any formatting or translation.
- Lesson 386 — Accessing elements with the `[]` operatorLesson 1075 — Process duplication and copy-on-writeLesson 1089 — Signal safety and reentrant functionsLesson 1097 — Reading and writing raw bytesLesson 1101 — Creating pipes with pipe()Lesson 1104 — Piping data between parent and child
- write end
- Imagine a literal physical pipe: you pour water into one end (the write end), and it flows out the other (the read end).
- Lesson 1100 — Anatomy of a pipe
- write()
- Non-blocking I/O allows your program to remain responsive by forcing read() and write() to return immediately with a "try again" status instead of pausing execution.
- Lesson 1089 — Signal safety and reentrant functionsLesson 1092 — File descriptors vs FILE pointersLesson 1098 — Non-blocking I/O basicsLesson 1106 — Introduction to named pipes (FIFOs)
- Writer
- By placing a new \0 (null terminator) at the writer position, you tell C that the string ends earlier than it used to.
- Lesson 444 — Removing a character from a string
- writing
- A Read-Write Lock (pthread_rwlock_t) distinguishes between reading and writing.
- Lesson 1138 — Read-write locks basics
- wrongWay
- In the code above, wrongWay fails because the division happens between two integers before the result is moved into the float variable.
- Lesson 154 — Floating-point division
X
- x * 2
- Modern compilers are excellent at optimizing x * 2 into x << 1 automatically.
- Lesson 1195 — Bitwise operations for speed
- x + 1
- For example, if you try to write (x + 1) = 5;, the computer complains because x + 1 is just a temporary result (a letter), not a permanent mailbox where the 5 can live.
- Lesson 191 — L-values vs R-valuesLesson 934 — What 'Undefined Behavior' actually means
- x << -1
- Don't shift by negative numbers: While it might seem logical that x << -1 should just be x >> 1, C does not work this way.
- Lesson 187 — Shift operator constraints
- x << 1
- Modern compilers are excellent at optimizing x * 2 into x << 1 automatically.
- Lesson 186 — Bit shifting as multiplication/divisionLesson 1195 — Bitwise operations for speed
- x << 2
- x << 2 is $x \times 2^2$ (or $x \times 4$)
- Lesson 186 — Bit shifting as multiplication/division
- x << 3
- x << 3 is $x \times 2^3$ (or $x \times 8$)
- Lesson 186 — Bit shifting as multiplication/division
- x = 10
- If you try to use that variable before assigning it a value (e.g., x = 10;), you aren't starting at zero; you are starting with whatever random junk happens to be sitting in that memory slot.
- Lesson 220 — Definition of a side effectLesson 339 — Local scope of parametersLesson 939 — Using uninitialized variablesLesson 1143 — Atomic load and storeLesson 1172 — Principles of Unit Testing
- x = 10; x = 20
- Normally, if you write x = 10; x = 20; in a row, a smart compiler skips the first line because it seems useless.
- Lesson 1147 — Volatile vs Atomic
- x = 5
- In most programming languages, you think of an assignment (like x = 5;) as a command that just "happens." You tell the computer to put 5 into x, and it’s done.
- Lesson 197 — Assignment expression return valueLesson 221 — Sequence point definitionLesson 255 — Common mistake: assignment (=) vs equality (==)
- x = 5 + 2
- This is why, in the line x = 5 + 2;, the computer calculates 5 + 2 first and then performs the assignment.
- Lesson 212 — Operator precedence table
- x = x - 1
- If you are just subtracting 1 on a line by itself, --x; works exactly like x = x - 1;.
- Lesson 200 — Prefix decrement `--x`
- x = x | 5
- For example, if you want to turn on a specific bit (using OR) or mask out certain bits (using AND), you might write x = x | 5;.
- Lesson 195 — Compound bitwise assignments
- x == 5
- If you write x == 5, you are asking the computer, "Is the value currently inside x the same as 5?" The computer answers this question with either a 1 (true) or a 0 (false).
- Lesson 255 — Common mistake: assignment (=) vs equality (==)
- x > 10
- The Condition: A test that results in true or false (e.g., x > 10).
- Lesson 252 — The ternary operator (?:) as a shortcut
- x > y + z
- In the example x > y + z, C calculates y + z first because addition outranks comparison.
- Lesson 219 — Common precedence errors
- x >> 1
- Don't shift by negative numbers: While it might seem logical that x << -1 should just be x >> 1, C does not work this way.
- Lesson 187 — Shift operator constraints
- x--
- When you use x-- in a line of code, C uses the original value of x for whatever calculation is happening right now, and only after that calculation is finished does it subtract one from the variable.
- Lesson 201 — Postfix decrement `x--`
- x/nfu <address>
- The command follows a specific pattern: x/nfu <address>.
- Lesson 839 — Examining raw memory with `x`
- x++
- With x++, the program uses the current value of x for whatever math or printing is happening right now, and only then bumps the value up by one.
- Lesson 199 — Postfix increment `x++`Lesson 202 — Differences in expression resultsLesson 204 — Common increment pitfallsLesson 223 — Sequence points in logic `&&` and `||`Lesson 226 — Function call sequence pointsLesson 370 — Macros vs. Inline functions
- x86
- The two main titans you will encounter are x86 (Complex Instruction Set) and ARM (Reduced Instruction Set).
- Lesson 963 — Platform-specific assembly (x86 vs ARM)
Y
- y + z
- In the example x > y + z, C calculates y + z first because addition outranks comparison.
- Lesson 219 — Common precedence errors
- YELLOW
- Because C lacks true namespacing for enums, the names RED, YELLOW, and OK become global constants.
- Lesson 662 — Default integer values in enumsLesson 666 — Scoped enum limitations in C
- You cannot change the characters
- There is one major rule when using pointers with string literals: You cannot change the characters.
- Lesson 479 — String literals as `char` pointers
- Your current accuracy is 95%
- When you run this code, the output will look perfectly normal: Your current accuracy is 95%. The compiler consumes both symbols but only displays one to the user.
- Lesson 690 — Escaping the percent sign %%
- Your health is: -20
- On one run, this might print Your health is: -20.
- Lesson 939 — Using uninitialized variables
- Your health is: 32747
- On another, it might print Your health is: 32747.
- Lesson 939 — Using uninitialized variables
Z
- zero
- The most important rule in C arrays is that we start counting from zero.
- Lesson 386 — Accessing elements with the `[]` operatorLesson 410 — Accessing elements using `[row][col]`
- zero extra memory
- This technique is powerful because it requires zero extra memory beyond a single head pointer.
- Lesson 579 — Building a simple free list
- zero performance penalty
- This happens before the program even runs, meaning there is zero performance penalty compared to calling printf manually.
- Lesson 975 — Implementing a generic 'Print' macro
- zero-based indexing
- Remember that C uses zero-based indexing.
- Lesson 387 — Modifying individual array elements
- zero-indexed
- Because C arrays are zero-indexed, a 10-element array starts at index 0 and ends at index 9.
- Lesson 405 — Avoiding off-by-one errors in loops
- zero-initialization overhead
- This process is known as zero-initialization overhead.
- Lesson 545 — Zero-initialization overhead
- zeros
- In C, those empty seats on the right are always filled with zeros.
- Lesson 183 — Left shift `<<` mechanics
- zipCode
- It prevents "namespace pollution," where you might accidentally mix up a zipCode variable for a user with a zipCode variable for a shipping warehouse.
- Lesson 623 — Defining a struct inside another struct