【C++ Qt】信号和槽(内配思维导图 图文并茂 通俗易懂)
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry”
绪论:
本章是Qt中的第三章,也是我们理解Qt中必备的点 信号槽,它本质由信号和槽两个来实现,其中将细致的讲述如何自定义信号、槽,以及通过connect函数进行将信号和槽连接起来的实现用户通过控件和程序进行交互的操作。
————————
早关注不迷路,话不多说安全带系好,发车啦(建议电脑观看)。
信号和槽概述
首先了解信号是什么,它由三个部分组成:
- 信号源:谁发的信号
- 信号的类型:那种类别的信号
- 信号的处理方式:注册信号处理函数,在信号被触发的时候会自动调用执行。
同样的Qt中谈到信号也涉及到三点:
- 信号源:由那个控件发出的信号
- 信号的类型:用户进行不同的操作,就可能触发不同的信号
- 点击按钮
- 输入框汇总移动光标…
GUI程序就是要让用户进行操作,就是要和用户进行交互的,这个过程就需要关注,用户当前的操作具体是什么样的操作,也就是通过用户的操作触发的信号(信号)从而知道用户做了什么,根据这个信号进行对应的处理(槽)
- 槽(slot)–> 函数
- Qt 中可以使用 connect 这样的函数,把一个信号和一个槽关联起来
- 后续只要信号触发了,Qt就会自动的执行槽函数(本质就是 回调函数(函数适配器、比较器))
注意:
- 其中一定是 先把信号的处理方式准备好,再触发信号~
- Qt 中,一定是先关联 信号 和 槽,然后再触发信号(顺序不能乱)
connect
connect是QObject 提供的静态成员函数
并且Qt中提供的这些类,本身是存在一定的继承关系的(如下图)

其中:QObject 就是其他 Qt 内置类的“祖宗”(Qt4才引入继承机制…)、所以因为connect是QObject中的函数,所有许多控件都能继承使用
connect的具体使用
connect (const QObject *sender,const char * signal ,const QObject * receiver ,const char * method ,Qt::ConnectionType type = Qt::AutoConnection )1. sender 前信号来自那个控件
2. signal 信号的类型
3. receiver 信号如何处理的类
4. method 这个对象该如何处理(要处理信号提供的成员函数!)
5. type ⽤于指定关联⽅式,默认的关联⽅式为 Qt::AutoConnection 一般不用设置
简单信号槽实例
- 创建按钮 QPushButton 变量 button并 构造 传递 this
- 设置文本 为关闭
- 设置位置 200 200
- 使用connect设置四个参数
- 传递 button 变量,设置信号源
- 信号的类型,根据按钮对象类域获取 clicked 信号函数
- 其中注意的是:上述两个参数必须对应匹配
- 也就是说 button 的类型 如果是 QPushButton*
- 那么 第二个参数的信号 必须是 QPushButton 内置的信号(父类的信号&QPushButton::clicked)

- 处理信号的类对象:此处填写
this,代表当前类 - 信号处理的函数,此处调用
Widget::close(widget继承的类中的函数)作用:关闭当前窗口/控件

其中的一些问题:
Qt 里面到底提供了许多内置的信号 和 槽 让我们可以直接使用(如:QPushButton的clicked信号、QWidget 的 close 槽)
通过文档查看:

其中 假如在某个文档中没有找到你想要找到方法、槽函数或者信号时,不妨看看他的父类
其中写在:

- 其中 abstract 就是抽象类
- Qt 中会提供很多种按钮,其中QAbstractButton中就会存在许多 “共性” 的内容
- 这样就能通过继承的方式让,多个类中都使用到,并且不需要自行再定义:

其中clicked就在 QAbstractButton 内部:

其中clicked内部会写也是最要关注的点:什么时候触发信号?

再次回顾connect函数:

- 其中第二个参数和第四个参数时,发现我们传递的是函数指针,但函数显示需要的参数类型是char *,这不是有问题吗?
其中C++中是并不允许不同类型间的传递的,那么是如何实现的呢?
- 这个函数声明是以前旧版本的 Qt 的connect 函数声明
- 老版本中的写法:需要加上两个宏 SIGNAL 和 SLOT,将函数指针转换为 const char*

