C/C++语言知识点二
1. 编程算法之“哨兵”思想
哨兵思想是一种编程技巧,通过在数据结构的边界或特定位置放置一个特殊值(称为“哨兵”),来简化逻辑判断和提高代码效率。哨兵通常是一个标记值,用于指示某种条件或边界,从而避免额外的边界检查或条件判断。
哨兵思想的应用场合:
-
数组或链表的遍历:在遍历数组或链表时,可以在末尾放置一个哨兵值,避免在每次循环中检查是否越界。
// 例如,在查找数组中的某个元素时,可以将目标值作为哨兵放在数组末尾,从而简化查找逻辑。 int find(int arr[], int n, int target) {int last = arr[n - 1]; // 保存最后一个元素arr[n - 1] = target; // 将目标值作为哨兵int i = 0;while (arr[i] != target) {i++;}arr[n - 1] = last; // 恢复最后一个元素if (i < n - 1 || arr[n - 1] == target) {return i; // 找到目标值}return -1; // 未找到 } -
循环终止条件:
- 在循环中,哨兵可以作为终止条件,避免额外的判断。
- 例如,在读取用户输入时,可以使用特定的哨兵值(如
-1或EOF)来终止循环。int sum = 0; int value;while (true) {scanf("%d", &value);if (value == -1) { // -1 作为哨兵break;}sum += value; } printf("Sum: %d\n", sum);
-
排序算法:
- 在某些排序算法(如插入排序)中,哨兵可以减少比较次数。
- 例如,在插入排序中,可以将数组的第一个元素作为哨兵,避免每次比较时检查数组边界。
-
字符串处理:
- 在字符串处理中,哨兵可以标记字符串的结束位置。
- 例如,C 语言中的字符串以
\0作为哨兵,表示字符串的结束。
-
图的遍历:在图算法中,哨兵可以标记节点的访问状态或边界。
2. Linux内核代码中的一个宏定义
代码:
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
分析:
-
(TYPE *)0:将地址0强制类型转换为TYPE类型的指针。这里的0代表一个空指针,但通过类型转换,它被当作TYPE类型的对象来处理。 -
((TYPE *)0)->MEMBER:通过上述转换得到的指针访问其MEMBER成员。这一步实际上是在访问一个不存在的地址上的成员,但由于编译器在编译时会计算成员的偏移量,所以这一步是安全的。 -
&((TYPE *)0)->MEMBER:获取MEMBER成员变量的地址。由于MEMBER是通过类型转换后的指针访问的,所以这个地址实际上是MEMBER在TYPE结构体中的偏移地址。 -
(size_t)&((TYPE *)0)->MEMBER:将上述地址转换为size_t类型的数据。size_t是一个无符号整数类型,通常用于表示大小或偏移量。
总结:这个宏的作用是计算并返回 MEMBER 成员在 TYPE 结构体中的偏移量。这个偏移量是一个 size_t 类型的值,表示从结构体的起始地址到成员 MEMBER 的起始地址之间的字节数。
3. 64位和32位Linux系统字节对齐问题
代码分析:
#include <stdio.h>#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)typedef struct s
{union{int a;char str[10];};struct s* next;
} S;int main()
{printf("%d\n", offsetof(S, next));return 0;
}
案例:
#include <stdio.h>#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)typedef struct s
{union{int a;char str;};struct s* next;
} S;int main()
{printf("Size of S: %zu\n", sizeof(S));printf("Offset of next: %zu\n", offsetof(S, next));return 0;
}//结果32位、四字节对齐
Size of S: 16
Offset of next: 12//结果64位、八字节对齐
Size of S: 24
Offset of next: 16
4. const和指针的用法
在 C/C++ 中,const 关键字用于定义常量或指定某些数据不可修改。它可以应用于变量、指针、函数参数等,具有多种用法和含义。以下是 const 关键字的几种常见用法,特别是与指针结合时的不同含义:
1. 定义常量:const 可以用于定义常量,常量的值在定义后不能被修改。
const int MAX_VALUE = 100;特点:
定义时必须初始化。
不能通过赋值修改常量的值。
2. const 与指针:const 与指针结合时,可以有不同的含义,具体取决于 const 的位置。
(1) 指向常量的指针:
const int *pt;含义:pt 是一个指向 const int 的指针。指针可以指向不同的对象,但不能通过 pt 修改所指向的对象。示例:int a = 10;const int *pt = &a;// *pt = 20; // 错误:不能通过 pt 修改 aa = 20; // 正确:可以直接修改 a
(2) 常量指针:
int *const pt;含义:pt 是一个常量指针,指向 int 类型。指针的值(即指向的地址)不能修改,但可以通过 pt 修改所指向的对象。示例:int a = 10;int *const pt = &a;*pt = 20; // 正确:可以通过 pt 修改 a// pt = &b; // 错误:不能修改 pt 的值
(3) 指向常量的常量指针:
const int *const pt;含义:pt 是一个常量指针,指向 const int 类型。指针的值(即指向的地址)不能修改,也不能通过 pt 修改所指向的对象。示例:int a = 10;const int *const pt = &a;// *pt = 20; // 错误:不能通过 pt 修改 a// pt = &b; // 错误:不能修改 pt 的值
3. const 修饰函数参数:const 可以用于修饰函数参数,表示该参数在函数内部不能被修改。
(1) 修饰指针参数
void print(const int *arr, int size); // arr 是一个指向常量的指针,函数内部不能通过 arr 修改所指向的数据。
示例:
void print(const int *arr, int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}
}
(2) 修饰引用参数(C++)
void print(const std::string &str); // str 是一个常量引用,函数内部不能修改 str 的值
示例:
void print(const std::string &str) {std::cout << str;
}
4. const 修饰成员函数(C++):在 C++ 中,const 可以修饰类的成员函数,表示该函数不会修改类的成员变量。
class MyClass {
public:int getValue() const {return value;}
private:int value;
};// getValue 是一个常量成员函数,不能修改类的成员变量。
5. const 修饰返回值:const 可以用于修饰函数的返回值,表示返回值不能被修改。
const int* getPointer(); // 返回的指针指向的内容不能被修改。
6. const 修饰全局或局部变量:const 可以用于修饰全局或局部变量,表示变量的值不能被修改。
void func() {const int LOCAL_VALUE = 10;// LOCAL_VALUE = 20; // 错误:不能修改常量
}
总结:const 关键字的用法非常灵活,主要作用是保证数据的不变性。以下是一些常见的应用场景:
- 定义常量。
- 修饰指针,限制指针或指向数据的修改。
- 修饰函数参数,防止参数被修改。
- 修饰成员函数(C++),保证函数不修改对象状态。
- 修饰返回值,限制返回值的修改。
通过合理使用 const,可以提高代码的安全性和可读性,避免意外的数据修改。
5. fork函数
分析代码:
int main() {fork() || fork();
}
-
fork()的作用:fork()创建一个新的进程(子进程),子进程是父进程的副本。fork()在父进程中返回子进程的 PID(大于 0),在子进程中返回 0。- 如果
fork()失败,返回 -1。
-
逻辑或运算符
||的特性:A || B:如果A为真(非零),则不会执行B(短路特性)。- 如果
A为假(零),则继续执行B。
进程创建过程:
-
第一次
fork():- 父进程调用
fork(),创建一个子进程。 - 父进程中,
fork()返回子进程的 PID(大于 0),因此fork() || fork()的值为真,短路特性生效,不会执行第二个fork()。 - 子进程中,
fork()返回 0,因此fork() || fork()的值为假,继续执行第二个fork()。
- 父进程调用
-
第二次
fork():- 只有在第一次
fork()创建的子进程中,才会执行第二个fork()。 - 子进程调用
fork(),创建另一个子进程(孙子进程)。 - 子进程中,
fork()返回孙子进程的 PID(大于 0),因此fork() || fork()的值为真,短路特性生效。 - 孙子进程中,
fork()返回 0,因此fork() || fork()的值为假。
- 只有在第一次
进程树结构:
父进程
|
├─ 子进程
| |
| └─ 孙子进程
|
└─ 子进程
进程总数:总共创建了 3 个进程。
- 父进程:1 个。
- 子进程:1 个。
- 孙子进程:1 个。
总结:
- 代码
fork() || fork()会创建 3 个进程。 - 第一次
fork()创建 1 个子进程。 - 第二次
fork()在子进程中创建 1 个孙子进程。 - 父进程和子进程都会执行
fork(),但由于逻辑或运算符的短路特性,父进程不会执行第二个fork()。
6. 按指针引用值传递参数
代码分析: 下面这段代码的输出结果为:
#include <stdio.h>
void change(int *a, int &b, int c)
{c=*a;b=30;*a=20;
}int main ( )
{int a = 10, b = 20, c = 30;change(&a, b, c);printf( "%d, %d, %d, ", a, b, c);return 0;
}
1. 函数 change 的参数传递
int *a:- 传递指针,函数内部可以通过指针修改
a的值。
- 传递指针,函数内部可以通过指针修改
int &b:- 传递引用(C++ 特性),函数内部可以直接修改
b的值。
- 传递引用(C++ 特性),函数内部可以直接修改
int c:- 传递值,函数内部对
c的修改不会影响外部的c。
- 传递值,函数内部对
2. 函数 change 的逻辑
void change(int *a, int &b, int c)
{c = *a; // 将指针 a 指向的值赋值给 c(局部变量,不影响外部的 c)b = 30; // 将引用 b 的值修改为 30*a = 20; // 将指针 a 指向的值修改为 20
}
3. main 函数的逻辑
int main()
{int a = 10, b = 20, c = 30;change(&a, b, c);printf("%d, %d, %d, ", a, b, c);return 0;
}
- 调用
change函数:&a传递a的地址。b传递b的引用。c传递c的值。
change函数执行后:*a = 20修改了a的值为20。b = 30修改了b的值为30。c = *a修改了局部变量c的值为10,但外部的c不受影响。
总结:
- 指针
int *a:可以修改外部变量的值。 - 引用
int &b:可以直接修改外部变量的值。 - 值传递
int c:对局部变量的修改不影响外部变量。
最终输出结果为:20, 30, 30。
7. 调用几次构造函数
题目内容是:
若
MyClass为一个类,执行MyClass a, *p;语句时会自动调用该类构造函数的次数是()
选项:
- A: 2
- B: 5
- C: 4
- D: 9
解题思路:
-
MyClass a:- 这是一个数组,包含 4 个
MyClass对象。 - 每个对象在创建时都会调用构造函数,因此会调用 4 次构造函数。
- 这是一个数组,包含 4 个
-
MyClass *p:- 这是一个指针数组,包含 5 个
MyClass类型的指针。 - 指针本身是内置类型,不会调用
MyClass的构造函数。 - 这些指针默认初始化为
nullptr,不会创建MyClass对象。
- 这是一个指针数组,包含 5 个
-
总结:
MyClass a会调用 4 次构造函数。MyClass *p不会调用构造函数。- 总共调用构造函数的次数是 4 次。
8. 统计二进制数中1的个数
题目内容是:
要求:求下面函数的返回值:
int func(int x)
{int countx = 0;while(x){countx++;x = x&(x-1);}return countx;
}
这个函数的返回值是 整数 x 的二进制表示中 1 的个数。以下是详细分析:
解题思路:
-
x = x & (x - 1):- 这个操作会将
x的二进制表示中最右边的1置为0。 - 例如:
- 如果
x = 12(二进制1100),则x - 1 = 11(二进制1011)。 x & (x - 1) = 1100 & 1011 = 1000(二进制1000)。- 下一次循环时,
x = 8(二进制1000),x - 1 = 7(二进制0111)。 x & (x - 1) = 1000 & 0111 = 0000(二进制0000)。- 循环结束。
- 如果
- 这个操作会将
-
countx++:- 每次循环将
countx加 1,表示找到了一个1
- 每次循环将
示例 1:
int x = 12; // 二进制 1100
int result = func(x);分析
第一次循环:x = 1100,x & (x - 1) = 1000,countx = 1。
第二次循环:x = 1000,x & (x - 1) = 0000,countx = 2。
循环结束,返回 2。
示例 2:
int x = 7; // 二进制 0111
int result = func(x);分析:
第一次循环:x = 0111,x & (x - 1) = 0110,countx = 1。
第二次循环:x = 0110,x & (x - 1) = 0100,countx = 2。
第三次循环:x = 0100,x & (x - 1) = 0000,countx = 3。
循环结束,返回 3。
9. 编写代码:判断一个数是不是2的N次方
方法 1:利用二进制特性
2 的 N 次方的二进制表示中,只有一个 1,其余位都是 0。例如:
1(2⁰):00012(2¹):00104(2²):01008(2³):1000
因此,判断一个数是否是 2 的 N 次方,可以检查它的二进制表示是否只有一个 1。
#include <stdio.h>int isPowerOfTwo(int x) {// 如果 x 是 2 的 N 次方,则 x & (x - 1) == 0return x > 0 && (x & (x - 1)) == 0;
}int main() {int x;printf("Enter a number: ");scanf("%d", &x);if (isPowerOfTwo(x)) {printf("%d is a power of two.\n", x);} else {printf("%d is not a power of two.\n", x);}return 0;
}
解释:
x > 0:确保x是正整数。(x & (x - 1)) == 0:如果x是 2 的 N 次方,则x & (x - 1)的结果为0。
方法 2:循环除以 2
通过循环将 x 反复除以 2,如果最终结果为 1,则 x 是 2 的 N 次方。
#include <stdio.h>int isPowerOfTwo(int x) {if (x <= 0) {return 0; // 非正整数不可能是 2 的 N 次方}while (x > 1) {if (x % 2 != 0) {return 0; // 如果不能被 2 整除,则不是 2 的 N 次方}x /= 2;}return 1; // 最终结果为 1,是 2 的 N 次方
}int main() {int x;printf("Enter a number: ");scanf("%d", &x);if (isPowerOfTwo(x)) {printf("%d is a power of two.\n", x);} else {printf("%d is not a power of two.\n", x);}return 0;
}
解释:
- 如果
x能被 2 整除,则继续除以 2,直到x变为1。 - 如果在过程中
x不能被 2 整除,则不是 2 的 N 次方。
方法 3:利用对数
如果 log₂(x) 是整数,则 x 是 2 的 N 次方。
#include <stdio.h>
#include <math.h>int isPowerOfTwo(int x) {if (x <= 0) {return 0; // 非正整数不可能是 2 的 N 次方}double log2x = log2(x);return log2x == (int)log2x; // 判断 log2x 是否为整数
}int main() {int x;printf("Enter a number: ");scanf("%d", &x);if (isPowerOfTwo(x)) {printf("%d is a power of two.\n", x);} else {printf("%d is not a power of two.\n", x);}return 0;
}
解释:
- 计算
log₂(x),如果结果是整数,则x是 2 的 N 次方。
总结:
- 推荐方法:方法 1(利用二进制特性),效率最高,代码简洁。
- 其他方法:方法 2 和方法 3 也可以实现,但效率较低。
#include <stdio.h>#define ISPOWER_OF_TWO(x) ((x&(x-1))==0)int main(void)
{int n;printf("Please enter a number, n = ");scanf("%d", &n);if(ISPOWER_OF_TWO(n))printf("n is the power of two\n");elseprintf("n is not the power of two\n");return 0;
}
#include <stdio.h>#define ISPOWER_OF_TWO(x) ((x > 0) && ((x & (x - 1)) == 0))int main(void)
{int n;printf("Please enter a number, n = ");scanf("%d", &n);if(ISPOWER_OF_TWO(n))printf("n is the power of two\n");elseprintf("n is not the power of two\n");return 0;
}相关文章:
C/C++语言知识点二
1. 编程算法之“哨兵”思想 哨兵思想是一种编程技巧,通过在数据结构的边界或特定位置放置一个特殊值(称为“哨兵”),来简化逻辑判断和提高代码效率。哨兵通常是一个标记值,用于指示某种条件或边界,从而避免…...
国产OS上完整编译Qt5.15、搭建基本开发环境需要的库
近期有师弟问我国产OS安装Qt5.15编译老是不完整,不是没声音,就是没视频,或者没有xcb。通过QEMU模拟Arm64,闲来20几天摸索,完整编译了Qt5.15,并编译成功了我的SDR玩具taskBus。 1.主要结论: 该O…...
Python 编程题第一节:判断素数、求阶乘、求圆的周长和面积、求三角形斜边长、比较三个数的大小、找出区间内的素数
判断素数 挺简单的,设一个flag来判断是否是素数,从2开始到前一个数,可以整除便不是素数,1不是素数 aint(input()) flagFalse for i in range(2,a):if a%i0:flagTruebreak if flagTrue or a1:print("不是素数") else:p…...
Python批量压缩并上载CSV数据文件到Box企业云盘
Python在Windows下批量压缩CSV文件为ZIP并异步上传到Box企业云,需整合文件处理、异步任务、配置管理和日志记录功能。 该方案通过线程池实现异步上传,每个文件独立压缩处理,异常发生时继续后续任务。日志系统记录完整操作流水,配置…...
MyBatis简明教程
MyBatis 是一个用于简化数据库操作的持久层框架,它的核心思想是 将 SQL 与 Java 代码解耦,让开发者专注于 SQL 的编写,同时自动处理重复的数据库操作步骤。 一、核心思想:SQL 与 Java 解耦 传统 JDBC 需要开发者手动管理数据库连…...
有什么区别?Elastic 和 Splunk 数据层
作者:来自 Elastic Ugo Sangiorgi, Matt Wehle 了解 Elastic 和 Splunk 数据管理方法之间的主要区别,以便做出明智的决策,实现高效的数据处理 在数据管理领域,在讨论如何根据不同的性能要求提供和/或保留数据时,经常会…...
Tips :仿真竞争条件 指的是什么?
文章目录 **为什么会出现仿真竞争条件?****典型场景举例****System Verilog 如何解决竞争条件?****1. 使用 `program` 块隔离测试平台****2. 使用 `clocking` 块明确时序关系****3. 非阻塞赋值(`<=`)的合理使用****竞争条件的根本原因****总结****代码结构****1. 设计模…...
BGP状态和机制
BGP邻居优化 为了增加稳定性,通常建议实验回环口来建立邻居。更新源:建立邻居和邻居所学习到的路由的下一跳。多跳:EBGP邻居建立默认选哟直连,因为TTL=1,如果非直连,必须修改TTL。命令备注peer 2.2.2.2 connect-interface lo1配置更新源peer 2.2.2.2 ebgp-max-hop 2配置T…...
【电机控制器】PY32F00BF15U6TR-从KEIL5中计算资源消耗资源
【电机控制器】PY32F00BF15U6TR-从KEIL5中计算资源消耗资源 文章目录 [TOC](文章目录) 前言一、MCU芯片手册二、实验三、实验结论四、参考资料总结 前言 使用工具: 1.KEIL5编译器 提示:以下是本篇文章正文内容,下面案例可供参考 一、MCU芯片…...
CaffeineCache自定义缓存时间
文章目录 1、POM文件依赖2、声明缓存3、缓存使用4、测试缓存5、自定义缓存过期时间6、测试自定义超时时间 1、POM文件依赖 <dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>3.1…...
python实战项目58:采集蜻蜓FM热门音频top排行榜
python实战项目58:采集蜻蜓FM热门音频top排行榜 一、采集流程介绍二、数据接口采集三、使用xpath提取页面数据1、抓包,找到数据接口2、发送请求,获取数据3、提取数据4、保存数据一、采集流程介绍 蜻蜓FM热门音频top排行榜的链接为: https://m.qingting.fm/rank/,首页如下图…...
STM32【3】芯片的底层组成概论
关于单片机的组成 单片机的意思是,小小计算电脑,麻雀虽小,五脏俱全,里面包含了CPU,ROM,RAM,各种外设。 CPU地位最高,可以访问ROM和RAM,Flash,GPIO等外设&…...
基于django图书信息管理系统的搭建(增删改查)
✍django项目搭建教程 ☞ ----------------- 教程 本文主要讲解django如何连接数据库MySQL并且可视化展示,实现增删改查功能 目录 一. 创建django应用 二. 数据库配置 三. 查看数据库 四. 编写代码 4.1视图函数 4.2 配置URL 4.3创建模板文件 4.…...
Kotlin 知识点二 延迟初始化和密封类
对变量延迟初始化 Kotlin 语言的许多特性,包括变量不可变,变量不可为空,等等。这些特性 都是为了尽可能地保证程序安全而设计的,但是有些时候这些特性也会在编码时给我们带来不 少的麻烦。 比如,如果你的类中存在很多…...
基于SpringBoot的“古城景区管理系统”的设计与实现(源码+数据库+文档+PPT)
基于SpringBoot的“古城景区管理系统”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SpringBoot 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统整体功能图 系统首页界面 系统注册界面 景…...
QT C++ QtConcurrent::run 异步任务 简单例子
QtConcurrent命名空间提供了高级API,使得无需使用低级线程原语即可编写多线程程序。 QtConcurrent::run是Qt框架中用于简化并发编程的一个功能,主要用于在后台线程中异步执行函数或成员函数。其主要用途包括: 异步执行函数…...
力扣hot100 —— 电话号码字母组合; 子集 (非回溯做法)简单易懂
由于博主对回溯也不是很熟悉,这里提出一种简单易懂的解法(有点暴力) 解题思路: 每个数字对应有自己的字母串; 首先遍历将每个字母存入也就是 res{{a},{b},{c}} 然后遍历后续数子对应的字母,让每个字母与…...
企业业务安全进阶之路:AI技术与数据分析的应用
在数字化时代,企业业务安全面临着前所未有的挑战。从网络安全到数据保护,每一个环节都至关重要。本文将探讨如何通过AI技术和数据分析来提升企业业务安全防护能力,确保企业在不断变化的安全威胁面前保持领先地位。 企业业务安全的重要性 企…...
windows本地升级npm
## 在管理员身份的cmd中: 运行以下命令来安装npm-windows-upgrade工具: npm install --global --production npm-windows-upgrade运行以下命令来升级到最新版本的npm: npm-windows-upgrade --npm-version latest如果你想升级到特定版本的n…...
【Redis】在Java中以及Spring环境下操作Redis
Java环境下: 1.创建maven 项目 2.导入依赖 <!-- redis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.2</version></dependency> 此处使用的是Jedis&…...
Sqlserver安全篇之_隐藏实例功能和禁用SQL Server Browser服务
总结: 1、隐藏实例功能和禁用SQL Server Browser服务的功能一样,对应非默认实例(且这个默认实例是1433端口)的情况下,都是需要在连接字符串中提供端口号才能连接到实例 2、隐藏实例功能后,就算开启了SQL Server Browser服务&#…...
Directx上传堆和默认堆注意事项
前景 之前我用directx写上传堆上传给默认堆Index,但是我发现数据无法被GPU读取 void HelloTriangle::createDefaultBuffer(const void* data, const UINT byteSize, ComPtr<ID3D12Resource>& defaultBuffer) {ThrowIfFiled(m_Device->CreateCommitte…...
Java封装弱密码校验工具类
弱密码校验工具类 通过检查密码是否符合某些安全策略来判断其强度 ● 密码长度 ● 字符类型 ● 常见密码组合 import java.util.Arrays; import java.util.HashSet; import java.util.Set;public class WeakPasswordCheckUtil {// 常见弱密码列表(可根据需求扩展&…...
Figure自研模型Helix发布,人形机器人迈向新纪元?
Figure 公司自 2022 年成立以来,便在人形机器人领域崭露头角,成为行业内备受瞩目的新星。公司由连续创业者 Brett Adcock 创立,总部位于美国加利福尼亚州桑尼维尔,汇聚了来自波士顿动力公司、特斯拉、谷歌 DeepMind 等知名企业的顶…...
vue3.0将后端返回的word文件流转换为pdf并导出+html2pdf.js将页面导出为pdf
实现思路 1.将Word文档转换为HTML:mammoth.js,它可以将.docx文件转换为HTML 2.将HTML转换为PDF:使用html2pdf.js将HTML转换为PDF 如果想要相同的效果,也可以把前端页面直接导出转换为pdf: 运用的插件:html2pdf.js 后端…...
(Arrow)试时间处理变得更简单
前言 Arrow库并不是简单的二次开发,而是在datetime的基础上进行了扩展和增强。它通过提供更简洁的API、强大的时区支持、丰富的格式化和解析功能以及人性化的显示,填补了datetime在某些功能上的空白。如果你需要更高效、更人性化的日期时间处理方式,Arrow库是一个不错的选择…...
SV基础(一):System Verilog与Verilog核心区别详解
文章目录 **1. 设计增强功能****数据类型扩展****接口(Interface)****2. 验证功能增强****断言(Assertions)****约束随机测试****功能覆盖率****3. 面向对象编程(OOP)****4. 测试平台(Testbench)改进****5. 语法简化****6. 其他关键区别****学习建议**System Verilog 是…...
锂电池使用和存储电压
表格补充说明: 每列数据中,2S和3S电池的数值都是单电芯数值的2倍和3倍;对于其他电压的电池,将单电芯数值乘以相应S数即可;理论上单个电芯过放电压为3.0V,实际中为了保险,电压降到3.6V即需充电。…...
【docker】namespace底层机制
Linux 的 Namespace 机制是实现容器化(如 Docker、LXC 等)的核心技术之一,它通过隔离系统资源(如进程、网络、文件系统等)为进程提供独立的运行环境。其底层机制涉及内核数据结构、系统调用和进程管理。以下是其核心实…...
欧拉回路与哈密尔顿回路: Fleury算法与Hierholzer 算法(C++)
图论中的回路是指一个路径, 它从某个顶点开始, 经过所有边恰好一次, 并回到起始顶点. 定义 欧拉回路: 从一个顶点出发, 经过每条边恰好一次, 并且最终回到起始顶点. 哈密尔顿回路: 从一个顶点出发, 经过每个顶点恰好一次, 并且最终回到起始顶点. 欧拉路径: 从一个顶点出发, …...
