深入探讨C存储类和存储期——Storage Duration
🔗 《C语言趣味教程》👈 猛戳订阅!!!
—— 热门专栏《维生素C语言》的重制版 ——
- 💭 写在前面:这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅!本专栏保证篇篇精品,继续保持本人一贯的幽默式写作风格,当然,在有趣的同时也同样会保证文章的质量,旨在能够产出 "有趣的干货" !本系列教程不管是零基础还是有基础的读者都可以阅读,可以先看看目录! 标题前带星号 (*) 的部分不建议初学者阅读,因为内容难免会超出当前章节的知识点,面向的是对 C 语言有一定基础或已经学过一遍的读者,初学者可自行选择跳过带星号的标题内容,等到后期再回过头来学习。值得一提的是,本专栏 强烈建议使用网页端阅读! 享受极度舒适的排版!你也可以展开目录,看看有没有你感兴趣的部分!希望需要学 C 语言的朋友可以耐下心来读一读。最后,可以订阅一下专栏防止找不到。
" 有趣的写作风格,还有特制的表情包,而且还干货满满!太下饭了!"
—— 沃兹基硕德
【C语言趣味教程】(7) 存储类:auto 关键字 | register 关键字 | 存储期 | 自动存储期 | 动态存储期 | 线程存储期 | 动态分配存储期 | 静态变量
📜 本章目录:
Ⅰ. 存储类(Storage Class)
0x00 引入:什么是存储类?
0x01 auto 关键字
0x01 注意:auto 只能修饰局部变量!
* 0x02 拓展阅读:C++ 中改版后的 auto
0x03 static 关键字初探
* 0x04 register 关键字
0x05 extern 关键字
Ⅱ. 存储期(Storage Duration)
0x00 引入:存储器的概念
0x01 自动存储期
0x02 静态存储期
* 0x03 动态分配存储期
* 0x04 线程存储期
Ⅲ. 静态变量(Static)
0x00 static 关键字
0x01 局部静态变量
0x02 全局静态变量
0x03 静态变量的初始值默认为0
Ⅰ. 存储类(Storage Class)
0x00 引入:什么是存储类?
❓ 你没有听说过存储类的概念?
存储类 (Storage Class) 在 C 语言标准中用来 规定变量与函数的可访问性与生命周期。
"可访问性" 的概念就是我们上一章说的作用域范围,我们先关注以下 4 种存储类别:
auto
static
register
extern
简单来说,存储类别定义了变量和函数的存储位置、生命周期和作用域。
为什么要引出存储类的概念?
大多数教程似乎并不涉及 "存储类" 的说法概念,讲解 auto, static 等关键字的时候都是直接介绍,而不引出存储类 (即 Storage Class) 的概念。
正因如此,我们想把存储类的概念单独抽出来作为一个章节去讲解,介绍存储类的概念,介绍一些常见的存储类别 (auto, staitc, register...) 。而不是单独的介绍这些关键字,孤立疏远它们的联系。
当然了,如果你是 C 语言初学者,一开始就接触存储类的概念大有裨益,利于体系化学习。如果你掌握 C语言基础,但是似乎之前没有听说过这个概念,也不用担心。像常见的 auto, extern, register, static 等关键字就属于 "存储类",通过本章的学习,可以体系化地了解这些东西,把它们归类起来。
0x01 auto 关键字
auto 是 "自动" 的意思,代表 变量在函数开始时自动创建,在函数结束时被自动销毁。
即使用 auto 修饰的变量,是具有自动存储器的局部变量。
auto int a = 0; // 表示a是一个自动存储类型,会在函数结束后自动销毁。
遗憾的是,大家都懒得去用它,这是为什么呢?
因为定义在函数中的所有变量都是自带 auto 的,即局部变量都是自带 auto 的。
💭 举个例子:
auto int a = 10; (A)
int a = 10; (B)
(A) 和 (B) 是一样的效果,我们不需要手动去加,因为 auto 是所有局部变量的默认存储类。
当使用 auto 修饰后,表示 a 是一个自动存储类型,它会在函数结束以后自动销毁。
0x01 注意:auto 只能修饰局部变量!
值得注意的是,auto 只能在函数内使用!这就意味着 auto 只能修饰局部变量。
❌ 错误演示:auto 修饰全局变量
#include <stdio.h> auto int a = 10; // 全局变量int main(void)
{auto int b = 20; // 局部变量return 0;
}
🚩 运行结果:error E0149
此时必然会触发报错和警告:warning C4042: “a”: 有坏的存储类
* 0x02 拓展阅读:C++ 中改版后的 auto
温馨提示:以下内容涉及 C++,读者可按自身情况阅读。
C++ 标准委员会觉得这 auto 也太尴尬了,我们得给它来一波加强。为了缓解 auto 的尴尬,C++ 标准委员会把 auto 原来的功能给废弃了。并赋予了 auto 全新的含义!
📚 游戏更新补丁(bushi):auto 现在不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器。auto 声明的变量必须由编译器在编译时推导而得。
也就是说,它可以自动推导出数据的类型:
int a = 0;
auto c = a; // C++11给auto关键字赋予了新的意义:自动推导c的类型
你的右边是什么,它就会推导出相应的类型,任何类型都可以实现,包括但不限于:
auto ch = 'A';
auto e = 10.11;
auto pa = &a;
为了方便测试,我们来打印一下对象的类型看看:
#include<iostream>
using namespace std;int main()
{int a = 0;auto c = a; // 自动推导c的类型auto ch = 'A';auto e = 10.11;auto pa = &a;// typeid - 打印对象的类型cout << typeid(c).name() << endl; // icout << typeid(ch).name() << endl; // ccout << typeid(e).name() << endl; // dcout << typeid(pa).name() << endl; // Pireturn 0;
}
🚩 运行结果如下:
emmm... 确实
这时候可能有人会觉得,这一波操作好像也没啥意义啊,
直接写数据类型不香吗?int c = a,我们继续往下看~
💭 举个例子:auto 的使用场景
处理又臭又长的数据类型
💬 遇到这种场景,就能体会到 auto 的香了:
#include <iostream>
#include <map>int main(void)
{std::map<std::string, std::string> dict = {{"sort", "排序"}, {"insert", "插入"}};std::map<std::string, std::string>::iterator it = dict.begin();// 这个类型又臭又长,写起来太麻烦了。。。auto it = dict.begin(); // 可以改成这样,爽!// ↑ 根据右边的返回值去自动推导it的类型,写起来就方便多了return 0;
}
像遇到这种又臭又长的类型,而且还要经常使用。
这时候使用 auto 帮你自动推到类型,就很爽了!
📌 注意事项:使用 auto 是必须要给值的!
int i = 0;
auto j; ❌auto j = i; 必须给值!!
这就意味着,auto 是不能做参数的!
auto 不能作为函数的参数
void TestAuto(auto a); ❌
此处代码编译失败,auto 不能作为形参类型,因为编译器无法对 a 的类型进行推导!
auto 不能直接用来声明数组
auto b[3] = {4,5,6}; ❌
📌 为了避免与 C++98 中的 auto 发生混淆,C++11 只保留了 auto 作为类型指示符的用法。
auto 在实际中最常见的优势用法就是 C++11 提供的新式 for 循环,
还有 lambda 表达式等进行配合使用。我们可以继续往下看~
auto 与指针结合起来使用:
📚 改版后的 auto 非常聪明,它在推导的时候其实是非常灵活的:
int main(void)
{int x = 10;auto a = &x; // int*auto* b = &x; // int*auto& c = x; // intreturn 0;
}
在同一行定义多个变量
当在同一行声明多个变量时,这些变量必须是相同的类型!
否则编译器将会报错,因为编译器实际只对第一个类型进行推导,
然后用推导出来的类型定义其他变量。
auto a = 1, b = 2;
auto c = 3, d = 4.0; ❌ 该行代码会编译失败,因为c和d的初始化表达式类型不同
0x03 static 关键字初探
static 是全局变量的默认存储类,它指示编译器在程序的生命周期内保持局部变量的存在。
static int a;
而不会像 auto 那样,每次进入和离开作用域时都会进行创建和销毁。
因此,我们可以使用 static 修饰局部变量在 "延长" 局部变量的生命周期。
让它能在函数调用之间保持局部变量的值。
static 也可以作用于全局变量,当 static 修饰全局变量时会让作用于提升至声明它的文件内。
静态变量的初始化:静态变量只被初始化一次,及时函数调用多次该变量的值也不会重置。
* 0x04 register 关键字
寄存器变量通常被存储在内存中,如果运气不错,寄存器变量就可以被存储在 CPU 寄存器中。
寄存器变量的访问速度比普通变量快的多。
而 register 关键字就是用来建议编译器把局部变量或函数的形参放入 CPU 的寄存器中的。
放到寄存器可以提高访问速度,如果一个变量比较常用,我们可以考虑加上 register 修饰:
register int count;
值得注意的是,register 对编译器只是一个 "建议",具体情况得看硬件和各种限制是否通过。
准确来说这是对编译器的一个请求,而不是一个命令,请求需要同意,命令无需同意。
这也是为什么在开头我说 "如果运气不错",用了 register 能不能放进去是要看天时地利人和的。
"天时地利人和,缺一不可。"
被 register 修饰的变量,编译器将尽可能地将其存入 CPU 的寄存器中。
并且,既然要存到寄存器中,那么 变量的字节长度应小于等于寄存器的长度。
局部变量存储在 RAM 中,而 register 可以建议编译器将某变量存到 CPU 寄存器中。
因此,如果一个变量需要频繁访问,可以使用 register 声明一下,提高程序的运行速度。
📌 注意事项:不能对 register 使用取地址 &,因为它没有内存位置。
0x05 extern 关键字
extern 关键字用于定义在其他文件中声明的全局变量或函数。
extern 让全局变量可以被各个对象模块访问。
使用 extern 关键字时,表示变量已经在别处定义,不能再初始化。
Ⅱ. 存储期(Storage Duration)
0x00 引入:存储器的概念
存储期描述了通过这些标识访问对象的生命周期,简单来说就是变量在内存中的 "存活期"。
C 语言中有 4 种存储期,分别是:
我们下面将逐个介绍它们,对于初学者来说只需做一个简单的了解即可。
0x01 自动存储期
我们一般在函数中创建的变量 (没被 static 定义的变量),都具有 "自动存储期"。
int main(void)
{int a; // 具有自动存储期
}
具有自动存储期的变量,仅存在于当前代码块内(大括号)。
如果不给自动存储期的变量初始化,会自动初始化一个不确定的随机值。
0x02 静态存储期
函数中用 static 关键字定义出来的变量,或在函数外声明定义的对象都具有 "静态存储期"。
int A; // 具有静态存储期int main(void)
{static int b; // 具有静态存储期
}
具有静态存储期的变量,从程序开始结束该变量会一直存在,寿 (生命周期) 与天 (程序) 齐。
同时具备自动初始化为 0 的特性,即不给这个变量初始化,变量的初始值默认为 0。
* 0x03 动态分配存储期
C 语言中的动态存储期是指在程序运行时分配和释放内存的过程。
这种存储期允许程序在运行时根据需要来管理内存,以适应不同的数据结构和问题需求。
动态存储期主要通过 malloc
和 free 实现。
(该部分知识点将在动态内存分配章节补充讲解)
* 0x04 线程存储期
线程存储期 (Thread-Local Storage),它的生命周期是创建它的线程的整个执行过程。
比如并发中具有线程存储期的对象,在该线程开始执行时创建,在线程结束时销毁。
这意味着每个线程都拥有其自己的一组变量副本,这些副本在不同的线程中具有不同的值。
举个例子,我们使用线程存储期来存储线程特定的数据。
💬 代码演示:线程 ID 计数器
#include <stdio.h>
#include <pthread.h>// 定义线程存储期变量
__thread int threadSpecificValue = 0;// 线程执行的函数
void* threadFunction(void* arg) {// 每个线程可以独立地修改 threadSpecificValue 的值threadSpecificValue = threadSpecificValue + 1;printf("Thread ID: %ld, \threadSpecificValue: %d\n", \pthread_self(), \threadSpecificValue);return NULL;
}int main() {pthread_t thread1, thread2;// 创建两个线程pthread_create(&thread1, NULL, threadFunction, NULL);pthread_create(&thread2, NULL, threadFunction, NULL);// 等待线程结束pthread_join(thread1, NULL);pthread_join(thread2, NULL);return 0;
}
💡 解读:我们定义了线程存储期变量 threadSpecificValue
,每个线程都有其自己的副本。可以看到在 threadFunction
中,每个线程独立地对 threadSpecificValue
进行递增操作,并打印出线程的 ID 以及变量的值。因为每个线程都有自己的变量副本,所以每个线程的输出是独立的。(这里用的 __thread
是 GCC 编译器的扩展,用于声明线程存储期变量)
使用存储类说明符声明标识符的对象
_Thread_local
(自C11开始)具有线程存储持续时间。它的生命周期是创建它的线程的整个执行过程,并且在线程启动时初始化它的存储值。每个线程都有一个独特的对象,并且在表达式中使用声明的名称是指与评估表达式的线程相关联的对象。尝试从与对象关联的线程以外的线程间接访问具有线程存储持续时间的对象的结果是实现定义的。
这边再多提一下,C++ 11 引入了 thread_local 关键字,用于声明线程局部变量。线程局部变量在每个线程中都有独立的实例,因此在不同线程中访问这些变量时不会相互干扰。
#include <stdio.h>
#include <threads.h>thread_local int tls_var = 0;int main() {thrd_t thread;thrd_create(&thread, another_thread, NULL);tls_var = 42;printf("Main thread TLS: %d\n", tls_var);thrd_join(thread, NULL);return 0;
}int another_thread(void *arg) {tls_var = 99;printf("Another thread TLS: %d\n", tls_var);return 0;
}
还可以使用 POSIX 线程局部存储函数,在 POSIX 线程库中,可以使用这些函数来创建和操作线程局部存储:
pthread_key_create()
pthread_setspecific()
pthread_getspecific()
线程局部存储允许每个线程维护一份独立的数据副本,这对于需要在线程之间保持独立状态的情况非常有用,例如线程特定的配置信息、日志句柄等操作。
Ⅲ. 静态变量(Static)
0x00 static 关键字
我们可以用 static 关键字来修饰一个变量为静态变量,修饰方法如下:
static 数据类型 变量名;
如果我们想让一个变量为静态变量,我们就在其数据类型前加一个 static 关键字就行了。
静态变量可以重复赋值,默认初始化的值为 0。
静态变量会被分配在静态存储区,静态变量在数据段中,函数退出后变量值不变。
上一章中我们学习了全局变量和局部变量,静态变量也是分全局和局部的。
分别是 静态局部变量 和 静态全局变量,下面我们将逐个介绍。
0x01 局部静态变量
静态局部变量的作用域和局部变量一致,在自己所处的代码块内有效。
但是生命周期被 "提升" 成全局的了,生命周期与全局变量一致,在整个程序运行期间有效。
0x02 全局静态变量
静态全局变量的作用域在定义它的源文件内。
它的生命周期和全局变量一致,在整个程序运行期间有效。
举个例子,如果我们在一个源文件中定义了静态全局变量,那么该变量只能在该源文件内使用。
0x03 静态变量的初始值默认为0
静态变量的初始值都是 0,静态局部变量和静态全局变量的初始值都是 0。
💬 代码演示:静态变量的初始值为 0
#include <stdio.h>static A;int main(void)
{static a;printf("静态局部变量 a = %d\n", a);printf("静态局部变量 A = %d\n", a);return 0;
}
🚩 运行结果如下:
📌 [ 笔者 ] 王亦优 | 雷向明
📃 [ 更新 ] 2023.8.27
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,本人也很想知道这些错误,恳望读者批评指正!
📜 参考文献: - C++reference[EB/OL]. []. http://www.cplusplus.com/reference/. - Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . - 百度百科[EB/OL]. []. https://baike.baidu.com/. - 维基百科[EB/OL]. []. https://zh.wikipedia.org/wiki/Wikipedia - R. Neapolitan, Foundations of Algorithms (5th ed.), Jones & Bartlett, 2015. - B. 比特科技. C/C++[EB/OL]. 2021[2021.8.31] - 林锐博士. 《高质量C/C++编程指南》[M]. 1.0. 电子工业, 2001.7.24. - 陈正冲. 《C语言深度解剖》[M]. 第三版. 北京航空航天大学出版社, 2019. - 侯捷. 《STL源码剖析》[M]. 华中科技大学出版社, 2002. - T. Cormen《算法导论》(第三版),麻省理工学院出版社,2009年。 - T. Roughgarden, Algorithms Illuminated, Part 1~3, Soundlikeyourself Publishing, 2018. - J. Kleinberg&E. Tardos, Algorithm Design, Addison Wesley, 2005. - R. Sedgewick&K. Wayne,《算法》(第四版),Addison-Wesley,2011 - S. Dasgupta,《算法》,McGraw-Hill教育出版社,2006。 - S. Baase&A. Van Gelder, Computer Algorithms: 设计与分析简介》,Addison Wesley,2000。 - E. Horowitz,《C语言中的数据结构基础》,计算机科学出版社,1993 - S. Skiena, The Algorithm Design Manual (2nd ed.), Springer, 2008. - A. Aho, J. Hopcroft, and J. Ullman, Design and Analysis of Algorithms, Addison-Wesley, 1974. - M. Weiss, Data Structure and Algorithm Analysis in C (2nd ed.), Pearson, 1997. - A. Levitin, Introduction to the Design and Analysis of Algorithms, Addison Wesley, 2003. - A. Aho, J. - E. Horowitz, S. Sahni and S. Rajasekaran, Computer Algorithms/C++, Computer Science Press, 1997. - R. Sedgewick, Algorithms in C: 第1-4部分(第三版),Addison-Wesley,1998 - R. Sedgewick,《C语言中的算法》。第5部分(第3版),Addison-Wesley,2002 |
相关文章:

深入探讨C存储类和存储期——Storage Duration
🔗 《C语言趣味教程》👈 猛戳订阅!!! —— 热门专栏《维生素C语言》的重制版 —— 💭 写在前面:这是一套 C 语言趣味教学专栏,目前正在火热连载中,欢迎猛戳订阅&#…...

医学图像融合的深度学习方法综述
文章目录 Deep learning methods for medical image fusion: A review摘要引言非端到端的融合方法基于深度学习的决策映射基于深度学习的特征提取 端到端图像融合方法基于卷积神经网络(CNN)的图像融合方法单级特征融合方法多级特征融合基于残差神经网络的图像融合方法基于密集神…...
【Qt学习】04:QDialog
QDialog OVERVIEW QDialog一、自定义对话框1.模态对话框2.非模态对话框3.练习代码 二、标准对话框1.消息对话框2.文件对话框3.颜色对话框4.字体对话框 对话框是 GUI 程序中不可或缺的组成部分,对话框通常会是一个顶层窗口出现在程序最上层,用于实现短期任…...
如何更好的进行异常处理
背景 在实际开发中,我们都希望程序可以一直按照期望的流程,无误的走下去。但是由于不可避免的内外部因素,可能导致出现异常的情况,轻则导致报错,重则数据错乱、服务不可用等情况。严重影响系统的稳定性,甚至…...