- 从 Qt 5 中进行了修改,给connect提供了重载,给第二个参数和第四个参数 改成了 泛型参数,允许咱们传入任意类型的函数指针

自定义槽
所谓的槽 slot 本质就是一个普通的成员函数,所以自定义槽本质就是新增成员函数
其中使用 conncet 连接的时候,将槽函数的参数填成自己的成员函数
代码实现信号槽
- 声明函数自己的槽函数:handle
- handle槽函数:
- 具体的实现:通过当前Widget类的this指针调用setWindowsTitle:设置窗口标题
- 通过connect进行PushButton按钮和handle槽函数的连接
具体信号槽源码:
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void handle();
private:Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建一个PushButton对象QPushButton* button = new QPushButton(this);button->setText("关闭窗口");button->move(200,200);//添加信号槽connect(button,&QPushButton::clicked,this,&Widget::handle);}Widget::~Widget()
{delete ui;
}void Widget::handle(){this->setWindowTitle("按钮已按下");
}
点击前:

点击后:

了解:在以前版本的Qt中,槽函数必须放到 public / private / protected slots这样的域内限定符中(现在版本并不需要这样写)

- 此处的slots 是 Qt 自己的扩展关键字,它的实现基于 Qt 中广泛使用的元编程技术(基于代码,生成代码)
- 元编程:qmake 构建Qt项目的时候,就会专门的扫描器,扫描代码中的关键字,基于这些关键字生成相关的代码
使用ui文件搭建信号槽
在拖拽式处,可以右键组件,找到构建槽这个选项

-
弹出的窗口就会列出 QPushButton 给我们提供的所有信号,都是能使用的

-
双击后就能使用了,也会自动生成一个函数

并且函数的声明也会自动生成

-
只需要在函数中编写即可!
- 方法同上

- 方法同上
其中我们在代码中发现并没有connect,所以Qt中除了connect来连接信号槽之外:
还能通过函数名的方式来自动连接(具体如下图)

- 当名称出错后,就无法连接成功,并且还会报错(Qt 中调用connectSlotsByName的时候,就会触发上述的自动连接信号槽的规则,该函数就是在 ui_widget.h 中的)


总结:
- 通过界面化的创建控件,还是推荐使用名称的方式快速连接信号槽
- 但如果是通过代码的方式来创建控件的话,还是得手动的 connect(因为自己代码中本身没有 connectSlotsByName)
-
自定义槽函数,非常关键,大部分情况下都是自定义槽函数的
-
槽函数,就是用户触发某个操作之后,要进行的业务逻辑
-
而自定义信号是比较少见的,实际开发中会很少需要自定义信号的
-
因为信号就是用户的某个操作,而对于GUI中,用户能进行的操作是很少的,可以穷举的
-
Qt内置的信号,基本就可以应付大部分开发场景的
自定义信号
虽然创建的Widget没有定义任何信号,但由于继承了 QWidget 和 QObject,而这两个类中就提供了一些信号可以直接使用了
- 而Qt中的信号,本质上也是一个函数
- Qt 5 以及更高版本中,槽函数和普通函数之间没啥区别
- 信号则是非常特殊的,程序员需要写出函数声明,告诉Qt这是一个信号
- 这个函数的定义,是Qt编译过程中,自动生成的(自动生成的过程,程序员无法干涉)
- 信号在Qt中的特殊机制,他需要配合Qt框架做很多操作
自定义信号
信号函数创建的要求
- 这个函数的返回值必须是 void
- 有没有参数都可以
使用Qt 扩展的关键字:signals 进行创建信号
在qmake的时候分析 / 生成工具,将下面的函数声明认为是信号,并且给这些函数自动生成函数定义

就能将自定义的信号连接槽

建立连接,不代表信号发出来了,而此处只是简单的将信号和槽连接了,还需要触发信号
如何触发自定义信号
Qt 内置的信号,都不需要手动通过代码触发,用户在GUI进行某些操作,就会触发对应的信号(内置到Qt框架中了)
关键字:emit发射自定义信号
emit 自定义信号
如:emit mySignal

