加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

_Generic关键字及其语法和应用(C11标准),C语言_Generic详解

发布时间:2020-12-15 17:32:55 所属栏目:百科 来源:网络整理
导读:对接触过面向对象程序设计的程序员来讲,相信各位对泛型编程并不陌生。在 C11 标准中,_Generic 关键字可以让 C 语言也如同 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 <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdint.h>
#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 所示。


图 1 类型不匹配

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

    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'

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读