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:

    // 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:

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

2. Storage Class Specifiers

While not "data types" themselves, these keywords determine the lifetime, visibility (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:

    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:

    // Without typedef
    unsigned long long int population;
    
    // With typedef
    typedef unsigned long long int uint64;
    uint64 population;
    
  • With Structs:

    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:

    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
    }