但上述情况会在构造函数中立马触发信号,从而立马执行槽函数
对于发射信号的情况,并不是非要在构造函数中,而是应该根据具体情况,写在所需要的地方
具体见下面代码:

在最新版本中,即使不写emit,信号也能发出去!(mySignal构造中都写了)
带参数的信号和槽的注意点
信号和槽 也可以带参数
- 当信号带有参数的时候,槽的参数必须和信号的参数一致!
- 此时发射信号的时候,就可以给信号函数传递实参,与之对应的这个参数就会被传递到对应的槽函数中,也就起到了信号给槽传参的效果
- 其中:参数必须一致,主要参数必须一致

然后对于实现代码来说,也需要进行添加参数

对于传参来说可以起到复用代码的效果,根据不同的场景传递不同的参数
通过发送不同的信号达到不同的效果
Qt 中很多内置的信号,也是带有信号的(这些参数不是咋们自己传递的)
如下图

- 其中可以允许个数不一致,但要求信号的参数个数必须比槽的参数个数要多
难道不应该严格要求一致吗?
- 因为:信号槽之间的绑定不一定是1 对 1的,一个槽函数,有可能绑定多个信号,如果严格要求,也就意味着信号绑定槽的要求变高了
- 换而言之,当下这样的规则,就允许信号和槽之间的绑定更灵活了,更多的信号可以绑定到这个槽函数上,个数不一致槽函数就会按照参数顺序,拿到信号的前N个参数(只能多不能少)


- 并且同样要保证信号的参数类型和槽的参数类型一致

Q_OBject宏:
Qt 中如果要让某个类能使用 信号槽(可以在类中定义信号和槽函数)
则必须要在类最开始的地方,写下 Q_OBject 宏(这个宏给展开成许多额外的代码)


总结:
所谓的信号槽,终究是要解决的问题,就是响应用户的操作,信号槽,其实在GUI开发的各种框架中,是一个比较特色的存在
connect机制是为了:
- 解耦合,把触发用户操作的控件 和 处理对应用户的操作逻辑解耦合
- 多对多的效果:一个信号,可以connect到多个槽函数,一个槽函数也可以被多个信号connect
- 而其中的connect本就就像一个关联表,将多对多的信号和槽的情况连接起来

综上,Qt 引入信号槽记住,最本质的目的,就是为了能够让信号和槽之间按照多对多的方式来进行关联,其他GUI框架往往不具备这样特性
而在GUI开发的过程中,“多对多”这件事,其实是个“伪需求”,绝大多数 一对一就够了
disconnect 信号与槽的断开
-
使用 disconnect 来断开信号槽的连接
-
connect和disconne使用的方式是类似的,主动断开往往是把信号重新绑定到另一个槽函数
具体操作如下:
- 首先第一次点击pushbutton只会触发一个槽函数
- 当再次把一个信号绑定一个槽函数后,此时一个信号就会触发两个槽函数(也就是验证了支持多对多!,如下图)


实现一个断开连接,然后再次连接新的信号和槽
- 当点击pushButton2按钮后就会断开 第一个 pushButton的信号槽
- 然后连接到新的槽函数handleClick2

- 其中若不进行断开,则当有一个信号后会触发两个槽函数

使用lambda表达式定义槽函数
lambda本质就是一个匿名函数,主要应用于“回调函数”场景(一次性使用)
其中若要使用内部的成员变量/成员函数的话
- 需要给lambda表达式进行 “变量捕获”
- 假如要使用button,那么在括号中添加button变量
- 假若要捕获多个变量时,可以使用
=的形式(值)捕获(拷贝得到)所有变量
源码:
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建一个PushButton对象QPushButton* button = new QPushButton(this);button->setText("关闭窗口");//添加信号槽connect(this,&Widget::MySignal,this,[=]{qDebug() << "lambda表达式" ;button->move(200,200);});
}


