(C11) 泛型表达式

2024-05-28 23:04
文章标签 表达式 泛型 c11

本文主要是介绍(C11) 泛型表达式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • ⭐语法
  • ⭐举例
    • 🚩判断对象类型
    • 🚩判断指针
    • 🚩函数重载
    • 🚩嵌套使用
  • END

⭐语法

Ref: 泛型选择 (C11 起) - cppreference.com

关键词:

  • Generic
  • default
_Generic(控制表达式 , 关联列表)  (C11 起) 

关联列表

  • 类型名:表达式
    • 类型名:任何并非可变修改的完整对象类型(即既非 VLA 亦非指向 VLA 的指针)。
    • 表达式:任何类型和值类别的表达式(除了逗号运算符)
  • default:表达式

控制表达式

  • 任何表达式(除了逗号运算符),若不使用 default 关联,则其类型必须与 类型名 之一兼容。

判定解释

控制表达式 的类型经历左值转换。

只在类型域中进行转换

  • 舍弃顶层 cvr 限定符和原子属性
  • 数组到指针/函数到指针变换
  • 不实例化任何副效应或计算任何值

有类型匹配,若其类型与各关联之一的 类型名 兼容,则解释为冒号后的表达式。

无类型匹配,且提供了 default 关联,则解释为其后的表达式。

注意

关联列表 中的任意二个 类型名 不能指定兼容类型。

使用关键词 default 的关联只能有一个。若不使用 default,且无一 类型名 与控制表达式类型兼容,则程序无法编译。

⭐举例

🚩判断对象类型

_Generic可以判断自定义类型。

cvr限定符对类型识别不受影响。

default不是必须写道最后一个,顺序这方面没有限制。

#include <stdbool.h>
#include <stdio.h>struct Node {};#define get_typename(x)             \_Generic((x),                   \default: "other",           \_Bool: "bool",              \int: "int",                 \char: "char",               \struct Node: "struct Node"  \)int main() {_Bool       b = true;char        c = 'a';const int   i = 10;struct Node node;printf("Type of [_Bool] is %s\n", get_typename(b));printf("Type of [char] is %s\n", get_typename(c));printf("Type of [int] is %s\n", get_typename(i));printf("Type of [struct Node] is %s\n", get_typename(node));
}

🚩判断指针

对指针类型的判断仍然使用。

#include <stdio.h>#define get_pointname(x) \_Generic((x),        \int*: "int*",    \void*: "void*",  \default: "other" \)int main() {int   i  = 0;int*  ip = NULL;void* vp = NULL;printf("Type of [int] is [%s]\n", get_pointname(i));printf("Type of [int*] is [%s]\n", get_pointname(ip));printf("Type of [void*] is [%s]\n", get_pointname(vp));
}

🚩函数重载

可以根据类型指定调用的函数,注意参数个数。

下方代码展示在使用_Generic时,并且直接调用的情况。_Generic((x), default: fun)(x)

#include <math.h>
#include <stdio.h>int default_fun() {printf("Line[%d], Func[%s]\n", __LINE__, __func__);return -1;
}#define sqrt(x)                  \_Generic((x),            \float: sqrtf,        \double: sqrt,        \long double: sqrtl,  \default: default_fun \)(x)int main(void) {int         i  = 4;float       f  = 4.0f;double      d  = 4.0;long double ld = 4.0L;printf("[i] sqrt = %d\n", sqrt(i));printf("[float] sqrt = %f\n", sqrt(f));printf("[double] sqrt = %lf\n", sqrt(d));printf("[long double] sqrt = %Lf\n", sqrt(ld));
}

🚩嵌套使用

由于每次_Generic只能判断一个表达式的类型,因此如果是需要用到多参的话,可以嵌套的使用_Generic

#include <stdio.h>#define add(x, y)                              \_Generic((x),                              \int: _Generic((y),                     \int: (int)(x) + (int)(y),          \default: (int)(x) + (double)(y)    \),                                     \default: _Generic((y),                 \int: (double)(x) + (int)(y),       \default: (double)(x) + (double)(y) \)                                      \)int main() {int    i1 = 10;int    i2 = 20;double d1 = 3.14;double d2 = 2.71;printf("%d + %d = %d\n", i1, i2, add(i1, i2));  // 整数加法printf("%f + %f = %f\n", d1, d2, add(d1, d2));  // 浮点数加法printf("%d + %f = %f\n", i1, d2, add(i1, d2));  // 混合加法
}

END

关注我,学习更多C/C++,算法,计算机知识

B站:

👨‍💻主页:天赐细莲 bilibili

这篇关于(C11) 泛型表达式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1011946

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成

Java基础回顾系列-第三天-Lambda表达式

Java基础回顾系列-第三天-Lambda表达式 Lambda表达式方法引用引用静态方法引用实例化对象的方法引用特定类型的方法引用构造方法 内建函数式接口Function基础接口DoubleToIntFunction 类型转换接口Consumer消费型函数式接口Supplier供给型函数式接口Predicate断言型函数式接口 Stream API 该篇博文需重点了解:内建函数式

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

JavaSE(十三)——函数式编程(Lambda表达式、方法引用、Stream流)

函数式编程 函数式编程 是 Java 8 引入的一个重要特性,它允许开发者以函数作为一等公民(first-class citizens)的方式编程,即函数可以作为参数传递给其他函数,也可以作为返回值。 这极大地提高了代码的可读性、可维护性和复用性。函数式编程的核心概念包括高阶函数、Lambda 表达式、函数式接口、流(Streams)和 Optional 类等。 函数式编程的核心是Lambda

逻辑表达式,最小项

目录 得到此图的逻辑电路 1.画出它的真值表 2.根据真值表写出逻辑式 3.画逻辑图 逻辑函数的表示 逻辑表达式 最小项 定义 基本性质 最小项编号 最小项表达式   得到此图的逻辑电路 1.画出它的真值表 这是同或的逻辑式。 2.根据真值表写出逻辑式   3.画逻辑图   有两种画法,1是根据运算优先级非>与>或得到,第二种是采

Java泛型类型解析

解析泛型类型 获取字段泛型类型 **java.lang.reflect.Field#getGenericType**: 作用:返回字段的泛型类型。返回类型:Type。如果字段是一个泛型类型,这个方法将返回一个表示这个泛型类型的 Type 对象,比如 ParameterizedType,TypeVariable 等等。如果字段不是泛型类型,这个方法将返回字段的具体类型,即 Class 对象。示例

将浮点型算式的中缀表达式转换成后缀表达式并算出式子结果

最近因为需要了解如何将在Win应用程序控制台输入的算式表达式转化成其后缀表达式的算法,所以在网上搜索了一下,看到许多人的程序都只是对应于运算数在0~9的范围内的整型运算式,所以自己就写了一个可以计算浮点型算式的程序,一下是运行时的截图: 式子中的a,b,c是可供用户自行输入的变量。 首先,我先对输入的运算符进行了简单的合法性判断,我的判断代 码如下: //函数的传入参