(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

相关文章

Java Lambda表达式的使用详解

《JavaLambda表达式的使用详解》:本文主要介绍JavaLambda表达式的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言二、Lambda表达式概述1. 什么是Lambda表达式?三、Lambda表达式的语法规则1. 无参数的Lambda表

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

C# Where 泛型约束的实现

《C#Where泛型约束的实现》本文主要介绍了C#Where泛型约束的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录使用的对象约束分类where T : structwhere T : classwhere T : ne

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin

SpringBoot @Scheduled Cron表达式使用方式

《SpringBoot@ScheduledCron表达式使用方式》:本文主要介绍SpringBoot@ScheduledCron表达式使用方式,具有很好的参考价值,希望对大家有所帮助,如有... 目录Cron 表达式详解1. 表达式格式‌2. 特殊字符解析3. 常用示例‌4. 重点规则5. 动态与复杂场景‌

Spring Boot 集成 Quartz 使用Cron 表达式实现定时任务

《SpringBoot集成Quartz使用Cron表达式实现定时任务》本文介绍了如何在SpringBoot项目中集成Quartz并使用Cron表达式进行任务调度,通过添加Quartz依赖、创... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

Go语言利用泛型封装常见的Map操作

《Go语言利用泛型封装常见的Map操作》Go语言在1.18版本中引入了泛型,这是Go语言发展的一个重要里程碑,它极大地增强了语言的表达能力和灵活性,本文将通过泛型实现封装常见的Map操作,感... 目录什么是泛型泛型解决了什么问题Go泛型基于泛型的常见Map操作代码合集总结什么是泛型泛型是一种编程范式,允

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

Java中JSON字符串反序列化(动态泛型)

《Java中JSON字符串反序列化(动态泛型)》文章讨论了在定时任务中使用反射调用目标对象时处理动态参数的问题,通过将方法参数存储为JSON字符串并进行反序列化,可以实现动态调用,然而,这种方式容易导... 需求:定时任务扫描,反射调用目标对象,但是,方法的传参不是固定的。方案一:将方法参数存成jsON字