若依微服务版部署到IDEA
1.进入若依官网,找到我们要下的微服务版框架 2.点击进入gitee,获取源码,下载到本地 3.下载到本地后,用Idea打开,点击若依官网,找到在线文档,找到微服务版本的,当然你不看文档,直接按…...

Elasticsearch 入门安装
1.Elasticsearch 是什么 The Elastic Stack, 包括 Elasticsearch、 Kibana、 Beats 和 Logstash(也称为 ELK Stack)。能够安全可靠地获取任何来源、任何格式的数据,然后实时地对数据进行搜索、分析和可视化。 Elaticsearch,简称为…...

【80天学习完《深入理解计算机系统》】第十一天 3.5 过程(函数调用)
专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录) 文章字体风格: 红色文字表示&#…...
LinuxUbuntu安装VMware tools Segmentation fault (core dumped)怎么解决
LinuxUbuntu安装VMware tools Segmentation fault (core dumped)怎么解决 在安装VMware Tools时遇到"Segmentation fault (core dumped)"错误,通常是由于兼容性问题或系统配置不正确导致的。以下是一些可能的解决方法: 检查VMware Tools兼容性…...

002微信小程序云开发API数据库-迁移状态查询/更新索引
文章目录 微信小程序云开发API数据库-迁移状态查询案例代码微信小程序云开发API数据库-更新索引案例代码 微信小程序云开发API数据库-迁移状态查询 在微信小程序中,云开发API数据库是一种方便快捷的数据库解决方案。但是,有时候我们可能需要将云开发数据…...

