基本表达式 primary expresson
primary-expression:
generic-selection
( expression )
string-literal
constant
identifier
primary expression 包含 5 中具体实现:
identifier constant string-literal generic-selection ( expression )
generic-selection
generic-selection:
_Generic ( assignment-expression , generic-assoc-list ) [注: 注意这儿的 逗号分隔]
generic-assoc-list:
generic-association
generic-assoc-list , generic-association [注: 注意这儿的 逗号分隔]
generic-association:
type-name : assignment-expression 【注:注意这儿的 冒号分隔】
示例
#include <stdio.h> #include <stdlib.h> #include <math.h> #define generic_abs(x) _Generic((x), \ int: abs,\ float: fabs, \ double: fabs \ )(x) int add(int a, int b) { return a+b; } int main(void){ add(5,6); printf("int abs %d \n", generic_abs(-12)); printf("float abs %f \n", generic_abs(-12.04f)); printf("double abs %lf \n", generic_abs(-13.8)); int a = 10; int b = 0; int c = 0; _Generic(a+0.1f, int:b, float:c, default:b)++ ; printf("b = %d, c = %d \n", b, c); _Generic(a+=1.1f, int : b, float:c, default: b)++; printf("a = %d b = %d c = %d \n", a, b, c); return 0; }
输出
int abs 12 float abs 12.040000 double abs 13.800000 b = 0, c = 1 a = 10 b = 1 c = 1
解释: 【来自 https://blog.csdn.net/qq_31243065/article/details/80904613】
前三个printf
generic_abs(-12):执行generic_abs宏,_Generic(泛型)发现-12是int(整型),然后返回abs(x),x(为传入的值)
generic_abs(-12.04f) :执行generic_abs宏,_Generic(泛型)发现-12.04f是float(单精度浮点数型),然后返回fabsf(x),x(为传入的值)
generic_abs(-13.09876):执行generic_abs宏,_Generic(泛型)发现-13.09876是double(双精度浮点数型),然后返回fabs(x),x(为传入的值)
_Generic(a+0.1f,int:b,float:c,default:b)++;
首先a为(int(整型)),然后a + 0.1f会被转换成float(单精度浮点数型),所以_Generic(泛型)发现传入的是float(单精度浮点数型),所以执行float的内容,返回一个c,然后跟着++,所以最终变成c++,然后printf格式化输出b=0,c=1
_Generic(a+=1.1f,int:b,float:c,default:b)++;
首先a为(int(整型)),然后a+=1.1f,执行了+=操作并不会改变a的值,执行完后_Generic(泛型)才进行判断a的类型,因为a的类型为int(整型),所以执行int的操作,返回b,然后跟着++,所以最终变成b++,然后printf格式化输出a=10,b=1,c=1
PS:从此可以得知在_Generic(泛型)中执行+= , =等等的操作都不会改变Generic(泛型)里的参数的值
参考文档
C11新增关键字:_Generic(泛型)
https://blog.csdn.net/qq_31243065/article/details/80904613