c语言中各个关键词的作用,_Generic关键字及其语法和应用(C11标准),C语言_Generic详解...

对接触过面向对象程序设计的程序员来讲,相信各位对泛型编程并不陌生。在 C11 标准中,_Generic 关键字可以让 C 语言也如同 C++ 等面向对象程序设计语言一样,使其支持轻量级的泛型编程设计。

利用 _Generic 关键字,可以简单地将一组具有不同类型却有相同功能的函数抽象为一个统一的接口,语法形式如下:

generic-selection:

_Generic (assignment-expression, generic-assoc-list)

generic-assoc-list:

generic-association

generic-assoc-list , generic-association

generic-association:

type-name : assignment-expression

default : assignment-expression

与 sizeof 与 typeof 类似,_Generic 中的 assignment-expression 只用于在编译时获得该表达式的类型,而不会对该表达式做运行时计算,如以下代码所示。

#include

#include

#include

#include

#define getTypeName(x) _Generic((x), _Bool:"_Bool",\

char: "char", \

signed char: "signed char", \

unsigned char: "unsigned char", \

short int: "short int", \

unsigned short int: "unsigned short int", \

int: "int", \

unsigned int: "unsigned int", \

long int: "long int", \

unsigned long int: "unsigned long int", \

long long int: "long long int", \

unsigned long long int: "unsigned long long int", \

float: "float", \

double: "double", \

long double: "long double", \

char *: "pointer to char", \

void *: "pointer to void", \

int *: "pointer to int")

int main(void)

{

char c = 'a';

size_t s;

ptrdiff_t p;

intmax_t i;

int arr[3] = { 0 };

printf("s is '%s'\n", getTypeName(s));

printf("p is '%s'\n", getTypeName(p));

printf("i is '%s'\n", getTypeName(i));

printf("c is '%s'\n", getTypeName(c));

printf("arr is '%s'\n", getTypeName(arr));

printf("0x7FFFFFFF is '%s'\n", getTypeName(0x7FFFFFFF));

printf("0xFFFFFFFF is '%s'\n", getTypeName(0xFFFFFFFF));

printf("0x7FFFFFFFU is '%s'\n", getTypeName(0x7FFFFFFFU));

}

运行结果为:

s is 'unsigned int'

p is 'int'

i is 'long long int'

c is 'char'

arr is 'pointer to int'

0x7FFFFFFF is 'int'

0xFFFFFFFF is 'unsigned int'

0x7FFFFFFFU is 'unsigned int'

除此之外,还必须保证 generic-association-list 中有与 assignment-expression 类型相同的 generic-association 与之对应,否则编译就会报错。例如,在上面代码的main函数中添加如下两行代码:

float *fp=NULL;

printf("fp is '%s'\n", getTypeName(fp));

很显然,generic-assoc-list 中没有 generic-association 与 fp 相匹配的类型,从而导致编译出错,如图 1 所示。

847eeb917e9142d8bde33399b2c71df3.png

图 1 类型不匹配

要解决图 1 这种类型不匹配时导致的编译错误,你可以在 generic-association-list 中添加 default 处理,那么编译就能够顺利进行,如下面的代码所示:

#define getTypeName(x) _Generic((x), _Bool:"_Bool",\

char: "char", \

signed char: "signed char", \

unsigned char: "unsigned char", \

short int: "short int", \

unsigned short int: "unsigned short int", \

int: "int", \

unsigned int: "unsigned int", \

long int: "long int", \

unsigned long int: "unsigned long int", \

long long int: "long long int", \

unsigned long long int: "unsigned long long int", \

float: "float", \

double: "double", \

long double: "long double", \

char *: "pointer to char", \

void *: "pointer to void", \

int *: "pointer to int",\

default: "other")

现在,如果编译器发现 generic-assoc-list 中没有 generic-association 与 fp 相匹配的类型时,将默认执行 default 处理,运行结果为:

s is 'unsigned int'

p is 'int'

i is 'long long int'

c is 'char'

arr is 'pointer to int'

fp is 'other'

0x7FFFFFFF is 'int'

0xFFFFFFFF is 'unsigned int'

0x7FFFFFFFU is 'unsigned int'

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值