(C语言) 泛型表达式

news2024/11/18 12:45:02

文章目录

  • ⭐语法
  • ⭐举例
    • 🚩判断对象类型
    • 🚩判断指针
    • 🚩函数重载
    • 🚩嵌套使用
  • 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1708052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

floodfill 算法(上)

目录 图像渲染 题意&#xff1a; 题解&#xff1a; 非递归&#xff1a; 递归&#xff1a; 岛屿数量 题解&#xff1a; 非递归&#xff1a; 递归&#xff1a; 岛屿的最大面积 题解&#xff1a; 非递归&#xff1a; 递归&#xff1a; 被围绕的区域 题解&#xff1a…

【加密与解密(第四版)】第十四章笔记

第十四章 漏洞分析技术 14.1 软件漏洞原理 缓冲区溢出漏洞&#xff1a;栈溢出 堆溢出、整型溢出&#xff08;存储溢出、计算溢出、符号问题&#xff09; UAF&#xff08;Use-After-Free&#xff09;漏洞 14.2 ShellCode 功能模块&#xff1a;下载执行、捆绑、反弹shell 14.3 …

采用java语言+B/S架构+后端SpringBoot前端Vue开发的ADR药品不良反应智能监测系统源码

采用java语言&#xff0b;B/S架构&#xff0b;后端SpringBoot前端Vue开发的ADR药品不良反应智能监测系统源码 ADR监测引擎每日主动获取检验数据、病历内容&#xff08;可拓展&#xff09;、以及其他临床数据&#xff0c;根据知识库内容自动判定患者是否有不良反应迹象&#xf…

kettle组件之java代码,快速上手必看

我们先了解不同于java代码的kettle的一些方法 1、getRow()&#xff1b; 获取每一行数据&#xff0c;循环读数据&#xff1b;返回的是Object[]数组 2、get(Fields.in,"字段名"); 获取具体的某个字段的名称 3、get(Fields.in,"字段名").getString(r); …

【软考】下篇 第15章 面向服务架构设计理论与实践

目录 一、SOA定义二、微服务微服务优势微服务与SOA对比微服务架构模式方案微服务设计约束 三、SOA参考架构四、SOA设计的标准要求五、SOA设计原则六、SOA设计模式七、SOA实施 一、SOA定义 面向服务的体系结构 (Service-Oriented Architecture,SOA), 从应用和原理的角度看&…

网络原理-HTTPS协议

在前面说到HTTP中,我们通过抓包,可以看到许多信息内容,其中往往会包含一些敏感信息,这些都是明文传输,当我们的请求被黑客或者不法分子截获后,那就很危险了,因此衍生出了HTTPS协议来对传输数据进行加密。 一、加密原理 基本原理如下&#xff1a; 明文 密钥 > 密文 密文…

线性稳压电路和开关稳压电路

稳压二极管稳压电路 电网电压增大&#xff0c;导到u1端的电压增大&#xff0c;从而使输出电压&#xff0c;稳压二极管两端的电压增大&#xff0c;稳压二极管两端电压增大&#xff0c;使流过的电注增大。那么&#xff0c;流过线性电阻R的总电流增大。 Ur电压增大&#xff0c;从…

网络故障排除—NAT-源进源出

多网络双出口一边是运营商A,一边是运营商B&#xff0c;将内网服务器分别映射到运营商B和运营商A出口。查了保证内部上网用户网速快管理员开启了运营商选路功能&#xff0c;运营商B的网站从运营商B出去&#xff0c;然后写有两条等价默认路由分别指向两个外网出口。营商A的网站从…

内网安全-隧道搭建穿透上线内网穿透-nps自定义上线内网渗透-Linux上线-cs上线Linux主机

目录 内网安全-隧道搭建&穿透上线内网穿透-nps-自定义-上线NPS工具介绍搭建过程 nps原理介绍MSF上线CS上线 内网渗透-Linux上线-cs上线Linux主机1.下载插件2.导入插件模块3.配置监听器4.服务端配置5.配置C2监听器并生成木马6.执行木马 内网安全-隧道搭建&穿透上线 内网…

重学java 49 增强for

知之俞明&#xff0c;则行之越笃&#xff1b;行之愈笃&#xff0c;则知之愈益&#xff1b; —— 24.5.28 一、基本使用 1.作用: 遍历集合或者数组 2.格式: for(元素类型 变量名:要遍历的集合名或者数组名) 变量名就是代表的每一个元素 3.快捷键: 集合名或者数组名.for package …

