当前位置: 首页 > article >正文

C#简易Modbus从站仿真器

       C#使用NModbus库,编写从站仿真器,支持Modbus TCP访问,支持多个从站地址和动态启用/停用从站(模拟离线),支持数据变化,可以很方便实现,最终效果如图所示。

项目采用.net framework 4.7的Windows窗体模式快速实现,NuGet包和版本如下:

界面设计如下:

窗体设计部分Form1.Designer.cs代码如下:

namespace ModbusSlaveSimulatorTest
{partial class Form1{/// <summary>/// 必需的设计器变量。/// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// 清理所有正在使用的资源。/// </summary>/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows 窗体设计器生成的代码/// <summary>/// 设计器支持所需的方法 - 不要修改/// 使用代码编辑器修改此方法的内容。/// </summary>private void InitializeComponent(){this.components = new System.ComponentModel.Container();this.checkBox1 = new System.Windows.Forms.CheckBox();this.checkBox2 = new System.Windows.Forms.CheckBox();this.checkBox3 = new System.Windows.Forms.CheckBox();this.checkBox4 = new System.Windows.Forms.CheckBox();this.checkBox5 = new System.Windows.Forms.CheckBox();this.checkBox6 = new System.Windows.Forms.CheckBox();this.checkBox7 = new System.Windows.Forms.CheckBox();this.checkBox8 = new System.Windows.Forms.CheckBox();this.checkBox9 = new System.Windows.Forms.CheckBox();this.checkBox10 = new System.Windows.Forms.CheckBox();this.timer1 = new System.Windows.Forms.Timer(this.components);this.label1 = new System.Windows.Forms.Label();this.comboBox1 = new System.Windows.Forms.ComboBox();this.SuspendLayout();// // checkBox1// this.checkBox1.AutoSize = true;this.checkBox1.Checked = true;this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox1.Location = new System.Drawing.Point(12, 12);this.checkBox1.Name = "checkBox1";this.checkBox1.Size = new System.Drawing.Size(66, 16);this.checkBox1.TabIndex = 0;this.checkBox1.Text = "Slave 1";this.checkBox1.UseVisualStyleBackColor = true;this.checkBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox2// this.checkBox2.AutoSize = true;this.checkBox2.Checked = true;this.checkBox2.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox2.Location = new System.Drawing.Point(84, 12);this.checkBox2.Name = "checkBox2";this.checkBox2.Size = new System.Drawing.Size(66, 16);this.checkBox2.TabIndex = 1;this.checkBox2.Text = "Slave 2";this.checkBox2.UseVisualStyleBackColor = true;this.checkBox2.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox3// this.checkBox3.AutoSize = true;this.checkBox3.Checked = true;this.checkBox3.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox3.Location = new System.Drawing.Point(167, 12);this.checkBox3.Name = "checkBox3";this.checkBox3.Size = new System.Drawing.Size(66, 16);this.checkBox3.TabIndex = 2;this.checkBox3.Text = "Slave 3";this.checkBox3.UseVisualStyleBackColor = true;this.checkBox3.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox4// this.checkBox4.AutoSize = true;this.checkBox4.Checked = true;this.checkBox4.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox4.Location = new System.Drawing.Point(251, 12);this.checkBox4.Name = "checkBox4";this.checkBox4.Size = new System.Drawing.Size(66, 16);this.checkBox4.TabIndex = 3;this.checkBox4.Text = "Slave 4";this.checkBox4.UseVisualStyleBackColor = true;this.checkBox4.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox5// this.checkBox5.AutoSize = true;this.checkBox5.Checked = true;this.checkBox5.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox5.Location = new System.Drawing.Point(342, 12);this.checkBox5.Name = "checkBox5";this.checkBox5.Size = new System.Drawing.Size(66, 16);this.checkBox5.TabIndex = 4;this.checkBox5.Text = "Slave 5";this.checkBox5.UseVisualStyleBackColor = true;this.checkBox5.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox6// this.checkBox6.AutoSize = true;this.checkBox6.Checked = true;this.checkBox6.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox6.Location = new System.Drawing.Point(432, 12);this.checkBox6.Name = "checkBox6";this.checkBox6.Size = new System.Drawing.Size(66, 16);this.checkBox6.TabIndex = 5;this.checkBox6.Text = "Slave 6";this.checkBox6.UseVisualStyleBackColor = true;this.checkBox6.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox7// this.checkBox7.AutoSize = true;this.checkBox7.Checked = true;this.checkBox7.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox7.Location = new System.Drawing.Point(516, 12);this.checkBox7.Name = "checkBox7";this.checkBox7.Size = new System.Drawing.Size(66, 16);this.checkBox7.TabIndex = 6;this.checkBox7.Text = "Slave 7";this.checkBox7.UseVisualStyleBackColor = true;this.checkBox7.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox8// this.checkBox8.AutoSize = true;this.checkBox8.Checked = true;this.checkBox8.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox8.Location = new System.Drawing.Point(588, 12);this.checkBox8.Name = "checkBox8";this.checkBox8.Size = new System.Drawing.Size(66, 16);this.checkBox8.TabIndex = 7;this.checkBox8.Text = "Slave 8";this.checkBox8.UseVisualStyleBackColor = true;this.checkBox8.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox9// this.checkBox9.AutoSize = true;this.checkBox9.Checked = true;this.checkBox9.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox9.Location = new System.Drawing.Point(660, 12);this.checkBox9.Name = "checkBox9";this.checkBox9.Size = new System.Drawing.Size(66, 16);this.checkBox9.TabIndex = 8;this.checkBox9.Text = "Slave 9";this.checkBox9.UseVisualStyleBackColor = true;this.checkBox9.MouseClick += new System.Windows.Forms.MouseEventHandler(this.checkBox9_MouseClick);// // checkBox10// this.checkBox10.AutoSize = true;this.checkBox10.Checked = true;this.checkBox10.CheckState = System.Windows.Forms.CheckState.Checked;this.checkBox10.Location = new System.Drawing.Point(12, 57);this.checkBox10.Name = "checkBox10";this.checkBox10.Size = new System.Drawing.Size(96, 16);this.checkBox10.TabIndex = 9;this.checkBox10.Text = "数据随机变化";this.checkBox10.UseVisualStyleBackColor = true;this.checkBox10.CheckedChanged += new System.EventHandler(this.checkBox10_CheckedChanged);// // timer1// this.timer1.Enabled = true;this.timer1.Interval = 2000;this.timer1.Tick += new System.EventHandler(this.timer1_Tick);// // label1// this.label1.AutoSize = true;this.label1.Location = new System.Drawing.Point(148, 58);this.label1.Name = "label1";this.label1.Size = new System.Drawing.Size(101, 12);this.label1.TabIndex = 10;this.label1.Text = "仿真频率(ms):";// // comboBox1// this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;this.comboBox1.FormattingEnabled = true;this.comboBox1.Items.AddRange(new object[] {"100","200","500","1000","2000","5000","10000"});this.comboBox1.Location = new System.Drawing.Point(247, 56);this.comboBox1.Name = "comboBox1";this.comboBox1.Size = new System.Drawing.Size(70, 20);this.comboBox1.TabIndex = 11;this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);// // Form1// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(802, 125);this.Controls.Add(this.comboBox1);this.Controls.Add(this.label1);this.Controls.Add(this.checkBox10);this.Controls.Add(this.checkBox9);this.Controls.Add(this.checkBox8);this.Controls.Add(this.checkBox7);this.Controls.Add(this.checkBox6);this.Controls.Add(this.checkBox5);this.Controls.Add(this.checkBox4);this.Controls.Add(this.checkBox3);this.Controls.Add(this.checkBox2);this.Controls.Add(this.checkBox1);this.Name = "Form1";this.Text = "Modbus从站仿真";this.Load += new System.EventHandler(this.Form1_Load);this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.CheckBox checkBox1;private System.Windows.Forms.CheckBox checkBox2;private System.Windows.Forms.CheckBox checkBox3;private System.Windows.Forms.CheckBox checkBox4;private System.Windows.Forms.CheckBox checkBox5;private System.Windows.Forms.CheckBox checkBox6;private System.Windows.Forms.CheckBox checkBox7;private System.Windows.Forms.CheckBox checkBox8;private System.Windows.Forms.CheckBox checkBox9;private System.Windows.Forms.CheckBox checkBox10;private System.Windows.Forms.Timer timer1;private System.Windows.Forms.Label label1;private System.Windows.Forms.ComboBox comboBox1;}
}

窗体实现部分代码如下:

using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Net;
using System.Windows.Forms;
using NModbus;namespace ModbusSlaveSimulatorTest
{public partial class Form1 : Form{class AppData{public string BindIp = "0.0.0.0";public ushort BindPort = 502;public byte SlaveCount = 9;public bool SimulationEnable = true;public int SimulationFreq = 1000;public string SimulationUnitId = "1,2,3,4,5,6,7,8,9";public ushort SimulationRegisterMax = 1000;public ushort SimulationStep = 1;}TcpListener modbusListener;List<IModbusSlave> listSlave = new List<IModbusSlave>();IModbusSlaveNetwork modbusSlaveNetwork = null;Dictionary<ushort, bool> dictSlaves = new Dictionary<ushort, bool>();//数据仿真ushort uValue = 0;ushort uStep = 1;AppData appData = new AppData();IModbusFactory factory = new ModbusFactory();public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){//创建通讯绑定端口modbusListener = new TcpListener(IPAddress.Parse(appData.BindIp), appData.BindPort);modbusListener.Start();modbusSlaveNetwork = factory.CreateSlaveNetwork(modbusListener);//创建Slave设备for (byte i = 0; i < appData.SlaveCount; i++){IModbusSlave slave = factory.CreateSlave((byte)(i + 1));listSlave.Add(slave);modbusSlaveNetwork.AddSlave(slave);dictSlaves[(ushort)(i + 1)] = true;}//接受连接modbusSlaveNetwork.ListenAsync();comboBox1.SelectedIndex = 4;}private void checkBox9_MouseClick(object sender, MouseEventArgs e){CheckBox cb = sender as CheckBox;byte slaveId = byte.Parse(cb.Text.Replace("Slave", ""));if (cb.Checked){modbusSlaveNetwork.AddSlave(listSlave[slaveId - 1]);dictSlaves[slaveId] = true;}else{modbusSlaveNetwork.RemoveSlave(slaveId);dictSlaves.Remove(slaveId);}}private void checkBox10_CheckedChanged(object sender, EventArgs e){timer1.Enabled = checkBox10.Checked;}private void timer1_Tick(object sender, EventArgs e){bool[] vb = new bool[appData.SimulationRegisterMax];ushort[] vu = new ushort[appData.SimulationRegisterMax];for (int i = 0; i < appData.SimulationRegisterMax; i++){vu[i] = uValue;vb[i] = (uValue % 2 == 1) ? true : false;}foreach (var slave in listSlave){if (!dictSlaves.ContainsKey(slave.UnitId))continue;slave.DataStore.CoilDiscretes.WritePoints(0, vb);slave.DataStore.CoilInputs.WritePoints(0, vb);slave.DataStore.InputRegisters.WritePoints(0, vu);slave.DataStore.HoldingRegisters.WritePoints(0, vu);}uValue += uStep;}private void comboBox1_SelectedIndexChanged(object sender, EventArgs e){timer1.Interval = int.Parse(comboBox1.Text);}}
}

代码托管地址:PascalMing/ModbusSlaveSimulatorTest: Modbus从站仿真
编译后的程序下载:https://github.com/PascalMing/ModbusSlaveSimulatorTest/releases/tag/v20250508

相关文章:

C#简易Modbus从站仿真器

C#使用NModbus库&#xff0c;编写从站仿真器&#xff0c;支持Modbus TCP访问&#xff0c;支持多个从站地址和动态启用/停用从站&#xff08;模拟离线&#xff09;&#xff0c;支持数据变化&#xff0c;可以很方便实现&#xff0c;最终效果如图所示。 项目采用.net framework 4.…...

Error parsing column 10 (YingShou=-99.5 - Double) dapper sqlite

在使用sqlite 调取 dapper的时候出现这个问题提示&#xff1a; 原因是 在 sqlite表中设定的字段类型是 decimel而在C#的字段属性也是decimel&#xff0c;结果解析F负数 小数的时候出现这个错误提示&#xff1a; 解决办法&#xff1a;使用默认的sqlite的字段类型来填入 REAL描述…...

Spring AI系列——使用大模型对文本进行内容总结归纳分析

一、技术原理与架构设计 1. 技术原理 本项目基于 Spring AI Alibaba 框架&#xff0c;结合 DashScope 大模型服务 实现文本内容的自动摘要和结构化输出。核心原理如下&#xff1a; 文档解析&#xff1a; 使用 TikaDocumentReader 解析上传的文件&#xff08;如 PDF、Word 等&…...

【深度学习】目标检测算法大全

目录 一、R-CNN 1、R-CNN概述 2、R-CNN 模型总体流程 3、核心模块详解 &#xff08;1&#xff09;候选框生成&#xff08;Selective Search&#xff09; &#xff08;2&#xff09;深度特征提取与微调 2.1 特征提取 2.2 网络微调&#xff08;Fine-tuning&#xff09; …...

5.1.1 WPF中Command使用介绍

WPF 的命令系统是一种强大的输入处理机制,它比传统的事件处理更加灵活和可重用,特别适合 MVVM (Model, View, ViewModel)模式开发。 一、命令系统核心概念 1.命令系统基本元素: 命令(Command): 即ICommand类,使用最多的是RoutedCommand,也可以自己继承ICommand使用自定…...

excel大表导入数据库

前文介绍了数据量较小的excel表导入数据库的方法&#xff0c;在数据量较大的情况下就不太适合了&#xff0c;一个是因为mysql命令的执行串长度有限制&#xff0c;二是node-xlsx这个模块加载excel文件是整个文件全部加载到内存&#xff0c;在excel文件较大和可用内存受限的场景就…...

《让歌声跨越山海:Flutter借助Agora SDK实现高质量连麦合唱》

对于Flutter开发者而言&#xff0c;借助Agora SDK实现这一功能&#xff0c;不仅能为用户带来前所未有的社交体验&#xff0c;更是在激烈的市场竞争中脱颖而出的关键。 Agora SDK作为实时通信领域的佼佼者&#xff0c;拥有一系列令人瞩目的特性&#xff0c;使其成为实现高质量连…...

A* (AStar) 寻路

//调用工具类获取路线 let route AStarSearch.getRoute(start_point, end_point, this.mapFloor.map_point); map_point 是所有可走点的集合 import { _decorator, Component, Node, Prefab, instantiate, v3, Vec2 } from cc; import { oops } from "../../../../../e…...

单词短语0512

当然可以&#xff0c;下面是“opportunity”在考研英语中的常用意思和高频短语&#xff0c;采用大字体展示&#xff0c;便于记忆&#xff1a; ✅ opportunity 的考研常用意思&#xff1a; &#x1f449; 机会&#xff0c;良机 表示有利的时机或条件&#xff0c;尤指成功的可能…...

视觉-语言-动作模型:概念、进展、应用与挑战(下)

25年5月来自 Cornell 大学、香港科大和希腊 U Peloponnese 的论文“Vision-Language-Action Models: Concepts, Progress, Applications and Challenges”。 视觉-语言-动作 (VLA) 模型标志着人工智能的变革性进步&#xff0c;旨在将感知、自然语言理解和具体动作统一在一个计…...

一键解锁嵌入式UI开发——LVGL的“万能配方”

面对碎片化的嵌入式硬件生态&#xff0c;LVGL堪称开发者手中的万能配方。它通过统一API接口屏蔽底层差异&#xff0c;配合丰富的预置控件&#xff08;如按钮、图表、滑动条&#xff09;与动态渲染引擎&#xff0c;让工程师无需深入图形学原理&#xff0c;效率提升肉眼可见。 L…...

C# NX二次开发:宏录制实战讲解(第一讲)

今天要讲的是关于NX软件录制宏操作的一些案例。 下面讲如何在NX软件中复制Part体的录制宏。 NXOpen.Session theSession NXOpen.Session.GetSession(); NXOpen.Part workPart theSession.Parts.Work; NXOpen.Part displayPart theSession.Parts.Display; NXOpe…...

记录裁员后的半年前端求职经历

普通的人生终起波澜 去年下半年应该算是我毕业以来发生人生变故最多的一段时间。 先是 7 月份的时候发作了一次急性痛风&#xff0c;一个人在厦门&#xff0c;坐在床上路都走不了&#xff0c;那时候真的好想旁边能有个人能扶我去医院&#xff0c;真的是感受到 10 级的孤独。尝…...

Linux 文件查看|查找|压缩|解压 常用命令

cat 连接文件并打印到标准输出设备上 指令备注cat aaa.txt连接文件aaa并打印到标准输出设备上 more 以全屏幕的方式按页显示文本文件的内容 按Space键&#xff1a;显示文本的下一屏内容 按Enier键&#xff1a;只显示文本的下一行内容 指令备注more aaa.txt查看文件aaa le…...

什么是:Word2Vec + 余弦相似度

什么是:Word2Vec + 余弦相似度 目录 什么是:Word2Vec + 余弦相似度示例文本基于Word2Vec的文本向量化计算余弦相似度Word2Vec不是基于Transformer架构的Word2Vec是一种将单词转化为向量表示的模型,而Word2Vec + 余弦相似度则是一种利用Word2Vec得到的向量来计算文本相似性的…...

智慧城市综合运营管理系统Axure原型

这款Axure原型的设计理念紧紧围绕城市管理者的需求展开。它旨在打破传统城市管理中信息孤岛的局面&#xff0c;通过统一标准接入各类业务系统&#xff0c;实现城市运营管理信息资源的全面整合与共享。以城市管理者为中心&#xff0c;为其提供一个直观、便捷、高效的协同服务平台…...

[学习]RTKLib详解:convkml.c、convrnx.c与geoid.c

RTKLib详解: datum.c、download.c 与 lambda.c 本文是 RTKLlib详解 系列文章的一篇&#xff0c;目前该系列文章还在持续总结写作中&#xff0c;以发表的如下&#xff0c;有兴趣的可以翻阅。 [学习] RTKlib详解&#xff1a;功能、工具与源码结构解析 [学习]RTKLib详解&#xff…...

Qwen智能体qwen_agent与Assistant功能初探

Qwen智能体qwen_agent与Assistant功能初探 一、Qwen智能体框架概述 Qwen&#xff08;通义千问&#xff09;智能体框架是阿里云推出的新一代AI智能体开发平台&#xff0c;其核心模块qwen_agent.agent提供了一套完整的智能体构建解决方案。该框架通过模块化设计&#xff0c;将L…...

LayerNorm vs RMSNorm 技术对比

1. 核心概念 LayerNorm (层归一化) 思想&#xff1a;对单个样本的所有特征维度进行归一化目标&#xff1a;使每个样本的特征分布 μ 0 \mu0 μ0&#xff0c; σ 1 \sigma1 σ1特点&#xff1a;同时调整均值和方差 RMSNorm (均方根归一化) 思想&#xff1a;基于均方根的简…...

可视化图解算法37:序列化二叉树-II

1. 题目 描述 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树&#xff0c;不对序列化之后的字符串进行约束&#xff0c;但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。 二叉树的序列化(Serialize)是指&#xff1a;把一棵二叉树按照某种遍…...

C++GO语言微服务和服务发现②

01 创建go-micro项目-查看生成的 proto文件 02 创建go-micro项目-查看生成的main文件和handler ## 创建 micro 服务 命令&#xff1a;micro new --type srv test66 框架默认自带服务发现&#xff1a;mdns。 使用consul服务发现&#xff1a; 1. 初始consul服务发现&…...

【Web前端开发】CSS基础

2.CSS 2.1CSS概念 CSS是一组样式设置的规则&#xff0c;称为层叠样式表&#xff0c;用于控制页面的外观样式。 使用CSS能够对网页中元素位置的排版进行像素控制&#xff0c;实现美化页面的效果&#xff0c;也能够做到页面的样式和结构分离。 2.2基本语法 通常都是&#xff…...

Google LLM prompt engineering(谷歌提示词工程指南)

文章目录 基本概念AI输出配置&#xff1a;调整AI的回答方式输出长度温度&#xff08;Temperature&#xff09;Top-K和Top-P 提示技术&#xff1a;让AI更好地理解你零样本提示&#xff08;Zero-shot&#xff09;少样本提示&#xff08;Few-shot&#xff09;系统提示&#xff08;…...

接口出现 请求参数格式错误 的解决方法

目录 前言1. 问题所示2. 原理分析3. 解决方法前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 爬虫神器,无代码爬取,就来:bright.cn Java基本知识: java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)【Java项目】实战CRUD的功能整理…...

Git实战经验分享:深入掌握git commit --amend的进阶技巧

一、工具简介 git commit --amend是Git版本控制系统的核心补救命令&#xff0c;主要用于修正最近一次提交的元数据。该命令不会产生新的提交记录&#xff0c;而是通过覆盖原提交实现版本历史的整洁性&#xff0c;特别适合在本地仓库进行提交优化。 二、核心应用场景 提交信息…...

PTA:jmu-ds-最短路径

给定一个有向图&#xff0c;规定源点为0&#xff0c;求源点0到其他顶点最短路径。###你要实现的 函数接口定义&#xff1a; void Dijkstra(MGraph g,int v);//源点v到其他顶点最短路径 裁判测试程序样例&#xff1a; #include <stdio.h> #include <iostream> …...

Uniapp编写微信小程序,使用canvas进行绘图

一、canvas文档&#xff1a; https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial 二、数据绘制&#xff08;单位是像素&#xff09;&#xff1a; 1、绘制文本&#xff1a; 文字的长度超过设置的最大宽度&#xff0c;文字会缩在一起 ① 填充文本&#xf…...

WEB UI自动化测试之Pytest框架学习

文章目录 前言Pytest简介Pytest安装Pytest的常用插件Pytest的命名约束Pytest的运行方式Pytest运行方式与unittest对比主函数运行命令行运行执行结果代码说明 pytest.ini配置文件方式运行&#xff08;推荐&#xff09;使用markers标记测试用例 pytest中添加Fixture&#xff08;测…...

深入理解 iOS 开发中的 `use_frameworks!`

在使用 CocoaPods 管理 iOS 项目依赖时&#xff0c;开发者经常会在 Podfile 文件中看到一个配置选项&#xff1a;use_frameworks!。本文将详细介绍这个配置选项的含义&#xff0c;以及如何决定是否在项目中使用它。 一、什么是 use_frameworks! 在 CocoaPods 中引入第三方库时…...

矩阵置零算法讲解

矩阵置零算法讲解 一、问题描述 给定一个 (m \times n) 的矩阵,如果一个元素为 (0) ,则将其所在行和列的所有元素都设为 (0) 。要求使用原地算法,即在不使用额外矩阵空间的情况下完成操作。 二、解题思路 暴力解法 最直观的想法是遍历矩阵,当遇到 (0) 元素时,直接将其…...