注:
- 如果槽函数比较简单或者一次使用,那么就使用lambda表达式快速编程
- 其中要确定捕获到 lambda 内部的变量时有意义的(仍然存储没有被销毁),因为回调函数执行时机是不确定的,所以需要注意捕获对象生命周期
- 还能进行引用方式捕获那么就将
=替代为&(Qt中很少这样写,一般捕获的就是控件的指针,因为按引用还得跟关注变量的生命周期,变量可能会随栈直接释放) - lambda 语法是 C++11 中引用的,对于Qt5及以上版本是默认按 C++11来编译的,而如果使用Qt4或者更老版本,就需要手动在 .pro 文件中添加 C++11的编译选项
CONFIG += c++11
总结回顾
- 信号槽是什么:设计三个要素
- 信号源
- 信号的类型
- 信号的处理方式
- 信号槽的使用
- connect
- 如何查阅文档
- 一个控件内置了那些信号,何时触发
- 控件内置了那些槽,作用是什么
- 一些需要的信号槽,可能在父类中存在
- 自定义槽函数
- 本质上就是自定义一个普通的成员函数
- 还可以让 Qt Creator 自动生成(虽然没显示写 connect,但还是可以通过函数名特定规则来完成自动连接)
- 自定义信号
- 本质也是一个成员函数(函数的定义是Qt自己生成的,咱们只需要写函数声明)
signals自定义关键字中emit来完成信号的发射
- 信号和槽还可以带有参数
- 发射信号的时候,把参数传递给对应的槽
- 信号的参数和槽的参数要一致(至少类型匹配,信号的个数要等于或多余槽的参数)
- 信号槽存在的意义
- 解耦合(高内聚低耦合(低耦合:代码间相互不会影响、高内聚:相关代码都写在一起))
- 多对多的效果(类似 mysql 中的多对多),一个信号多个槽、一个槽多个信号
- discount、lambda表达式简化槽函数的定义
本章完。预知后事如何,暂听下回分解。
如果有任何问题欢迎讨论哈!
如果觉得这篇文章对你有所帮助的话点点赞吧!
持续更新大量C++细致内容,早关注不迷路。
相关文章:
【C++ Qt】信号和槽(内配思维导图 图文并茂 通俗易懂)
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 本章是Qt中的第三章,也是我们理解Qt中必备的点 信号槽,它本质由信号和槽两个来实现,其中将细致的讲述如何自定义信号…...
突破AI检测边界:对抗技术与学术伦理的终极博弈
随着GPT-4、Claude等大模型的文本生成能力突破人类写作水平,AI检测工具与对抗技术的博弈已进入白热化阶段。本文深入解析基于对抗训练的文本风格混淆网络如何突破GPTZero最新防御体系,探讨OpenAI多模态内容溯源系统引发的技术升级,并针对学术…...
从零开始构建微博爬虫:实现自动获取并保存微博内容
从零开始构建微博爬虫:实现自动获取并保存微博内容 前言 在信息爆炸的时代,社交媒体平台已经成为信息传播的重要渠道,其中微博作为中国最大的社交媒体平台之一,包含了大量有价值的信息和数据。对于研究人员、数据分析师或者只是…...
Git -> Git 所有提交阶段的回滚操作
已经修改但没有暂存的回滚 修改状态单个文件所有文件说明已修改未暂存git checkout -- 文件路径git checkout -- .丢弃工作区修改 已经暂存但没有提交的回滚 修改状态单个文件所有文件说明已暂存未提交git reset HEAD 文件路径 -> git checkout -- 文件路径git reset HEA…...
三餐四季、灯火阑珊
2025年4月22日,15~28℃,挺好的 待办: 教学技能大赛教案(2025年4月24日,校赛,小组合作,其他成员给力,暂不影响校赛进度,搁置) 教学技能大赛PPT(202…...
【Java面试笔记:基础】8.对比Vector、ArrayList、LinkedList有何区别?
在Java中,Vector、ArrayList和LinkedList均实现了List接口,但它们在线程安全、数据结构、性能特性及应用场景上存在显著差异。 1. Vector、ArrayList 和 LinkedList 的区别 Vector: 线程安全:Vector 是线程安全的动态数组&#…...
麒麟V10安装MySQL8.4
1、下载安装包 wget https://cdn.mysql.com//Downloads/MySQL-8.4/mysql-8.4.5-1.el7.x86_64.rpm-bundle.tar2、解压 mkdir -p /opt/mysql tar -xvf mysql-8.4.5-1.el7.x86_64.rpm-bundle.tar -C /opt/mysql3、安装MySQL 3.1、卸载mariadb rpm -qa | grep mariadb rpm -e m…...
基于javaweb的SSM+Maven教材管理系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
C语言教程(十二):C 语言数组详解
一、引言数组的基本概念 数组是一组具有相同数据类型的元素的集合,这些元素在内存中连续存储。通过一个统一的数组名和下标来访问数组中的每个元素。使用数组可以方便地处理大量相同类型的数据,避免为每个数据单独定义变量。 二、一维数组 2.1 数组的…...
osxcross 搭建 macOS 交叉编译环境
1. osxcross 搭建 macOS 交叉编译环境 1. osxcross 搭建 macOS 交叉编译环境 1.1. 安装依赖1.2. 安装 osxcross 及 macOS SDK 1.2.1. 可能错误 1.3. 编译 cmake 类工程1.4. 编译 configure 类工程1.5. 单文件编译及其他环境编译1.6. 打包成 docker 镜像1.7. 使用 docker 编译 …...
Zookeeper 概述
Zookeeper 概述 Zookeeper 概述与使用指南什么是Zookeeper?Zookeeper的主要作用使用Zookeeper的框架典型使用场景1. 配置管理2. 分布式锁3. 服务注册与发现 Zookeeper的缺陷与其他协调服务的比较实际案例:Kafka使用Zookeeper最佳实践 Zookeeper 概述与使…...
智能座舱测试内容与步骤
智能座舱的测试步骤通常包括以下环节: 1.测试环境搭建与准备 • 硬件需求分析:准备测试车辆、服务器与工作站、网络设备以及传感器和执行器模拟器等硬件设备。 • 软件需求分析:选择测试管理软件、自动化测试工具、模拟软件和开发调试工具等。…...
NineData 与飞书深度集成,企业级数据管理审批流程全面自动化
NineData 正式推出与飞书审批系统的深度集成功能,企业用户在 NineData 平台发起的审批工单,将自动推送至审批人的飞书中,审批人可以直接在飞书进行审批并通过/拒绝。该功能实现跨系统协作,带来巨大的审批效率提升,为各…...
mockMvc构建web单元测试学习笔记
web应用本来需要依靠tomcat这个环境运行 现在用mockMvc是为了模拟这个web环境,简化测试 什么是mock(模拟) 模拟对象---mock object是以可控方式模拟真实对象行为的假对象,通过模拟输入数据,验证程序达到预期结果 为什么使用mock对象 因为…...
【白雪讲堂】[特殊字符]内容战略地图|GEO优化框架下的内容全景布局
📍内容战略地图|GEO优化框架下的内容全景布局 1️⃣ 顶层目标:GEO优化战略 目标关键词: 被AI理解(AEO) 被AI优先推荐(GEO) 在关键场景中被AI复读引用 2️⃣ 三大引擎逻辑&#x…...
Windows7升级Windows10,无法在此驱动器上安装Windows
一、现象描述 台式机工作站,从Windows7升级Windows10,采用MediaCreationTool_22H2制作U盘启动盘,安装系统遇到问题如下: 二、原因分析 是由于硬盘格式不是GPT硬盘,而Windows系统只能安装到GPT硬盘上,所以…...
Element Plus表格组件深度解析:构建高性能企业级数据视图
一、架构设计与核心能力 Element Plus的表格组件(el-table)基于Vue 3的响应式系统构建,通过声明式配置实现复杂数据渲染。其核心设计理念体现在三个层级: 数据驱动:通过data属性绑定数据源,支持动态更新与…...
Idea创建项目的搭建
1、普通java项目 如果没有project SDK去new,默认在C:\Program Files\Java\jdk1.8.0_261 输入项目名称和项目路径 点击完成,即创建好一个普通的Java项目。 2、普通JavaWEB项目 目录中没有WEB-INF文件可以直接从tomcat中粘贴过来 D:\apache-tomcat-8.5.…...
drupal7可以从测试环境一键部署到生产环境吗
Drupal 7 本身并没有“内建的一键部署功能”,所以“从测试环境一键部署到生产环境”不能完全自动化完成,尤其是涉及数据库、配置和文件系统时。但你可以通过一些工具和方法实现接近“一键部署”的效果 ✅ 🚧 为什么不能直接一键部署ÿ…...
Springboot 集成 RBAC 模型实战指南
RBAC 模型核心原理 详情可参考之前的笔记:https://blog.csdn.net/qq_35201802/article/details/146036789?spm1011.2415.3001.5331 RBAC 定义与优势 RBAC(Role-Based Access Control,基于角色的访问控制)** 是一种通过角色关联…...
KWDB 创作者计划 KWDB(KaiwuDB)系列专题 (四) KWDB核心概念解析:多模、时序与分布式
KWDB核心概念解析:多模、时序与分布式 1. 引言 KWDB(KaiwuDB)作为一款面向AIoT(人工智能物联网)的分布式多模数据库,以其独特的多模融合设计、高效时序处理能力和灵活的分布式架构,满足了物联网场景下复杂数据管理的需求。要深入掌握KWDB,理解其三大核心概念——多模…...
GpuGeek:以弹性算力与全栈服务赋能产业智能升级
在人工智能技术快速融入各领域的趋势下,企业对高效、低成本的AI基础设施需求日益迫切。GpuGeek作为一站式AI基础设施平台,凭借其弹性算力调度、全流程开发支持、全球化资源覆盖以及国产化技术适配四大核心优势,为产业智能化升级提供了坚实的技…...
C语言main的参数;argc与argv
目录 前言 什么是命令行参数 argc与argv argc (Argument Count) argv (Argument Vector) 示例 前言 在C语言中,main函数的标准形式通常有两种: int main(void)int main(int argc, char *argv[]) 其中,argc 和 argv 是用于处理命令行参数…...
C++_并发编程_thread_01_基本应用
👋 Hi, I’m liubo👀 I’m interested in harmony🌱 I’m currently learning harmony💞️ I’m looking to collaborate on …📫 How to reach me …📇 sssssdsdsdsdsdsdasd🎃 dsdsdsdsdsddfsg…...
网络原理 - 4(TCP - 1)
目录 TCP 协议 TCP 协议段格式 可靠传输 几个 TCP 协议中的机制 1. 确认应答 2. 超时重传 完! TCP 协议 TCP 全称为 “传输控制协议”(Transmission Control Protocol),要对数据的传输进行一个详细的控制。 TCP 协议段格…...
强化学习框架:OpenRLHF源码解读,模型处理
本文主要介绍 强化学习框架:OpenRLHF源码解读,模型处理 models框架设计 了解一下 OpenRLHF的模型框架设计范式: From:https://arxiv.org/pdf/2405.11143 可以知道一个大概的流程:输入Pormpt通过Actor model输出回复 Response&am…...
STL常用算法——C++
1.概述 2.常用遍历算法 1.简介 2.for_each 方式一:传入普通函数(printf1) #include<stdio.h> using namespace std; #include<string> #include<vector> #include<functional> #include<algorithm> #include…...
UofTCTF-2025-web-复现
感兴趣朋友可以去我博客里看,画风更好看 UofTCTF-2025-web-复现 文章目录 scavenger-huntprismatic-blogscode-dbprepared-1prepared-2timeless scavenger-hunt 国外的一些ctf简单题就喜欢把flag藏在注释里,开源代码找到第一部分的flag 抓个包返回数据…...
Ruby 正则表达式
Ruby 正则表达式 引言 正则表达式(Regular Expression,简称Regex)是一种强大的文本处理工具,在编程和数据处理中有着广泛的应用。Ruby 作为一种动态、灵活的编程语言,同样内置了强大的正则表达式功能。本文将详细介绍…...
[密码学基础]GB与GM国密标准深度解析:定位、差异与协同发展
[密码学基础]GB与GM国密标准深度解析:定位、差异与协同发展 导语 在国产密码技术自主可控的浪潮下,GB(国家标准)与GM(密码行业标准)共同构建了我国商用密码的技术规范体系。二者在制定主体、法律效力、技术…...