十几款拿来就能用的炫酷表白代码
「作者主页」:士别三日wyx 「作者简介」:CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」:小白零基础《Python入门到精通》 表白代码 1、坐我女朋友好吗,不同意就关机.vbs2、坐我女朋友好吗&…...

证券低延时环境设置并进行性能测试
BIOS设置BIOS参考信息 关闭 logical Process Virtualization Technology 在System Profiles Settings 中System Profile 选择Performance Workload Profile 选择HPC Profile OS中信息参考在/etc/default/grub文件中添加 intel_idle.max_cstate=0 processor.max_cstate=0 idle=p…...

百度工程师浅析解码策略
作者 | Jane 导读 生成式模型的解码方法主要有2类:确定性方法(如贪心搜索和波束搜索)和随机方法。确定性方法生成的文本通常会不够自然,可能存在重复或过于简单的表达。而随机方法在解码过程中引入了随机性,以便生成更…...
windows下实现查看软件请求ip地址的方法
一、关于wmic和nestat wmic是Windows Management Instrumentation的缩写,是一款非常常用的用于Windows系统管理的命令行实用程序。wmic可以通过命令行操作,获取系统信息、安装软件、启动服务、管理进程等操作。 netstat命令是一个监控TCP/IP网络的非常有…...

【JAVA】String 类
⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈Java 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 String 1. 字符串构造2. String对象的比…...

