用 C 语言实现求补码的运算
缘起
前两天程序中需要求一堆参数的补码,一时犯懒,想从CSDN上搜一个勉强能用的代码借鉴一下,结果几乎没有搜到一个靠谱的!这种求补码的操作,用脚趾头想想也应该知道要用C或者C++的位运算来实现呀。结果搜到的一些实现方式竟然是把数值的二进制形式下的位,一位一位地进行操作!这简直离谱到家了,虽然这样做也能从功能上实现求补码的运算,但是性能肯定奇差呀。我们之所以用 C 或者 C++,通常都是对性能有一定的追求,如果你丝毫不在意性能,那你干嘛不去用 C# 或者 Java?
所以还是自己写了几个求补码的函数,分享在这里。本来觉得这是简单得不值一提的东西,但是看来并非人人都能把这件事情做对了。
之所以用 C 实现,而不是用 C++,是因为:(1) C 的函数可以在 C++ 中被无缝调用,反之则不行;(2) 用 C 实现,可以照顾到某些只能用 C 不能用 C++ 的嵌入式环境;(3) 这个实现过程实在是没有必要用到 C++ 的那些面向对象的特性,直接用 C 的过程式编程就足够了。我看到 CSDN 上有一个人实现求补码的过程,居然用到了 C++ 的 vector 容器,而且还对这个容器进行了动态地 insert 的操作,有这个必要吗??
从实际需求出发,我依次实现了对 8 位带符号整数、16 位带符号整数和 32 位带符号整数求补码的函数,以及它们的逆运算的函数。通常我们求补码的时候也不会希望求一个任意二进制字节流的补码,都是对实际的 8 位带符号整数、16 位带符号整数和 32 位带符号整数求补码进行求补码运算的。
原码、反码和补码的基础知识我就不在这里啰嗦了,CSDN 网站上介绍这些知识的文章多得是!我就直接上代码了。
程序实现
统一数据类型
对于 8 位整数、16 位整数和 32 位整数,为了照顾到不同的编译环境,我定义了一堆统一的数据类型,包括:
- 8位带符号和无符号整型:int8_t 与 uint8_t;
- 16位带符号和无符号整型:int16_t 与 uint16_t;
- 32位带符号和无符号整型:int32_t 与 uint32_t;
这些定义我放在了 datatypes.h 这个头文件里,通常我的 C / C++ 程序都会引用这个头文件:
#ifndef _INC_COMMON_datatypes_H
#define _INC_COMMON_datatypes_H#if _MSC_VER && _MSC_VER < 1700
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endiftypedef float float32_t;
typedef double float64_t;
typedef unsigned char byte;
typedef char sbyte;#ifdef _WIN64
#define ssize_t __int64
#else
#define ssize_t long
#endif#endif // !_INC_COMMON_datatypes_H
求补码的函数
头文件里面的函数原型定义:
#include "datatypes.h"#ifdef __cplusplus
extern "C" {
#endif// 求 srcvalue 的8位补码, srcvalue 的取值范围是: [-128(-0x80), +127(+0x7F)]uint8_t I8_to_Complement(int8_t srcvalue);// 求 srcvalue 的16位补码, srcvalue 的取值范围是 : [-32768(-0x8000), +32767(+0x7FFF)]uint16_t I16_to_Complement(int16_t srcvalue);// 求 srcvalue 的32位补码, srcvalue 的取值范围是 : [-2147483648(-0x80000000), +2147483647(+0x7FFFFFFF)]uint32_t I32_to_Complement(int32_t srcvalue);#ifdef __cplusplus
} // ! extern "C"
#endif
函数实现:
// 求 srcvalue 的8位补码, srcvalue 的取值范围是: [-128(-0x80), +127(+0x7F)]
uint8_t I8_to_Complement(int8_t srcvalue)
{uint8_t compcode;if (srcvalue >= 0){compcode = (uint8_t)srcvalue;goto EXIT;}uint8_t tail = (uint8_t)(0 - srcvalue);tail = ~tail;compcode = tail + 1;EXIT:return compcode;
}// 求 srcvalue 的16位补码, srcvalue 的取值范围是 : [-32768(-0x8000), +32767(+0x7FFF)]
uint16_t I16_to_Complement(int16_t srcvalue)
{uint16_t compcode;if (srcvalue >= 0){compcode = (uint16_t)srcvalue;goto EXIT;}uint16_t tail = (uint16_t)(0 - srcvalue);tail = ~tail;compcode = tail + 1;EXIT:return compcode;
}// 求 srcvalue 的32位补码, srcvalue 的取值范围是 : [-2147483648(-0x80000000), +2147483647(+0x7FFFFFFF)]
uint32_t I32_to_Complement(int32_t srcvalue)
{uint32_t compcode;if (srcvalue >= 0){compcode = (uint32_t)srcvalue;goto EXIT;}uint32_t tail = (uint32_t)(0 - srcvalue);tail = ~tail;compcode = tail + 1;EXIT:return compcode;
}
根据补码求原值(即:求补码运算的逆运算)
头文件里面的函数原型定义:
#include "datatypes.h"#ifdef __cplusplus
extern "C" {
#endif// 求8位补码 compcode 的原值int8_t Complement_to_I8(uint8_t compcode);// 求16位补码 compcode 的原值int16_t Complement_to_I16(uint16_t compcode);// 求32位补码 compcode 的原值int32_t Complement_to_I32(uint32_t compcode);#ifdef __cplusplus
} // ! extern "C"
#endif
函数实现:
// 求8位补码 compcode 的原值
int8_t Complement_to_I8(uint8_t compcode)
{int8_t srcvalue;uint8_t head = compcode & 0x80;if (head == 0){srcvalue = (int8_t)compcode;goto EXIT;}uint8_t tail = compcode - 1;tail = ~tail;srcvalue = 0 - (int8_t)tail;EXIT:return srcvalue;
}// 求16位补码 compcode 的原值
int16_t Complement_to_I16(uint16_t compcode)
{int16_t srcvalue;uint16_t head = compcode & 0x8000;if (head == 0){srcvalue = (int16_t)compcode;goto EXIT;}uint16_t tail = compcode - 1;tail = ~tail;srcvalue = 0 - (int16_t)tail;EXIT:return srcvalue;
}// 求32位补码 compcode 的原值
int32_t Complement_to_I32(uint32_t compcode)
{int32_t srcvalue;uint32_t head = compcode & 0x80000000;if (head == 0){srcvalue = (int32_t)compcode;goto EXIT;}uint32_t tail = compcode - 1;tail = ~tail;srcvalue = 0 - (int32_t)tail;EXIT:return srcvalue;
}
程序验证
我找到了一个求原码、反码、补码的在线工具,亲测靠谱,给大家推荐一下网址:https://www.lddgo.net/convert/number-binary-code
我用 CUnit 写了一些单元测试,来验证我上述提供的这些求补码的函数及其逆运算函数的正确性。我就不在这里科普 CUnit 的基本用法了,直接贴相关的单元测试代码。
单元测试程序的头文件
#ifndef _INC_UNITTETST_CUNIT_COMMFUNC_TESTCASES_COMMONFUNC_TS_A001_Common_H
#define _INC_UNITTETST_CUNIT_COMMFUNC_TESTCASES_COMMONFUNC_TS_A001_Common_H#define TS_A001_Identifier "TS_A001: Bit Operation"#ifdef __cplusplus
extern "C" {
#endifint TS_A001_Setup(void);int TS_A001_Cleanup(void);// 验证 I8_to_Complement 函数对输入参数`srcvalue`为0或正整数时工作正常void TC0001_I8_to_Complement_PositiveInteger();// 验证 I8_to_Complement 函数对输入参数`srcvalue`为负整数时工作正常void TC0002_I8_to_Complement_NegativeInteger();// 验证 Complement_to_I8 函数对 TC0001 和 TC0002 中的正/负整数求得的补码,都能逆向求得其原始值(正/负整数)void TC0003_Complement_to_I8();// 验证 I16_to_Complement 函数对输入参数`srcvalue`为0或正整数时工作正常void TC0004_I16_to_Complement_PositiveInteger();// 验证 I16_to_Complement 函数对输入参数`srcvalue`为负整数时工作正常void TC0005_I16_to_Complement_NegativeInteger();// 验证 Complement_to_I16 函数对 TC0004 和 TC0005 中的正/负整数求得的补码,都能逆向求得其原始值(正/负整数)void TC0006_Complement_to_I16();// 验证 I32_to_Complement 函数对输入参数`srcvalue`为0或正整数时工作正常void TC0007_I32_to_Complement_PositiveInteger();// 验证 I32_to_Complement 函数对输入参数`srcvalue`为负整数时工作正常void TC0008_I32_to_Complement_NegativeInteger();// 验证 Complement_to_I32 函数对 TC0007 和 TC0008 中的正/负整数求得的补码,都能逆向求得其原始值(正/负整数)void TC0009_Complement_to_I32();#ifdef __cplusplus
} // ! extern "C"
#endif#endif // !_INC_UNITTETST_CUNIT_COMMFUNC_TESTCASES_COMMONFUNC_TS_A001_Common_H
单元测试程序的测试用例实现
#include "CUnit/CUnit.h"
#include "Common/CommonFuncs.h"#include "TS_A001_Common.h"// ----------------------------------------------------------------------
// Public functions implementation
// ----------------------------------------------------------------------int TS_A001_Setup(void)
{return CUE_SUCCESS;
}int TS_A001_Cleanup(void)
{return CUE_SUCCESS;
}// ========================================================
// 参考:在线原码/反码/补码计算器
// https://www.lddgo.net/convert/number-binary-code
// ========================================================// 验证 I8_to_Complement 函数对输入参数`srcvalue`为0或正整数时工作正常
void TC0001_I8_to_Complement_PositiveInteger()
{
#define TC0001_VARS_COUNT 3int8_t SrcValues[TC0001_VARS_COUNT] = {0, 1, 127};uint8_t CompCodes[TC0001_VARS_COUNT] = {0, 1, 0x7F};for (int idx = 0; idx < TC0001_VARS_COUNT; idx++){uint8_t compcode = I8_to_Complement(SrcValues[idx]);CU_ASSERT_EQUAL(compcode, CompCodes[idx]);}
}// 验证 I8_to_Complement 函数对输入参数`srcvalue`为负整数时工作正常
void TC0002_I8_to_Complement_NegativeInteger()
{
#define TC0002_VARS_COUNT 6int8_t SrcValues[TC0002_VARS_COUNT] = {-1, -3, -63, -64, -127, -128};uint8_t CompCodes[TC0002_VARS_COUNT] = {0xFF, 0xFD, 0xC1, 0xC0, 0x81, 0x80};for (int idx = 0; idx < TC0002_VARS_COUNT; idx++){uint8_t compcode = I8_to_Complement(SrcValues[idx]);CU_ASSERT_EQUAL(compcode, CompCodes[idx]);}
}// 验证 Complement_to_I8 函数对 TC0001 和 TC0002 中的正/负整数求得的补码,都能逆向求得其原始值(正/负整数)
void TC0003_Complement_to_I8()
{
#define TC0003_VARS_COUNT 9int8_t SrcValues[TC0003_VARS_COUNT] = {0, 1, 127,-1, -3, -63, -64, -127, -128};uint8_t CompCodes[TC0003_VARS_COUNT] = {0, 1, 0x7F,0xFF, 0xFD, 0xC1, 0xC0, 0x81, 0x80};for (int idx = 0; idx < TC0003_VARS_COUNT; idx++){int8_t srcValue = Complement_to_I8(CompCodes[idx]);CU_ASSERT_EQUAL(srcValue, SrcValues[idx]);}
}// 验证 I16_to_Complement 函数对输入参数`srcvalue`为0或正整数时工作正常
void TC0004_I16_to_Complement_PositiveInteger()
{
#define TC0004_VARS_COUNT 7int16_t SrcValues[TC0004_VARS_COUNT] = {0, 1, 127, 128, 255,256, 32767};uint16_t CompCodes[TC0004_VARS_COUNT] = {0, 1, 0x7F, 0x80, 0xFF,0x0100, 0x7FFF};for (int idx = 0; idx < TC0004_VARS_COUNT; idx++){uint16_t compcode = I16_to_Complement(SrcValues[idx]);CU_ASSERT_EQUAL(compcode, CompCodes[idx]);}
}// 验证 I16_to_Complement 函数对输入参数`srcvalue`为负整数时工作正常
void TC0005_I16_to_Complement_NegativeInteger()
{
#define TC0005_VARS_COUNT 12int16_t SrcValues[TC0005_VARS_COUNT] = {-1, -3, -63, -64, -127, -128, -129, -255, -256,-257,-32767, -32768};uint16_t CompCodes[TC0005_VARS_COUNT] = {0xFFFF, 0xFFFD, 0xFFC1, 0xFFC0, 0xFF81, 0xFF80, 0xFF7F, 0xFF01, 0xFF00,0xFEFF,0x8001, 0x8000};for (int idx = 0; idx < TC0005_VARS_COUNT; idx++){uint16_t compcode = I16_to_Complement(SrcValues[idx]);CU_ASSERT_EQUAL(compcode, CompCodes[idx]);}
}// 验证 Complement_to_I16 函数对 TC0004 和 TC0005 中的正/负整数求得的补码,都能逆向求得其原始值(正/负整数)
void TC0006_Complement_to_I16()
{
#define TC0006_VARS_COUNT 19int16_t SrcValues[TC0006_VARS_COUNT] = {0, 1, 127, 128, 255,256, 32767,-1, -3, -63, -64, -127, -128, -129, -255, -256,-257,-32767, -32768};uint16_t CompCodes[TC0006_VARS_COUNT] = {0, 1, 0x7F, 0x80, 0xFF,0x0100, 0x7FFF,0xFFFF, 0xFFFD, 0xFFC1, 0xFFC0, 0xFF81, 0xFF80, 0xFF7F, 0xFF01, 0xFF00,0xFEFF,0x8001, 0x8000};for (int idx = 0; idx < TC0006_VARS_COUNT; idx++){int16_t srcValue = Complement_to_I16(CompCodes[idx]);CU_ASSERT_EQUAL(srcValue, SrcValues[idx]);}
}// 验证 I32_to_Complement 函数对输入参数`srcvalue`为0或正整数时工作正常
void TC0007_I32_to_Complement_PositiveInteger()
{
#define TC0007_VARS_COUNT 3int32_t SrcValues[TC0007_VARS_COUNT] = {0, 1, 0x7FFFFFFF};uint32_t CompCodes[TC0007_VARS_COUNT] = {0, 1, 0x7FFFFFFF};for (int idx = 0; idx < TC0007_VARS_COUNT; idx++){uint32_t compcode = I32_to_Complement(SrcValues[idx]);CU_ASSERT_EQUAL(compcode, CompCodes[idx]);}
}// 验证 I32_to_Complement 函数对输入参数`srcvalue`为负整数时工作正常
#if defined(_WIN32) && defined(_MSC_VER)
#pragma warning(disable: 4146)
#endif
void TC0008_I32_to_Complement_NegativeInteger()
{
#define TC0008_VARS_COUNT 4// 2147483647(DEC): 0x7FFFFFFF// 2147483648(DEC): 0x80000000int32_t SrcValues[TC0008_VARS_COUNT] = {-1, -2, -2147483647, -2147483648};uint32_t CompCodes[TC0008_VARS_COUNT] = {0xFFFFFFFF, 0xFFFFFFFE, 0x80000001, 0x80000000};for (int idx = 0; idx < TC0008_VARS_COUNT; idx++){uint32_t compcode = I32_to_Complement(SrcValues[idx]);CU_ASSERT_EQUAL(compcode, CompCodes[idx]);}
}// 验证 Complement_to_I32 函数对 TC0007 和 TC0008 中的正/负整数求得的补码,都能逆向求得其原始值(正/负整数)
#if defined(_WIN32) && defined(_MSC_VER)
#pragma warning(disable: 4146)
#endif
void TC0009_Complement_to_I32()
{
#define TC0009_VARS_COUNT 7int32_t SrcValues[TC0009_VARS_COUNT] = {0, 1, 0x7FFFFFFF,-1, -2, -2147483647, -2147483648};uint32_t CompCodes[TC0009_VARS_COUNT] = {0, 1, 0x7FFFFFFF,0xFFFFFFFF, 0xFFFFFFFE, 0x80000001, 0x80000000};for (int idx = 0; idx < TC0009_VARS_COUNT; idx++){int32_t srcValue = Complement_to_I32(CompCodes[idx]);CU_ASSERT_EQUAL(srcValue, SrcValues[idx]);}
}
单元测试的运行结果
通过单元测试,验证了程序的正确性。截图如下:


