Skip to content

Advanced C Type Qualifiers & Concepts 类型修饰符与其它概念

1. Advanced Type Qualifiers

Qualifiers add special properties to variables. We previously discussed const and volatile. Here is the deep dive into restrict and _Atomic.

A. restrict (Introduced in C99)

  • Definition: A keyword used only with pointers.

  • The Promise: It tells the compiler that for the lifetime of the pointer, only this specific pointer (or values directly derived from it) will be used to access the object it points to.

  • Meaning: "I promise this memory block does not overlap with any other pointer in this scope."

  • Purpose: Optimization. It allows the compiler to cache values in registers aggressively because it knows the value won't be changed "behind its back" by another pointer (a concept called pointer aliasing).

  • Example:

    c // The compiler assumes src and dst might overlap without 'restrict' // With 'restrict', the compiler can optimize the copy loop. void update_values(int *restrict ptrA, int *restrict ptrB, int *n) { *ptrA += *n; *ptrB += *n; }

B. _Atomic (Introduced in C11)

  • Definition: Specifies that access to a variable is atomic (indivisible).

  • Use: Crucial for multi-threaded programming. It ensures that reading or writing to the variable cannot be interrupted by another thread, preventing data races without needing explicit locks (mutexes).

  • Example:

    c _Atomic int counter = 0; // Thread-safe integer


2. Storage Class Specifiers

While not "data types" themselves, these keywords determine the lifetimevisibility (scope), and storage location of a variable.

Specifier Lifetime Scope Description
auto Block Local Default for local variables. Stored on the stack.
register Block Local Hint to store the variable in a CPU register for speed (address & cannot be taken).
static Program Local/File Preserves value between function calls (local) or limits visibility to the current file (global).
extern Program Global Declares a variable that is defined in another file (linking).
  • Example of static:

    c void counter() { static int count = 0; // Initialized only ONCE count++; printf("%d ", count); } // Calling counter() 3 times prints: 1 2 3 (not 1 1 1)


3. The typedef Keyword

typedef does not create a new type; it creates a new name (alias) for an existing type. This is vital for code readability and portability.

  • Simplifying Complex Types:

    ```c // Without typedef unsigned long long int population;

    // With typedef typedef unsigned long long int uint64; uint64 population; ```

  • With Structs:

    ```c typedef struct { int x; int y; } Point;

    Point p1; // No need to write 'struct Point p1' ```


4. Function Pointers

In C, functions have memory addresses, just like variables. You can store a function's address in a pointer variable. This allows you to pass functions as arguments (callbacks).

  • Syntax: ReturnType (*PointerName)(ParameterTypes);

  • Example:

    ```c int add(int a, int b) { return a + b; }

    int main() { // Declare a function pointer named 'op' int (*op)(int, int);

    // Point it to the 'add' function
    op = add;
    
    // Use it
    int result = op(5, 3); // result is 8
    

    } ```