LoRA继任者ReLoRA登场,通过叠加多个低秩更新矩阵实现更高效大模型训练效果
论文链接: https://arxiv.org/abs/2307.05695 代码仓库: https://github.com/guitaricet/peft_pretraining 一段时间以来,大模型(LLMs)社区的研究人员开始关注于如何降低训练、微调和推理LLMs所需要的庞大算力…...

Elasticsearch 8.X reindex 源码剖析及提速指南
1、reindex 源码在线地址 为方便大家验证,这里给出 reindex github 源码地址。 https://github.com/elastic/elasticsearch/blob/001fcfb931454d760dbccff9f4d1b8d113f8708c/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java reindex 常见…...

前端组件库造轮子——Input组件开发教程
前端组件库造轮子——Input组件开发教程 前言 本系列旨在记录前端组件库开发经验,我们的组件库项目目前已在Github开源,下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。 文章旨在总结经验,开源…...
Day04-Vue基础-监听器-双向绑定-组件通信
Day04-Vue基础-监听器-双向绑定-组件通信 一 侦听器 语法一 <template><div>{{name}}<br><button @click="update1">修改1</button><...

Java小白基础自学阶段(持续更新...)
引言 Java作为一门广泛应用于企业级开发的编程语言,对初学者来说可能会感到有些复杂。然而,通过适当的学习方法和资源,即使是小白也可以轻松掌握Java的基础知识。本文将提供一些有用的建议和资源,帮助小白自学Java基础。 学习步骤…...
Vue自定义指令- v-loading封装
Vue自定义指令- v-loading封装 文章目录 Vue自定义指令- v-loading封装01-自定义指令自定义指令的两种注册语法: 02自定义指令的值03-自定义指令- v-loading指令封装 01-自定义指令 什么是自定义指令? 自定义指令:自己定义的指令,…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...