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 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:
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} ```