Tianya
发布于 2026-07-23 / 7 阅读
0
0

C语言_Generic

1. 简介

_Generic 是 C11 标准引入的类型泛型选择符,可以理解为「基于数据类型的 switch 语句」—— 它能根据表达式的类型,选择对应的代码分支执行,核心作用是实现类型无关的通用接口(类似 C++ 的函数重载,但更轻量)。

简单比喻:你有一个 "通用计算器" 函数,传入整数就用整数加法逻辑,传入浮点数就用浮点数加法逻辑,_Generic 就是帮你判断参数类型并选择对应逻辑的 "开关"。

2. 基本语法

_Generic( 表达式, 
	类型1: 分支1, 
	类型2: 分支2, 
	..., 
	默认类型: 默认分支 // 可选,无匹配时若没有默认分支会编译报错 
)

核心规则

  1. 先判断「表达式」的类型(仅判断类型,不执行表达式);
  2. 匹配第一个完全一致的类型分支,执行对应分支的代码;
  3. 分支可以是常量、表达式、函数指针、函数调用等。

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. 注意事项

  • 类型匹配严格intlongfloatdouble 是不同类型,不会自动转换匹配;
    例如:add(10L, 20L)(long 类型)会编译报错,需补充 long: add_long 分支。

  • 表达式不执行_Generic 仅判断类型,不会计算表达式的值;
    例如:_Generic(10+20, int: 1, float: 2)10+20 不会计算,仅判断结果类型是 int

  • 仅编译期生效:类型判断在编译阶段完成,不会产生运行时开销,性能无损耗。

  • 兼容性:仅支持 C11 及以上标准(GCC、Clang、MSVC 2015+ 均支持)。


评论