Transformers x SwanLab:可视化NLP模型训练

HuggingFace 的 Transformers 是目前最流行的深度学习训框架之一&#xff08;100k Star&#xff09;&#xff0c;现在主流的大语言模型&#xff08;LLaMa系列、Qwen系列、ChatGLM系列等&#xff09;、自然语言处理模型&#xff08;Bert系列&#xff09;等&#xff0c;都在使用T…

Web3探索加密世界:空投常见类型有哪些?附操作教程

每种空投类型都有独特的特征和目的&#xff0c;我们需要了解不同类型的加密空投。本文给大家介绍的是流行的加密货币空投类型&#xff0c;以及一般空投是如何做的。感兴趣的话请看下去。 一、空投常见类型 1、持有者空投 持有者空投向钱包中持有一定数量数字货币的人免费发放…

基于MyBatisPlus表结构维护工具

SuperTable表结构维护工具 一、简述 用于同步表实体与数据库表结构&#xff0c;同步建表、删改字段、索引&#xff0c;种子数据的工具… 一、开发环境 JDK&#xff1a;JDK8SpringBoot&#xff1a;2.7.2MyBatisPlus: 3.5.6MySQL: 5.7其他依赖&#xff1a;略 二、特性 表结…

大话C语言:第18篇 函数

1 函数概述 函数是c语言的功能单位&#xff0c;实现一个功能可以封装一个函数来实现。函数是一种可重用的代码块&#xff0c;用于执行特定任务或完成特定功能。函数主要作用是对具备相同逻辑的代码进行封装&#xff0c;提高代码的编写效率&#xff0c;实现对代码的重用。例如&a…

【Spring】深入学习AOP编程思想的实现原理和优势

【切面编程】深入学习AOP编程思想的实现原理和优势 前言AOP的由来及AOP与代理的关系AOP的实现方式详解静态代理动态代理 AOP的应用场景记录日志权限控制数据库事务控制缓存处理异常处理监控管理 AOP的底层实现全流程解析Spring AOP的简介动态代理的实现原理Spring AOP的实现原理…

流水账(CPU设计实战)——lab3

Lab3 Rewrite V1.0 版本控制 版本描述V0V1.0相对V0变化&#xff1a; 修改了文件名&#xff0c;各阶段以_stage结尾&#xff08;因为if是关键词&#xff0c;所以module名不能叫if&#xff0c;遂改为if_stage&#xff0c;为了统一命名&#xff0c;将所有module后缀加上_stage&a…

关于Windows中桌面窗口管理器的知识,看这篇文章就可以了

序言 你打开了任务管理器,发现了一个叫做“桌面窗口管理器”的东西,它是恶意软件吗?它应该在任务管理器吗?如果它应该在那里,它的作用什么?以下是你需要了解的所有信息。 什么是桌面窗口管理器 Desktop Window Manager(dwm.exe)是一个合成窗口管理器,可以在Windows…

SB-OSC,最新的 MySQL Schema 在线变更方案

目前主流的 MySQL 在线变更方案有两个&#xff1a; 基于 trigger 的 pt-online-schema-change基于 binlog 的 gh-ost 上周 Sendbird 刚开源了他们的 MySQL Schema 在线变更方案 SB-OSC: Sendbird Online Schema Change。 GitHub 上刚刚 25 颗星星&#xff0c;绝对新鲜出炉。 …

Java | Leetcode Java题解之第104题二叉树的最大深度

题目&#xff1a; 题解&#xff1a; class Solution {public int maxDepth(TreeNode root) {if (root null) {return 0;}Queue<TreeNode> queue new LinkedList<TreeNode>();queue.offer(root);int ans 0;while (!queue.isEmpty()) {int size queue.size();wh…

go语言基准测试Benchmark 最佳实践-冒泡排序和快速排序算法基准测试时间复杂度对比

在go语言中Benchmark基准测试( 在后缀为_test.go的文件中&#xff0c;函数原型为 func BenchmarkXxx(b *testing.B) {}的函数 )可以用来帮助我们发现代码的性能和瓶颈&#xff0c; 其最佳实践 应该是我们最常用的 冒泡排序和快速排序的测试了&#xff0c;废话不说&#xff0c;直…