相关文章:
用 C 语言实现求补码的运算
缘起 前两天程序中需要求一堆参数的补码,一时犯懒,想从CSDN上搜一个勉强能用的代码借鉴一下,结果几乎没有搜到一个靠谱的!这种求补码的操作,用脚趾头想想也应该知道要用C或者C的位运算来实现呀。结果搜到的一些实现方…...
python下载文件
import urllib.request url "http://****/storage/x4MigEhU6BGAuTqjrRfIBky0S2aMmkyGl4UzTqUb.png"#下载地址 path "ddad.png"#保存路径,保存项目路径 urllib.request.urlretrieve(url, path)...
JMU 数科 数据库与数据仓库期末总结(1)
本章根据老师给出的知识点作进一步相对生动一点的解释。 不保证完全正确。 先给出总的知识点,再给出生动解释。 知识点 数据模型通常由三部分组成:数据结构、数据操作和完整性约束。关系模式中主码的取值必须唯一且非空,这是实体完整性的…...
前端问题整理
Vue vue mvvm(Model-View-ViewModel)架构模式原理 Model 是数据层,即 vue 实例中的数据View 是视图层, 即 domViewModel,即连接Model和Vue的中间层,Vue实例就是ViewModelViewModel 负责将 Model 的变化反映…...
【实践功能记录6】表格列悬浮展示tooltip信息
需求描述: 鼠标悬浮在表格的IP字段上时,使用tooltip展示IP信息,如图: 1.封装根据IP展示信息的组件 请求接口获取IP信息,注意请求接口时防抖 <!-- 根据IP展示资产信息 --> <template><div><el-…...
AI论文速读 | 2024[SIGIR]基于大语言模型的下一个兴趣点推荐
论文标题:Large Language Models for Next Point-of-Interest Recommendation 作者:Peibo Li ; Maarten de Rijke ; Hao Xue (薛昊); Shuang Ao ; Yang Song ; Flora D. Salim 机构:新南威尔士大学(UNSW),…...
Rust 实战丨通过实现 json! 掌握声明宏
在 Rust 编程语言中,宏是一种强大的工具,可以用于在编译时生成代码。json! 是一个在 Rust 中广泛使用的宏,它允许我们在 Rust 代码中方便地创建 JSON 数据。 声明宏(declarative macros)是 Rust 中的一种宏࿰…...
vue+elementUI实现在表格中添加输入框并校验的功能
背景: vue2elmui 需求: 需要在一个table中添加若干个输入框,并且在提交时需要添加校验 思路: 当需要校验的时候可以考虑添加form表单来触发校验,因此需要在table外面套一层form表单,表单的属性就是ref…...
为国产加油:“缺芯少屏”暂缓,另一领域,也要加把劲
说起咱中国之前的“缺芯少屏”,真的是让人挺闹心的。 不过呢,为了改变这个状况,咱们的工程师们可是费了不少劲儿,辛辛苦苦努力了数十年。现在好了,咱们也迎来了柔性屏的时代。 柔性屏 说起来,在触摸屏或者…...
【Qnx】Qnx coredump解析
Qnx coredump解析 coredump文件 Qnx运行的程序崩溃时,会生成coredump文件。 默认情况下这些文件默认会保存在/var/log/*.core 文件中。 解析coredump文件,可以帮忙加快分析程序崩溃的原因,比如了解崩溃的堆栈。 通常可以使用gdb和coreinfo…...
超级签名源码/超级签/ios分发/签名端本地linux服务器完成签名
该系统完全在linux下运行,不存在使用第三方收费工具,市面上很多系统都是使用的是第三方收费系统,例如:某心签名工具,某测侠等,不开源而且需要每年交费,这种系统只是在这些工具的基础上套了一层壳…...
RocketMQ在Centos7系统上单机部署
最近因为一些信创问题,要将RabbitMQ替换为RocketMQ,因此在此分享一些RocketMQ在Centos7系统上单机部署相关过程。 优缺点 RocketMQ的优点: 性能优越:RocketMQ在处理大量消息时,性能优于RabbitMQ。当面临每秒数万到数…...
Vue37-非单文件组件
一、组件的两种编写形式: 非单文件组件;单文件组件。 二、创建一个组件 2-1、组件中的el 组件中不写el,不说为谁服务。 2-2、组件中的data 因为对象形式,多处复用的话,有引用关系,改一处,另一…...
CSS实现经典打字小游戏《生死时速》
🌻 前言 CSS 中有这样一个模块:Motion Path 运动模块,它可以使元素按照自定义的路径进行移动。本文将为你讲解这个模块属性的使用,并且利用它实现我小时候电脑课经常玩的一个打字游戏:金山打字的《生死时速》。 &…...
推箱子-小游戏
学习目标: 巩固Java基础,数据类型、二维数组、条件语句等; 效果展示:...
AI数字人的开源解决方案
目前,国内外已经涌现出一些优秀的数字人开源解决方案,这些解决方案为开发者提供了构建数字人应用的工具和基础设施。以下是一些比较知名的数字人开源解决方案。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1…...
java写一个验证码
生成验证码 内容:可以是小写字母,也可以是大写字母,还可以是数字 规则 长度为5 内容中是四位字母,1位数字。 其中数字只有1位,但是可以出现在任意的位置。 package User;import java.util.ArrayList; import jav…...
【星海随笔】ELK优化
ELS 再遇到大的日志文件的时候不会自动进行清理的,我们可以通过 logrotate 转储工具进行操作。 该命令是基于 Cron 实现,由系统执行,当然也可以手动进行执行例如 logrotate -f configfile# more /etc/logrotate.confweekly // 默认每一周执行一次rotate轮转工作 r…...
SQL Auto Increment
SQL Auto Increment 在关系型数据库中,自动增量(Auto Increment)是一个常见且实用的特性。它允许数据库自动为表中插入的新行分配唯一的标识符,通常用于主键字段。本文将深入探讨SQL中的自动增量功能,包括其工作原理、…...
网络安全练气篇——PHP编程语言基础
目录 PHP基础 一、PHP简介与环境搭建 什么是PHP? PHP环境安装 代码编辑选择 二、基本语法 PHP基本语法操作 PHP变量与输出 啥是常量? PHP注释 PHP单引号双引号声明 三、PHP表单 PHP表单 四、登录界面搭建与讲解 构建登陆页面 登陆页面端 服务器端…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
Android写一个捕获全局异常的工具类
项目开发和实际运行过程中难免会遇到异常发生,系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler,它是Thread的子类(就是package java.lang;里线程的Thread)。本文将利用它将设备信息、报错信息以及错误的发生时间都…...
Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...
rm视觉学习1-自瞄部分
首先先感谢中南大学的开源,提供了很全面的思路,减少了很多基础性的开发研究 我看的阅读的是中南大学FYT战队开源视觉代码 链接:https://github.com/CSU-FYT-Vision/FYT2024_vision.git 1.框架: 代码框架结构:readme有…...
