1. 简介
_Generic 是 C11 标准引入的类型泛型选择符,可以理解为「基于数据类型的 switch 语句」—— 它能根据表达式的类型,选择对应的代码分支执行,核心作用是实现类型无关的通用接口(类似 C++ 的函数重载,但更轻量)。
简单比喻:你有一个 "通用计算器" 函数,传入整数就用整数加法逻辑,传入浮点数就用浮点数加法逻辑,_Generic 就是帮你判断参数类型并选择对应逻辑的 "开关"。
2. 基本语法
_Generic( 表达式,
类型1: 分支1,
类型2: 分支2,
...,
默认类型: 默认分支 // 可选,无匹配时若没有默认分支会编译报错
)
核心规则:
- 先判断「表达式」的类型(仅判断类型,不执行表达式);
- 匹配第一个完全一致的类型分支,执行对应分支的代码;
- 分支可以是常量、表达式、函数指针、函数调用等。
3. 使用示例
3.1 基础用法
#include <stdio.h>
#define TYPE_PRINT(x) _Generic((x), \
int: printf("类型:int,值:%d\n", x), \
float: printf("类型:float,值:%.2f\n", x), \
double: printf("类型:double,值:%.3f\n", x), \
default: printf("类型:其他,值:%c\n", x) \
)
int main() {
int a = 10;
float b = 3.14;
double c = 2.718;
char d = 'A'; // 基于类型输出不同提示
TYPE_PRINT(a); // 输出:类型:int,值:10
TYPE_PRINT(b); // 输出:类型:float,值:3.14
TYPE_PRINT(c); // 输出:类型:double,值:2.718
TYPE_PRINT(d); // 输出:类型:其他,值:A return 0;
}
3.2 模拟函数重载
#include <stdio.h>
// 不同类型的加法函数
int add_int(int a, int b) {
printf("整数加法:");
return a + b;
}
float add_float(float a, float b) {
printf("浮点数加法:");
return a + b;
}
double add_double(double a, double b) {
printf("双精度加法:");
return a + b;
}
// 泛型加法接口
#define add(x, y) _Generic((x), \
int: add_int, \
float: add_float, \
double: add_double \
)(x, y) // 注意:这里是函数指针调用,括号要跟在外面
int main() {
printf("%d\n", add(10, 20)); // 输出:整数加法:30
printf("%.2f\n", add(1.5f, 2.5f)); // 输出:浮点数加法:4.00
printf("%.3f\n", add(1.111, 2.222));//输出:双精度加法:3.333 return 0;
}
4. 注意事项
-
类型匹配严格:
int和long、float和double是不同类型,不会自动转换匹配;
例如:add(10L, 20L)(long 类型)会编译报错,需补充long: add_long分支。 -
表达式不执行:
_Generic仅判断类型,不会计算表达式的值;
例如:_Generic(10+20, int: 1, float: 2)中10+20不会计算,仅判断结果类型是int。 -
仅编译期生效:类型判断在编译阶段完成,不会产生运行时开销,性能无损耗。
-
兼容性:仅支持 C11 及以上标准(GCC、Clang、MSVC 2015+ 均支持)。