Content list
About
Chapter 1: Getting started with C Language
Section 1.1: Hello World
Section 1.2: Original "Hello, World!" in K&R C
Chapter 2: Comments
Section 2.1: Commenting using the preprocessor
Section 2.2: /* */ delimited comments
Section 2.3: // delimited comments
Section 2.4: Possible pitfall due to trigraphs
Chapter 3: Data Types
Section 3.1: Interpreting Declarations
Section 3.2: Fixed Width Integer Types (since C99)
Section 3.3: Integer types and constants
Section 3.4: Floating Point Constants
Section 3.5: String Literals
Chapter 4: Operators
Section 4.1: Relational Operators
Section 4.2: Conditional Operator/Ternary Operator
Section 4.3: Bitwise Operators
Section 4.4: Short circuit behavior of logical operators
Section 4.5: Comma Operator
Section 4.6: Arithmetic Operators
Section 4.7: Access Operators
Section 4.8: sizeof Operator
Section 4.9: Cast Operator
Section 4.10: Function Call Operator
Section 4.11: Increment / Decrement
Section 4.12: Assignment Operators
Section 4.13: Logical Operators
Section 4.14: Pointer Arithmetic
Section 4.15: _Alignof
Chapter 5: Boolean
Section 5.1: Using stdbool.h
Section 5.2: Using #define
Section 5.3: Using the Intrinsic (built-in) Type _Bool
Section 5.4: Integers and pointers in Boolean expressions
Section 5.5: Defining a bool type using typedef
Chapter 6: Strings
Section 6.1: Tokenisation: strtok(), strtok_r() and strtok_s()
Section 6.2: String literals
Section 6.3: Calculate the Length: strlen()
Section 6.4: Basic introduction to strings
Section 6.5: Copying strings
Section 6.6: Iterating Over the Characters in a String
Section 6.7: Creating Arrays of Strings
Section 6.8: Convert Strings to Number: atoi(), atof() (dangerous, don't use them)
Section 6.9: string formatted data read/write
Section 6.10: Find first/last occurrence of a specific character: strchr(), strrchr()
Section 6.11: Copy and Concatenation: strcpy(), strcat()
Section 6.12: Comparsion: strcmp(), strncmp(), strcasecmp(), strncasecmp()
Section 6.13: Safely convert Strings to Number: strtoX functions
Section 6.14: strspn and strcspn
Chapter 7: Literals for numbers, characters and strings
Section 7.1: Floating point literals
Section 7.2: String literals
Section 7.3: Character literals
Section 7.4: Integer literals
Chapter 8: Compound Literals
Section 8.1: Definition/Initialisation of Compound Literals
Chapter 9: Bit-fields
Section 9.1: Bit-fields
Section 9.2: Using bit-fields as small integers
Section 9.3: Bit-field alignment
Section 9.4: Don'ts for bit-fields
Section 9.5: When are bit-fields useful?
Chapter 10: Arrays
Section 10.1: Declaring and initializing an array
Section 10.2: Iterating through an array eciently and row-major order
Section 10.3: Array length
Section 10.4: Passing multidimensional arrays to a function
Section 10.5: Multi-dimensional arrays
Section 10.6: Define array and access array element
Section 10.7: Clearing array contents (zeroing)
Section 10.8: Setting values in arrays
Section 10.9: Allocate and zero-initialize an array with user defined size
Section 10.10: Iterating through an array using pointers
Chapter 11: Linked lists
Section 11.1: A doubly linked list
Section 11.2: Reversing a linked list
Section 11.3: Inserting a node at the nth position
Section 11.4: Inserting a node at the beginning of a singly linked list
Chapter 12: Enumerations
Section 12.1: Simple Enumeration
Section 12.2: enumeration constant without typename
Section 12.3: Enumeration with duplicate value
Section 12.4: Typedef enum
Chapter 13: Structs
Section 13.1: Flexible Array Members
Section 13.2: Typedef Structs
Section 13.3: Pointers to structs
Section 13.4: Passing structs to functions
Section 13.5: Object-based programming using structs
Section 13.6: Simple data structures
Chapter 14: Standard Math
Section 14.1: Power functions - pow(), powf(), powl()
Section 14.2: Double precision floating-point remainder: fmod()
Section 14.3: Single precision and long double precision floating-point remainder: fmodf(), fmodl()
Chapter 15: Iteration Statements/Loops: for, while, do-while
Section 15.1: For loop
Section 15.2: Loop Unrolling and Du's Device
Section 15.3: While loop
Section 15.4: Do-While loop
Section 15.5: Structure and flow of control in a for loop
Section 15.6: Infinite Loops
Chapter 16: Selection Statements
Section 16.1: if () Statements
Section 16.2: Nested if()...else VS if()..else Ladder
Section 16.3: switch () Statements
Section 16.4: if () ... else statements and syntax
Section 16.5: if()...else Ladder Chaining two or more if () ... else statements
Chapter 17: Initialization
Section 17.1: Initialization of Variables in C
Section 17.2: Using designated initializers
Section 17.3: Initializing structures and arrays of structures
Chapter 18: Declaration vs Definition
Section 18.1: Understanding Declaration and Definition
Chapter 19: Command-line arguments
Section 19.1: Print the arguments to a program and convert to integer values
Section 19.2: Printing the command line arguments
Section 19.3: Using GNU getopt tools
Chapter 20: Files and I/O streams
Section 20.1: Open and write to file
Section 20.2: Run process
Section 20.3: fprintf
Section 20.4: Get lines from a file using getline()
Section 20.5: fscanf()
Section 20.6: Read lines from a file
Section 20.7: Open and write to a binary file
Chapter 21: Formatted Input/Output
Section 21.1: Conversion Specifiers for printing
Section 21.2: The printf() Function
Section 21.3: Printing format flags
Section 21.4: Printing the Value of a Pointer to an Object
Section 21.5: Printing the Dierence of the Values of two Pointers to an Object
Section 21.6: Length modifiers
Chapter 22: Pointers
Section 22.1: Introduction
Section 22.2: Common errors
Section 22.3: Dereferencing a Pointer
Section 22.4: Dereferencing a Pointer to a struct
Section 22.5: Const Pointers
Section 22.6: Function pointers
Section 22.7: Polymorphic behaviour with void pointers
Section 22.8: Address-of Operator ( & )
Section 22.9: Initializing Pointers
Section 22.10: Pointer to Pointer
Section 22.11: void* pointers as arguments and return values to standard functions
Section 22.12: Same Asterisk, Dierent Meanings
Chapter 23: Sequence points
Section 23.1: Unsequenced expressions
Section 23.2: Sequenced expressions
Section 23.3: Indeterminately sequenced expressions
Chapter 24: Function Pointers
Section 24.1: Introduction
Section 24.2: Returning Function Pointers from a Function
Section 24.3: Best Practices
Section 24.4: Assigning a Function Pointer
Section 24.5: Mnemonic for writing function pointers
Section 24.6: Basics
Chapter 25: Function Parameters
Section 25.1: Parameters are passed by value
Section 25.2: Passing in Arrays to Functions
Section 25.3: Order of function parameter execution
Section 25.4: Using pointer parameters to return multiple values
Section 25.5: Example of function returning struct containing values with error codes
Chapter 26: Pass 2D-arrays to functions
Section 26.1: Pass a 2D-array to a function
Section 26.2: Using flat arrays as 2D arrays
Chapter 27: Error handling
Section 27.1: errno
Section 27.2: strerror
Section 27.3: perror
Chapter 28: Undefined behavior
Section 28.1: Dereferencing a pointer to variable beyond its lifetime
Section 28.2: Copying overlapping memory
Section 28.3: Signed integer overflow
Section 28.4: Use of an uninitialized variable
Section 28.5: Data race
Section 28.6: Read value of pointer that was freed
Section 28.7: Using incorrect format specifier in printf
Section 28.8: Modify string literal
Section 28.9: Passing a null pointer to printf %s conversion
Section 28.10: Modifying any object more than once between two sequence points
Section 28.11: Freeing memory twice
Section 28.12: Bit shifting using negative counts or beyond the width of the type
Section 28.13: Returning from a function that's declared with `_Noreturn` or `noreturn` function specifier
Section 28.14: Accessing memory beyond allocated chunk
Section 28.15: Modifying a const variable using a pointer
Section 28.16: Reading an uninitialized object that is not backed by memory
Section 28.17: Addition or subtraction of pointer not properly bounded
Section 28.18: Dereferencing a null pointer
Section 28.19: Using ush on an input stream
Section 28.20: Inconsistent linkage of identifiers
Section 28.21: Missing return statement in value returning function
Section 28.22: Division by zero
Section 28.23: Conversion between pointer types produces incorrectly aligned result
Section 28.24: Modifying the string returned by getenv, strerror, and setlocale functions
Chapter 29: Random Number Generation
Section 29.1: Basic Random Number Generation
Section 29.2: Permuted Congruential Generator
Section 29.3: Xorshift Generation
Section 29.4: Restrict generation to a given range
Chapter 30: Preprocessor and Macros
Section 30.1: Header Include Guards
Section 30.2: #if 0 to block out code sections
Section 30.3: Function-like macros
Section 30.4: Source file inclusion
Section 30.5: Conditional inclusion and conditional function signature modification
Section 30.6: __cplusplus for using C externals in C++ code compiled with C++ - name mangling
Section 30.7: Token pasting
Section 30.8: Predefined Macros
Section 30.9: Variadic arguments macro
Section 30.10: Macro Replacement
Section 30.11: Error directive
Section 30.12: FOREACH implementation
Chapter 31: Signal handling
Section 31.1: Signal Handling with “signal()”
Chapter 32: Variable arguments
Section 32.1: Using an explicit count argument to determine the length of the va_list
Section 32.2: Using terminator values to determine the end of va_list
Section 32.3: Implementing functions with a `printf()`-like interface
Section 32.4: Using a format string
Chapter 33: Assertion
Section 33.1: Simple Assertion
Section 33.2: Static Assertion
Section 33.3: Assert Error Messages
Section 33.4: Assertion of Unreachable Code
Section 33.5: Precondition and Postcondition
Chapter 34: Generic selection
Section 34.1: Check whether a variable is of a certain qualified type
Section 34.2: Generic selection based on multiple arguments
Section 34.3: Type-generic printing macro
Chapter 35: X-macros
Section 35.1: Trivial use of X-macros for printfs
Section 35.2: Extension: Give the X macro as an argument
Section 35.3: Enum Value and Identifier
Section 35.4: Code generation
Chapter 36: Aliasing and eective type
Section 36.1: Eective type
Section 36.2: restrict qualification
Section 36.3: Changing bytes
Section 36.4: Character types cannot be accessed through non-character types
Section 36.5: Violating the strict aliasing rules
Chapter 37: Compilation
Section 37.1: The Compiler
Section 37.2: File Types
Section 37.3: The Linker
Section 37.4: The Preprocessor
Section 37.5: The Translation Phases
Chapter 38: Inline assembly
Section 38.1: gcc Inline assembly in macros
Section 38.2: gcc Basic asm support
Section 38.3: gcc Extended asm support
Chapter 39: Identifier Scope
Section 39.1: Function Prototype Scope
Section 39.2: Block Scope
Section 39.3: File Scope
Section 39.4: Function scope
Chapter 40: Implicit and Explicit Conversions
Section 40.1: Integer Conversions in Function Calls
Section 40.2: Pointer Conversions in Function Calls
Chapter 41: Type Qualifiers
Section 41.1: Volatile variables
Section 41.2: Unmodifiable (const) variables
Chapter 42: Typedef
Section 42.1: Typedef for Structures and Unions
Section 42.2: Typedef for Function Pointers
Section 42.3: Simple Uses of Typedef
Chapter 43: Storage Classes
Section 43.1: auto
Section 43.2: register
Section 43.3: static
Section 43.4: typedef
Section 43.5: extern
Section 43.6: _Thread_local
Chapter 44: Declarations
Section 44.1: Calling a function from another C file
Section 44.2: Using a Global Variable
Section 44.3: Introduction
Section 44.4: Typedef
Section 44.5: Using Global Constants
Section 44.6: Using the right-left or spiral rule to decipher C declaration
Chapter 45: Structure Padding and Packing
Section 45.1: Packing structures
Section 45.2: Structure padding
Chapter 46: Memory management
Section 46.1: Allocating Memory
Section 46.2: Freeing Memory
Section 46.3: Reallocating Memory
Section 46.4: realloc(ptr, 0) is not equivalent to free(ptr)
Section 46.5: Multidimensional arrays of variable size
Section 46.6: alloca: allocate memory on stack
Section 46.7: User-defined memory management
Chapter 47: Implementation-defined behaviour
Section 47.1: Right shift of a negative integer
Section 47.2: Assigning an out-of-range value to an integer
Section 47.3: Allocating zero bytes
Section 47.4: Representation of signed integers
Chapter 48: Atomics
Section 48.1: atomics and operators
Chapter 49: Jump Statements
Section 49.1: Using return
Section 49.2: Using goto to jump out of nested loops
Section 49.3: Using break and continue
Chapter 50: Create and include header files
Section 50.1: Introduction
Section 50.2: Self-containment
Section 50.3: Minimality
Section 50.4: Notation and Miscellany
Section 50.5: Idempotence
Section 50.6: Include What You Use (IWYU)
Chapter 51: <ctype.h> — character classification & conversion
Section 51.1: Introduction
Section 51.2: Classifying characters read from a stream
Section 51.3: Classifying characters from a string
Chapter 52: Side Eects
Section 52.1: Pre/Post Increment/Decrement operators
Chapter 53: Multi-Character Character Sequence
Section 53.1: Trigraphs
Section 53.2: Digraphs
Chapter 54: Constraints
Section 54.1: Duplicate variable names in the same scope
Section 54.2: Unary arithmetic operators
Chapter 55: Inlining
Section 55.1: Inlining functions used in more than one source file
Chapter 56: Unions
Section 56.1: Using unions to reinterpret values
Section 56.2: Writing to one union member and reading from another
Section 56.3: Dierence between struct and union
Chapter 57: Threads (native)
Section 57.1: Inititialization by one thread
Section 57.2: Start several threads
Chapter 58: Multithreading
Section 58.1: C11 Threads simple example
Chapter 59: Interprocess Communication (IPC)
Section 59.1: Semaphores
Chapter 60: Testing frameworks
Section 60.1: Unity Test Framework
Section 60.2: CMocka
Section 60.3: CppUTest
Chapter 61: Valgrind
Section 61.1: Bytes lost -- Forgetting to free
Section 61.2: Most common errors encountered while using Valgrind
Section 61.3: Running Valgrind
Section 61.4: Adding flags
Chapter 62: Common C programming idioms and developer practices
Section 62.1: Comparing literal and variable
Section 62.2: Do not leave the parameter list of a function blank — use void
Chapter 63: Common pitfalls
Section 63.1: Mixing signed and unsigned integers in arithmetic operations
Section 63.2: Macros are simple string replacements
Section 63.3: Forgetting to copy the return value of realloc into a temporary
Section 63.4: Forgetting to allocate one extra byte for \0
Section 63.5: Misunderstanding array decay
Section 63.6: Forgetting to free memory (memory leaks)
Section 63.7: Copying too much
Section 63.8: Mistakenly writing = instead of == when comparing
Section 63.9: Newline character is not consumed in typical scanf() call
Section 63.10: Adding a semicolon to a #define
Section 63.11: Incautious use of semicolons
Section 63.12: Undefined reference errors when linking
Section 63.13: Checking logical expression against 'true'
Section 63.14: Doing extra scaling in pointer arithmetic
Section 63.15: Multi-line comments cannot be nested
Section 63.16: Ignoring return values of library functions
Section 63.17: Comparing floating point numbers
Section 63.18: Floating point literals are of type double by default
Section 63.19: Using character constants instead of string literals, and vice versa
Section 63.20: Recursive function — missing out the base condition
Section 63.21: Overstepping array boundaries
Section 63.22: Passing unadjacent arrays to functions expecting "real" multidimensional arrays
Credits
You may also like
The C Notes for Professionals book is compiled from Stack Overflow Documentation, the content is written by the beautiful people at Stack Overflow. Text content is released under Creative Commons BY-SA. See credits at the end of this book whom contributed to the various chapters. Images may be copyright of their respective owners unless otherwise specified
Book created for educational purposes and is not affiliated with C group(s), company(s) nor Stack Overflow. All trademarks belong to their respective company owners