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

利用可变参数模板,可打印任意参数和参数值。(C++很好的调式函数)

很酷的应用:

(1) 如何获取可变参数名

代码例子:

#define _test(...) (test_t(#__VA_ARGS__, __VA_ARGS__))template<typename... Args>
void test_t(const char* names, Args... args)
{std::cout << names << "\n";
}

__VA_ARGS__ 是 C/C++ 宏定义中的一个特殊标识符,用于表示 可变参数宏(Variadic Macros)中的参数包。它允许宏接受任意数量的参数。

详细说明

  1. 可变参数宏

    • 在宏定义中,使用 ... 表示可变参数。

    • 使用 __VA_ARGS__ 来引用这些可变参数。

  2. #__VA_ARGS__

    • # 是字符串化运算符,将宏参数转换为字符串。

    • #__VA_ARGS__ 将可变参数包中的所有参数转换为一个字符串。

#define _test(...) (test_t(#__VA_ARGS__, __VA_ARGS__))

这条语句定义了一个宏 _test,它接受可变数量的参数(通过 ... 表示),并将这些参数传递给一个函数 test_t

1. 宏定义的基本结构

  • _test 是宏的名称。

  • (...) 表示宏可以接受任意数量的参数。

  • test_t(#__VA_ARGS__, __VA_ARGS__) 是宏的展开内容。

2. __VA_ARGS__ 的作用

  • __VA_ARGS__ 是 C/C++ 中的特殊标识符,用于表示可变参数宏中的参数包。

  • 它允许宏接受任意数量的参数。

3. #__VA_ARGS__ 的作用

  • # 是字符串化运算符,将宏参数转换为字符串。

  • #__VA_ARGS__ 将可变参数包中的所有参数转换为一个字符串。

4. 宏的展开逻辑

假设调用 _test(a, b, c),宏会展开为:

(test_t("a, b, c", a, b, c))

  • #__VA_ARGS__ 将 a, b, c 转换为字符串 "a, b, c"

  • __VA_ARGS__ 展开为 a, b, c

5. test_t 函数的作用

test_t 是一个函数,它至少接受两个参数:

  1. 第一个参数是字符串 "a, b, c",表示变量名。

  2. 后续参数是变量值 a, b, c

test_t 的具体实现需要根据需求编写。例如,它可以用于打印变量名和变量值,或者进行其他处理。

下面看一下例子:

#define _test(...) (test_t(#__VA_ARGS__, __VA_ARGS__))template<typename... Args>
void test_t(const char* names, Args... args)
{std::cout << names << "\n";
}int main(int argc, char* argv[])
{QApplication a(argc, argv);  //注意,这里是QApplication	 ga.setStdLocaleForUTF8();int i = 5;double c = 3.14;std::string s = "abcd";_test(i, c,s);return a.exec();
}

运行结果:

请注意变量 i 和 c 中间是有一个空格的,这跟你的书写格式有关:

例如:

(2)如何展开参数包。

 
#define _test(...) (test_t(#__VA_ARGS__, __VA_ARGS__))template<typename... Args>
void test_t(const char* names, Args... args)
{auto arrNames = _string(names).split(','); //拆分变量列表for (auto s : arrNames) {std::wcout << _t("s=") << s << _t("\n");}
}int main(int argc, char* argv[])
{QApplication a(argc, argv);  //注意,这里是QApplication	 ga.setStdLocaleForUTF8();	 int i = 5;double c = 3.14;std::string s = "abcd";_test(i,c,s);return a.exec();
}

输出结果:

(3)如何获取变量的值,这里只介绍C++17及其以上的写法。

#define _test(...) (test_t(#__VA_ARGS__, __VA_ARGS__))template<typename... Args>
void test_t(const char* names, Args... args)
{auto arrNames = _string(names).split(','); //拆分变量列表int i = 0;// 使用折叠表达式展开参数包,只支持C++17及其以上//-------------------------------------------------------------------------((std::wcout << arrNames[i],std::cout << "=",std::cout << args << "\n", ++i //下一个参数),...);}int main(int argc, char* argv[])
{QApplication a(argc, argv);  //注意,这里是QApplication	 ga.setStdLocaleForUTF8();	 int i = 5;double c = 3.14;std::string s = "abcd";_test(i,c,s);return a.exec();
}

运行结果:

(4)应用例子:

//在控制台打印出n个变量名和变量值
#define _pns(...) (_cout << _generateString(#__VA_ARGS__, __VA_ARGS__))
//在窗口中显示n个变量名和变量值
#define _pnw(...) (qt.showText(_generateString(#__VA_ARGS__, __VA_ARGS__)))
int main(int argc, char* argv[])
{QApplication a(argc, argv);  //注意,这里是QApplication	 ga.setStdLocaleForUTF8();	 QWidget w;w.resize(500, 800);int i = 5;double d = 3.14;std::string s = "abcd";_Color  c;_Font f;_pns(i, d, s, w.geometry(), c, f);_pnw(i, d, s, w.geometry(), c, f);return a.exec();
}

结果:

下面是代码:

#if _c17_
/*-------------------------------------------- - 源程序(由DeepSeek提供)
// 辅助函数,生成变量名和值的字符串
template<typename... Args>
std::string _generateString(const char* names, Args... args) {std::string result;std::ostringstream oss;std::istringstream iss(names);std::string name;((oss << (iss >> name ? name : "") << " = " << args << "<br>"), ...);return oss.str();
}
*//// <summary>
/// 参数名 = 参数值
/// </summary>
/// <typeparam name="...Args"></typeparam>
/// <param name="names"></param>
/// <param name="...args"></param>
/// <returns></returns>
/// 创建时间:2025-03-07    最后一次修改时间:2025-03-07 (已测试)
template<typename... Args>
_string _generateString(const char* names, Args... args) {_string result;using namespace lf;auto arrNames = _string(names).split(','); //拆分变量列表int i = 0;const char* namePtr = names;//std::cout << "names=" << names << "\n";// 使用折叠表达式展开参数包//((result += std::string(namePtr) + " = " + std::to_string(args) + "<br>", namePtr = nullptr), ...);// 使用折叠表达式展开参数包,只支持C++17及其以上//-------------------------------------------------------------------------((// names = i, d, f, w.geometry(),用逗号和一个空格分隔,是固定的。//result.append(_string(typeid(args).name())),//result.append(_t("<br>")),//result.append(_t("----------")),//result.append(_t("<br>")),//name = _string(namePtr).left(_t(", ")),result.add(arrNames[i].trim()),			result.append(_t("=")),result.append(_tostr(args)),//result.append(_t("<br>")),  //如果是纯文本 <br> 替代成  \nresult.append(_t("\n")),++i //下一个参数),...);//-------------------------------------------------------------------------return result;
}
#else
/*---------------------------------------------源程序(由DeepSeek提供)
// 递归终止条件
std::string _generateStringHelper(const char* namePtr) {return "";
}// 递归展开参数包
template<typename T, typename... Args>
std::string _generateStringHelper(const char* namePtr, T arg, Args... args) {std::string result;// 提取变量名std::string name;while (*namePtr && *namePtr != ',') {name += *namePtr++;}if (*namePtr == ',') namePtr++; // 跳过逗号while (*namePtr == ' ') namePtr++; // 跳过空格// 拼接变量名和值result += name + " = " + std::to_string(arg) + "<br>";// 递归处理剩余参数result += _generateStringHelper(namePtr, args...);return result;
}template<typename... Args>
std::string _generateString(const char* names, Args... args) {return _generateStringHelper(names, args...);
}
*/// 递归终止条件
_string _generateStringHelper(const char* namePtr) {return _t("");
}// 递归展开参数包
template<typename T, typename... Args>
_string  _generateStringHelper(const char* namePtr, T arg, Args... args) {_string result;_pn(namePtr);// 提取变量名_string name;while (*namePtr && *namePtr != ',') {name.append(*namePtr++);}if (*namePtr == ',') namePtr++; // 跳过逗号while (*namePtr == ' ') namePtr++; // 跳过空格// 拼接变量名和值result += name + _t(" = ") + _tostr(arg) + _t("<br>");// 递归处理剩余参数result += _generateStringHelper(namePtr, args...);return result;
}template<typename... Args>
_string _generateString(const char* names, Args... args) {return _generateStringHelper(names, args...);
}#endif

这里有个关键函数,_tostr上次已介绍过:

_tostr


/// <summary>
/// 
/// </summary>
/// <param name="pt"></param>
/// <param name="sTypeName"></param>
/// <returns></returns>
/// 创建时间:2025-02-16    最后一次修改时间:2025-02-16
_string _tostr(void* pt, const char* sTypeName);/// <summary>
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
/// 创建时间:2025-02-16    最后一次修改时间:2025-02-16
template<class T>
inline _string _tostr(const T& t) {return _tostr((void*)(&t), typeid(t).name());
}
_string  _tostr(void* pt, const char* sTypeName)
{_StrA  sType = sTypeName;_string sResult(_t(""), 100);if (sType == typeid(char*).name() || sType == typeid(const char*).name()) {char** ppC = ((char**)(pt)); //指向指针的指针sResult.add(_string::qt_fromUtf8(*ppC));}else if (sType == typeid(wchar_t*).name() || sType == typeid(const wchar_t*).name()) {wchar_t** ppC = ((wchar_t**)(pt)); //指向指针的指针sResult.add(*ppC);}
#ifdef _QT_  //---------------------------------------------------------_QT_	 else if (sType == typeid(QStringList).name()) {QStringList* data = (QStringList*)pt;if (data->size() == 0)sResult.add(_t("{}"));else {sResult.add(_t("{"));for (int i = 0; i < data->size() - 1; ++i) {sResult.add(_t("\""));sResult.add(data->at(i).toStdWString());sResult.add(_t("\","));}sResult.add(_t("\""));sResult.add(data->last().toStdWString());sResult.add(_t("\""));sResult.add(_t("}"));}}else if (sType == typeid(QString).name()) {sResult.add(_t("\""));sResult.add((*((QString*)(pt))).toStdWString());sResult.add(_t("\""));}else if (sType == typeid(QDateTime).name()) {return QtDateTimeToString((QDateTime*)pt);}else if (sType == typeid(QFont).name()) {QFont* pf = (QFont*)(pt);sResult.add(pf->toString().toStdWString());}else if (sType == typeid(QByteArray).name()) {QByteArray* pb = (QByteArray*)(pt);sResult.add(_string::fromOnlyData(pb->data(), pb->size()));}else if (sType == typeid(QColor).name()) {QColor* pc = (QColor*)(pt);//sResult.add(_string::fromOnlyData(pb->data(), pb->size()));/*alpha:透明度。red:红色分量。green:绿色分量。blue:蓝色分量。pad:填充字段。*/_Color c;c._a = pc->alpha();c._r = pc->red();c._g = pc->green();c._b = pc->blue();sResult.add(c.toString());}else if (sType == typeid(QSize).name()) {QSize* ps = (QSize*)(pt);sResult.add(_t("("));sResult.add(_Math::intToStrForBaseN(ps->width()));sResult.add(_t(","));sResult.add(_Math::intToStrForBaseN(ps->height()));sResult.add(_t(")"));}else if (sType == typeid(QRect).name()){QRect* pr = (QRect*)(pt);sResult.add(_t("("));sResult.add(_Math::intToStrA(pr->left()));sResult.add(_t(","));sResult.add(_Math::intToStrA(pr->top()));sResult.add(_t(","));sResult.add(_Math::intToStrA(pr->bottom()));sResult.add(_t(","));sResult.add(_Math::intToStrA(pr->right()));sResult.add(_t(")"));}
#endif // ---------------------------------------------------------_lf_	 else if (sType == typeid(_StrListW).name()) {_StrListW* data = (_StrListW*)pt;if (data->size() == 0)sResult.add(_t("{}"));else {sResult.add(_t("{"));for (int i = 0; i < data->size() - 1; ++i) {sResult.add(_t("\""));sResult.add(data->at(i).qt_toStdWString());sResult.add(_t("\","));}sResult.add(_t("\""));sResult.add(data->last()->data.qt_toStdWString());sResult.add(_t("\""));sResult.add(_t("}"));}}else if (sType == typeid(_Color).name()) {_Color* pc = ((_Color*)(pt));sResult.add(pc->toString());}else if (sType == typeid(_Font).name()) {_Font* pf = ((_Font*)(pt));sResult.add(pf->toString());}else if (sType == typeid(_GuiTreeNodeEncryptionType).name()) {_GuiTreeNodeEncryptionType* ptnt = ((_GuiTreeNodeEncryptionType*)(pt));if (*ptnt == _GuiTreeNodeEncryptionType::noEncryption) {sResult.add(_t("_GuiTreeNodeEncryptionType::noEncryption"));}else if (*ptnt == _GuiTreeNodeEncryptionType::simpleEncryption) {sResult.add(_t("_GuiTreeNodeEncryptionType::simpleEncryption"));}else if (*ptnt == _GuiTreeNodeEncryptionType::aesEncryption) {sResult.add(_t("_GuiTreeNodeEncryptionType::aesEncryption"));}else if (*ptnt == _GuiTreeNodeEncryptionType::desEncryption) {sResult.add(_t("_GuiTreeNodeEncryptionType::desEncryption"));}}else if (sType == typeid(int).name()) {int *pNum = ((int*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(float).name()) {float* pNum = ((float*)(pt));sResult.add(_Math::doubleToStr(*pNum));}else if (sType == typeid(double).name()) {double *pNum = ((double*)(pt));sResult.add(_Math::doubleToStr(*pNum));}else if (sType == typeid(__int64).name()) {__int64 *pNum = ((__int64*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_byte).name()) {_byte *pNum = ((_byte*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_int8).name()) {_int8 *pNum = ((_int8*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_int16).name()) {_int16 *pNum = ((_int16*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_int32).name()) {_int16 *pNum = ((_int16*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_int64).name()) {_int64 *pNum = ((_int64*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_uint8).name()) {_uint8 *pNum = ((_uint8*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_uint16).name()) {_uint16 *pNum = ((_uint16*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_uint32).name()) {_uint32 *pNum = ((_uint32*)(pt));sResult.add(_Math::intToStr(*pNum));}else if (sType == typeid(_uint64).name()) {_uint64* pNum = ((_uint64*)(pt));sResult.add(std::to_wstring(*pNum));}else if (sType == typeid(std::string).name()) {std::string* ps = ((std::string*)(pt));sResult.add(_string::qt_fromStdString(*ps));}else if (sType == typeid(std::wstring).name()) {std::wstring* ps = ((std::wstring*)(pt));sResult.add(_string::qt_fromStdWString(*ps));}else if (sType == typeid(_string).name()) {_string* ps = ((_string*)(pt));sResult.add(*ps);}else if (sType.indexOf("char const [") != -1) {//char const [9]const char* ps = (char*)(pt);sResult.add(_string::qt_fromUtf8(ps));}else if (sType.indexOf("wchar_t const [") != -1) {//char const [9]const wchar_t* ps = (wchar_t*)(pt);sResult.add(ps);}else if (sType == typeid(bool).name()) {bool* pb = (bool*)(pt);if (*pb)sResult.add(_t("true"));elsesResult.add(_t("false"));}else if (sType.indexOf("lf::_DList") != -1)  //class lf::_DList<class lf::_StrW>{_Object* po = (_Object*)(pt);return po->toString();}else if (sType == typeid(_Object).name()) {_Object* po = (_Object*)(pt);return po->toString();}else {sResult.add(sType);}return sResult;
}

相关文章:

利用可变参数模板,可打印任意参数和参数值。(C++很好的调式函数)

很酷的应用&#xff1a; &#xff08;1&#xff09; 如何获取可变参数名 代码例子&#xff1a; #define _test(...) (test_t(#__VA_ARGS__, __VA_ARGS__))template<typename... Args> void test_t(const char* names, Args... args) {std::cout << names <<…...

Yashan DB 体系结构

一、体系结构概况 1.1 线程管理 YashanDB采用多线程架构&#xff0c;线程分为两类&#xff1a; • 工作线程&#xff08;Worker Threads&#xff09;&#xff1a;每个客户端连接到数据库实例时&#xff0c;会创建一个工作线程。工作线程负责处理客户端的SQL请求&#xff0c;执…...

测试工程师Deepseek实战之如何反向PUA它

问: 你是一名资深测试开发工程师 帮我设计一个提效工具&#xff0c;具有以下功能&#xff1a; 1.页面使用PYQT5设计&#xff0c;用两个输入控件&#xff0c;最好是日期类型的控件&#xff0c;第一个日期控件作为开始日期&#xff0c;第二个日期控件作为结束日期&#xff1b;前后…...

Windows系统中在VSCode上配置CUDA环境

前置步骤 安装符合GPU型号的CUDA Toolkit 配置好 nvcc 环境变量 安装 Visual Studio 参考https://blog.csdn.net/Cony_14/article/details/137510909 VSCode 安装插件 Nsight Visual Studio Code Editionvscode-cudacpp 安装 cmake 并配置好环境变量 注&#xff1a;Windows 端…...

React Native 0.76 升级后 APK 体积增大的原因及优化方案

在将 React Native 从 0.71 升级到 0.76 后,打包体积从 40 多 MB 增加到了 80 MB。经过一系列排查和优化,最终找到了解决方案,并将优化过程整理如下。 1. React Native 0.76 体积增大的可能原因 (1) 新架构默认启用 React Native 0.76 默认启用了 New Architecture(新架…...

pycharm找不到conda可执行文件

conda 24.9.2 在pycharm的右下角就可以切换python解释器了...

定时任务框架

常用定时任务框架 JDK 自带的 ScheduledExecutorService 适用于轻量级定时任务&#xff0c;基于线程池实现。API 简单&#xff0c;适用于小规模任务调度。 Quartz 强大的 Java 任务调度框架&#xff0c;支持 Cron 表达式、分布式集群、持久化等。适用于复杂调度场景&#xff0…...

ESP32S3读取数字麦克风INMP441的音频数据

ESP32S3 与 INMP441 麦克风模块的集成通常涉及使用 I2S 接口进行数字音频数据的传输。INMP441 是一款高性能的数字麦克风&#xff0c;它通过 I2S 接口输出音频数据。在 Arduino 环境中&#xff0c;ESP32S3 的开发通常使用 ESP-IDF&#xff08;Espressif IoT Development Framew…...

利用后缀表达式构造表达式二叉树的方法

后缀表达式&#xff08;逆波兰表达式&#xff09;是一种将运算符放在操作数之后的表达式表示法。利用后缀表达式构造表达式二叉树的方法主要依赖于栈结构。 转换步骤 初始化 创建一个空栈。 遍历后缀表达式 对后缀表达式的每个符号依次处理&#xff1a; 遇到操作数 如果当前符…...

使用express创建服务器保存数据到mysql

创建数据库和表结构 CREATE DATABASE collect;USE collect;CREATE TABLE info (id int(11) NOT NULL AUTO_INCREMENT,create_date bigint(20) DEFAULT NULL COMMENT 时间,type varchar(20) DEFAULT NULL COMMENT 数据分类,text_value text COMMENT 内容,PRIMARY KEY (id) ) EN…...

YOLOv12本地部署教程——42%速度提升,让高效目标检测触手可及

YOLOv12 是“你只看一次”&#xff08;You Only Look Once, YOLO&#xff09;系列的最新版本&#xff0c;于 2025 年 2 月发布。它引入了注意力机制&#xff0c;提升了检测精度&#xff0c;同时保持了高效的实时性能。在保持速度的同时&#xff0c;显著提升了检测精度。例如&am…...

SQLAlchemy系列教程:如何防止SQL注入

SQL注入是一种常见的安全漏洞&#xff0c;它允许攻击者通过应用程序的SQL查询操纵数据库。使用ORM工具&#xff08;如SQLAlchemy&#xff09;提供的内置功能可以帮助减轻这些风险。本教程将指导您完成保护SQLAlchemy查询的实践。 了解SQL注入 当攻击者能够通过用户输入插入或操…...

1. 树莓派上配置机器人环境(具身智能机器人套件)

1. 安装树莓派系统 镜像下载地址&#xff08;windows/Mac/Ubuntu)&#xff0c;安装Pi5. 2. 环境配置&#xff08;登录Pi系统&#xff09; 2.1 启用 SSH From the Preferences menu, launch Raspberry Pi Configuration. Navigate to the Interfaces tab. Select Enable…...

基于SpringBoot的智慧停车场小程序(源码+论文+部署教程)

运行环境 • 前端&#xff1a;小程序 Vue • 后端&#xff1a;Java • IDE工具&#xff1a;IDEA&#xff08;可自行选择&#xff09; HBuilderX 微信开发者工具 • 技术栈&#xff1a;小程序 SpringBoot Vue MySQL 主要功能 智慧停车场微信小程序主要包含小程序端和…...

【从零开始学习计算机科学】数字逻辑(九)有限状态机

【从零开始学习计算机科学】数字逻辑(九)有限状态机 有限状态机状态机的表示方法有限状态机的Verilog描述有限状态机 有限状态机(简称状态机)相当于一个控制器,它将一项功能的完成分解为若干步,每一步对应于二进制的一个状态,通过预先设计的顺序在各状态之间进行转换,状…...

HarmonyOS Next~鸿蒙系统ArkCompiler跨平台编译技术的革新实践

HarmonyOS Next~鸿蒙系统ArkCompiler跨平台编译技术的革新实践 引言 在万物互联时代&#xff0c;操作系统对编译技术的需求已从单纯的代码转换演变为跨设备协同、高效资源调度与极致性能优化的综合挑战。华为鸿蒙系统&#xff08;HarmonyOS&#xff09;自主研发的ArkCompiler…...

AI大模型概念知多少

什么是大模型&#xff1f;什么是模型参数 1&#xff09;现在的大模型要解决的问题&#xff0c;就是一个序列数据转换的问题&#xff1a; 输入序列 X X[x1 ,x2 ,...,xm ]&#xff0c; 输出序列Y[y1 ,y2 ,…,yn ]&#xff0c;X和Y之间的关系是&#xff1a;YWX。 “大模型”这个词…...

powermock,mock使用笔记

介于日本的形式主义junit4单体测试&#xff0c;特记笔记&#xff0c;以下纯用手机打出来&#xff0c;因为电脑禁止复制粘贴。 pom文件 powermock-module-junit1.7.4 powermock-api-mokcito 1.7.4 spring-test 8 1&#xff0c;测试类头部打注解 RunWith(PowerMockRunner.class…...

基于置换对称性的模型融合:实现凸盆地单盆地理论

【摘要】 一种合并神经网络模型的新方法,通过置换对称性来合并模型。即使在大规模的非凸优化问题中,神经网络损失景观似乎通常只有一个(几乎)封闭的盆地,这在很大程度上归因于隐藏层单元置换对称性。作者介绍了三种算法,用于将一个模型的单元置换为与参考模型对齐,从而…...

把握好自己的节奏, 别让世界成为你的发条匠

我见过凌晨两点还在回复工作群消息的职场妈妈&#xff0c;也见过凌晨三点抱着手机刷短视频的年轻人。 地铁站台的上班族永远在狂奔&#xff0c;连刚会走路的小孩都被早教班塞满了日程表。 现如今生活节奏快&#xff0c;像一只巨大的发条&#xff0c;每个人都被拧得紧紧的&#…...

linux awk命令和awk语言

linux awk和awk语言 通常大家说的awk几乎都是在linux/unix中使用的awk命令&#xff0c;见下&#xff0c; https://www.geeksforgeeks.org/awk-command-unixlinux-examples/ 作为命令使用的话&#xff0c;存在下内容 Awk 是一个工具&#xff0c;使程序员能够编写小巧但有效的…...

电脑网络出现问题!简单的几种方法解除电脑飞行模式

在某些情况下&#xff0c;您可能需要关闭电脑上的飞行模式以便重新连接到 Wi-Fi、蓝牙或其他无线网络。本教程中简鹿办公将指导您如何在 Windows 和 macO S操作系统上解除飞行模式。 一、Windows 系统下解除飞行模式 通过快捷操作中心 步骤一&#xff1a;点击屏幕右下角的通知…...

ASP.NET Core 6 MVC 文件上传

概述 应用程序中的文件上传是一项功能&#xff0c;用户可以使用该功能将用户本地系统或网络上的文件上传到 Web 应用程序。Web 应用程序将处理该文件&#xff0c;然后根据需要对文件进行一些验证&#xff0c;最后根据要求将该文件存储在系统中配置的用于保存文件的存储中&#…...

【VBA】WPS/PPT设置标题字体

通过VBA&#xff0c;配合左上角的快速访问工具栏&#xff0c;实现自动化调整 选中文本框的 字体位置、大小、颜色。 配合quicker更加便捷 Sub DisableAutoWrapAndFormat()Dim shp As Shape 检查是否选中了一个形状&#xff08;文本框&#xff09;If ActiveWindow.Selection.Typ…...

白盒测试(4):电源瞬态电流测试

电源瞬态电流测试至关重要&#xff0c;主要用于评估电源在负载突变时的响应能力。通过测试&#xff0c;可以确保电源在短时间内提供足够的电流并快速恢复稳定&#xff0c;避免电压波动或系统故障。这对于保证电子设备的可靠性和稳定性尤为关键&#xff0c;尤其是在高动态负载应…...

三维建模与视频融合(3D-Video Integration)技术初探。

三维建模与视频融合&#xff08;3D-Video Integration&#xff09;是一种将虚拟三维模型无缝嵌入实拍视频场景的技术&#xff0c;广泛应用于影视特效、增强现实&#xff08;AR&#xff09;、游戏开发、广告制作 、视频监控 等领域。 一、技术核心流程 三维建模与动画 使用工具…...

DeepSeek提问术:解锁AI交互新姿势-20 个精准提问框架

一、引言 在人工智能的浩瀚星空中,DeepSeek 无疑是一颗耀眼的新星,以其独特的光芒照亮了 AI 发展的新路径。自问世以来,DeepSeek 凭借先进的技术架构、强大的自然语言处理能力和出色的性能表现,迅速在竞争激烈的 AI 领域崭露头角,成为众多开发者、研究人员以及各行业从业者…...

避免魔法值和多层if的关键:编程范式和设计模式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、案例分析二、技术手段函数式接口在枚举中 三、优化后完整代码总结 前言 提示&#xff1a;避免魔法值和多层if的关键&#xff1a;编程范式和设计模式&#…...

第六课:数据存储三剑客:CSV/JSON/MySQL

在Python的数据存储与处理领域&#xff0c;CSV、JSON和MySQL被广大开发者誉为“数据存储三剑客”。它们各自在不同的场景下发挥着重要作用&#xff0c;无论是简单的数据交换、轻量级的数据存储&#xff0c;还是复杂的关系型数据库管理&#xff0c;都能找到它们的身影。本文将详…...

Qt常用控件之表格QTableWidget

表格QTableWidget QTableWidget 是一个表格控件&#xff0c;行和列交汇形成的每个单元格&#xff0c;是一个 QTableWidgetItem 对象。 1. QTableWidget属性 QTableWidget 的属性只有两个&#xff1a; 属性说明rowCount当前行的个数。columnCount当前列的个数。 2. QTableW…...