跳转到内容

C 语言 C11 新特性

来自代码酷


C11(也称为ISO/IEC 9899:2011)是C语言的第三个官方标准,于2011年发布。它在C99的基础上引入了多项新特性,旨在提高代码的安全性、可读性和性能。本教程将详细介绍C11的核心特性,并提供实际代码示例。

概述[编辑 | 编辑源代码]

C11标准的主要目标包括:

  • 改进对多线程编程的支持
  • 增强类型安全性
  • 提供更好的内存模型
  • 引入新的标准库功能
  • 保持与C99的向后兼容性

主要新特性[编辑 | 编辑源代码]

多线程支持(<threads.h>)[编辑 | 编辑源代码]

C11首次在标准库中引入了多线程支持,包括线程创建、互斥锁和条件变量等基本同步原语。

#include <stdio.h>
#include <threads.h>

int print_thread(void *arg) {
    printf("Hello from thread!\n");
    return 0;
}

int main() {
    thrd_t thread;
    if (thrd_create(&thread, print_thread, NULL) == thrd_success) {
        thrd_join(thread, NULL);
    }
    return 0;
}

输出:

Hello from thread!

泛型选择(_Generic)[编辑 | 编辑源代码]

_Generic关键字允许根据表达式的类型选择不同的代码路径,类似于C++的函数重载。

#include <stdio.h>

#define print_type(x) _Generic((x), \
    int: "int", \
    float: "float", \
    double: "double", \
    default: "unknown" \
)

int main() {
    int i = 0;
    float f = 0.0f;
    printf("i is of type: %s\n", print_type(i));
    printf("f is of type: %s\n", print_type(f));
    return 0;
}

输出:

i is of type: int
f is of type: float

匿名结构体和联合体[编辑 | 编辑源代码]

C11允许在结构体和联合体中嵌套匿名成员,简化了对嵌套成员的访问。

#include <stdio.h>

struct point {
    union {
        struct { int x, y; };
        int coords[2];
    };
};

int main() {
    struct point p = {.x = 10, .y = 20};
    printf("x=%d, y=%d\n", p.x, p.coords[1]);
    return 0;
}

输出:

x=10, y=20

边界检查函数(<stdalign.h>和<stdalign.h>)[编辑 | 编辑源代码]

C11引入了一组边界检查函数,如gets_s替代不安全的gets函数。

#include <stdio.h>
#include <string.h>

int main() {
    char buf[10];
    gets_s(buf, sizeof(buf)); // 安全的输入函数
    printf("You entered: %s\n", buf);
    return 0;
}

静态断言(_Static_assert)[编辑 | 编辑源代码]

编译时断言,用于在编译期间检查条件。

#include <assert.h>

_Static_assert(sizeof(int) == 4, "int must be 4 bytes");

int main() {
    return 0;
}

对齐说明符(_Alignas和_Alignof)[编辑 | 编辑源代码]

C11提供了更直观的方式来处理内存对齐。

#include <stdio.h>
#include <stdalign.h>

int main() {
    alignas(16) int aligned_data[4];
    printf("Alignment: %zu\n", alignof(aligned_data));
    return 0;
}

输出:

Alignment: 16

无锁原子操作(<stdatomic.h>)[编辑 | 编辑源代码]

C11引入了原子类型和操作,支持无锁编程。

#include <stdio.h>
#include <stdatomic.h>
#include <threads.h>

atomic_int counter = ATOMIC_VAR_INIT(0);

int increment(void *arg) {
    for (int i = 0; i < 100000; ++i) {
        atomic_fetch_add(&counter, 1);
    }
    return 0;
}

int main() {
    thrd_t t1, t2;
    thrd_create(&t1, increment, NULL);
    thrd_create(&t2, increment, NULL);
    thrd_join(t1, NULL);
    thrd_join(t2, NULL);
    printf("Counter: %d\n", atomic_load(&counter));
    return 0;
}

输出:

Counter: 200000

实际应用案例[编辑 | 编辑源代码]

案例1:多线程数据处理[编辑 | 编辑源代码]

使用C11线程API处理并行数据计算。

graph TD A[主线程] --> B[创建工作线程1] A --> C[创建工作线程2] B --> D[处理数据块1] C --> E[处理数据块2] D --> F[合并结果] E --> F F --> G[输出最终结果]

案例2:类型安全的泛型打印函数[编辑 | 编辑源代码]

利用_Generic实现类型安全的打印函数。

#include <stdio.h>

void print_int(int x) { printf("int: %d\n", x); }
void print_double(double x) { printf("double: %f\n", x); }

#define print(x) _Generic((x), \
    int: print_int, \
    double: print_double \
)(x)

int main() {
    print(42);
    print(3.14);
    return 0;
}

输出:

int: 42
double: 3.140000

数学公式示例[编辑 | 编辑源代码]

C11中的一些特性可以用数学公式表示。例如,原子操作的顺序一致性可以表示为:

对于所有原子操作A和B如果A在B之前执行那么A对所有线程的可见性B对所有线程的可见性

总结[编辑 | 编辑源代码]

C11标准为C语言带来了现代化的特性,包括:

  • 原生多线程支持
  • 改进的类型系统
  • 更好的内存模型
  • 增强的安全性特性
  • 更灵活的代码组织方式

虽然并非所有编译器都完全支持C11的所有特性,但这些新功能为C程序员提供了更强大的工具来编写高效、安全的代码。