深入探讨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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/107938.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux CentOS安装抓包解包工具Wireshark图形化界面

1.Wireshark介绍 Wireshark 是一个开源的网络协议分析工具&#xff0c;它能够捕获和分析网络数据包&#xff0c;提供深入的网络故障排除、网络性能优化和安全审计等功能。它支持跨多个操作系统&#xff0c;包括 Windows、macOS 和 Linux。 2.Wireshark主要使用方法 捕获数据…

智能井盖传感器,物联网智能井盖系统

随着城市人口的不断增加和城市化进程的不断推进&#xff0c;城市基础设施的安全和可靠性变得愈发重要&#xff0c;城市窨井盖作为城市基础设施重要组成部分之一&#xff0c;其安全性事关城市安全有序运行和居民生产生活安全保障。 近年来&#xff0c;各地都在加强城市窨井盖治理…

el-backtop返回顶部的使用

2023.8.26今天我学习了如何使用el-backtop组件进行返回页面顶部的效果&#xff0c;效果如&#xff1a; <el-backtop class"el-backtop"style"right: 20px; bottom: 150px;"><i class"el-icon-caret-top"></i></el-backtop&…

16、Flink 的table api与sql之连接外部系统: 读写外部系统的连接器和格式以及JDBC示例(4)

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

跳跃游戏【贪心算法】

跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。在这里插入图片…

【Linux】多线程概念线程控制

文章目录 多线程概念Linux下进程和线程的关系pid本质上是轻量级进程id&#xff0c;换句话说&#xff0c;就是线程IDLinux内核是如何创建一个线程的线程的共享和独有线程的优缺点 线程控制POSIX线程库线程创建线程终止线程等待线程分离 多线程概念 Linux下进程和线程的关系 在…

MySql015——使用子查询

一、创建customers表 ######################## # Create customers table ######################## use study;CREATE TABLE customers (cust_id int NOT NULL AUTO_INCREMENT,cust_name char(50) NOT NULL ,cust_address char(50) NULL ,cust_city char…

9.oracle中sign函数

在Oracle/PLSQL中, sign 函数返回一个数字的正负标志. 语法如下&#xff1a;sign( number ) number 要测试标志的数字. If number < 0, then sign returns -1. If number 0, then sign returns 0. If number > 0, then sign returns 1. 应用于: Oracle 8i, Oracle …

Idea配置Remote Host

一、打开RemoteHost窗口 双击shift打开全局搜索 搜索Tools→Deployment→Browse Remote Host或 idea项目顶部Tools→Deployment→Browse Remote Host 二、添加服务 右侧边栏打开RemoteHost&#xff0c;点击三个点&#xff0c;起个名字&#xff0c;选择type为SFTP&#xff…

Jenkins工具系列 —— 配置邮箱 每个job下动态设置临时发送人

文章目录 安装插件添加邮箱认证邮箱申请&#xff08;以QQ邮箱网页为例&#xff09;jenkins添加邮箱认证 jenkins设置邮箱相关信息配置全局邮件单个JOB邮箱配置 安装插件 点击 左侧的 Manage Jenkins —> Plugins ——> 左侧的 Available plugins 添加邮箱认证 邮箱申请…

前端基础(ES6 模块化)

目录 前言 复习 ES6 模块化导出导入 解构赋值 导入js文件 export default 全局注册 局部注册 前言 前面学习了js&#xff0c;引入方式使用的是<script s"XXX.js">&#xff0c;今天来学习引入文件的其他方式&#xff0c;使用ES6 模块化编程&#xff0c;…

01、前端使用 thymeleaf 后,视图页面找不到---Cannot resolve MVC View ‘xxxxx前端页面‘

Cannot resolve MVC View ‘xxxxx前端页面’ 没有找到对应的mvc的前端页面。 代码&#xff1a;前端这里引入了 thymeleaf 模板 解决&#xff1a; 需要添加 thymeleaf 的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s…

智慧充电桩物联网方案架构

智慧充电桩物联网采用“云-管-边-端”的边缘计算物联网架构&#xff0c;融合5G、AI、Wi-Fi 6等技术&#xff0c;实现充电基础设施由数字化向智能化演进。智慧充电桩物联网方案架构设计&#xff0c;如下图所示&#xff1a; 云端&#xff1a; 物联网平台具备广泛协议的南向接入…

smartsofthelp 5.0 最专业的数据库优化工具,数据库配置优化,数据库高并发优化,SQL 语句优化...

下载地址:百度网盘 请输入提取码 SQL操作返回历史记录&#xff1a; 2023-08-21 20:42:08:220 输入&#xff1a;select version as 版本号 2023-08-21 20:42:08:223 输出&#xff1a;当前数据库实例版本号&#xff1a;Microsoft SQL Server 2012 - 11.0.2100.60 (X64) …

2023年 Java 面试八股文(25w字)

0.Java八股文上&#xff08;25w字&#xff09;2.3w 1.集合容器 2.Java基础链接 目录 一.Java 基础面试题1.Java概述Java语言有哪些特点&#xff1f;Java和C有什么关系&#xff0c;它们有什么区别&#xff1f;JVM、JRE和JDK的关系是什么&#xff1f;**什么是字节码?**采用字…

使用Pillow对图像进行变换

使用Pillow对图像进行变换 from PIL import Image, ImageEnhance# 原图 image Image.open("1.jpg") image.show()# 镜像 mirrored_image image.transpose(Image.FLIP_LEFT_RIGHT) mirrored_image.show() mirrored_image.save(mirror_image.jpg)# 旋转 rotated_imag…

【PHP面试题82】system和exec是用来做什么的?有什么区别

文章目录 &#x1f680;一、前言&#xff0c;PHP中system和exec命令的作用&#x1f680;二、system()函数&#x1f680;三、exec()函数&#x1f680;四、区别和应用场景&#x1f50e;4.1 使用system()函数的应用场景&#x1f50e;4.2 使用exec()函数的应用场景&#x1f50e;4.3…

几个nlp的小任务(生成任务(摘要生成))

几个nlp的小任务生成任务——摘要生成 安装库选择模型加载数据集展示数据集数据预处理 tokenizer注意特殊的 token处理组成预处理函数调用map,对数据集进行预处理微调模型,设置参数设置数据收集器,将处理好的数据喂给模型封装测评方法将参数传给 trainer,开始训练安装库 选…

RS485保护电路

今天给大家分享485接口的EMC设计&#xff0c;希望对电路设计&#xff0c;及相关软件开发的人员有帮助。 一、原理图 1. RS485接口6KV防雷电路设计方案 &#xff08;RS485接口防雷电路&#xff09; 接口电路设计概述&#xff1a; RS485用于设备与计算机或其它设备之间通讯&…

【AI底层逻辑】——篇章7(下):计算资源软件代码共享

续上篇... 目录 续上篇... 三、计算资源 1、第一阶段&#xff1a;数据大集中 2、第二阶段&#xff1a;资源云化 ①“云”的分类 ②虚拟化技术 ③边缘计算的普及 四、软件代码共享 总结 往期精彩&#xff1a; 三、计算资源 AlphaGo算法论文虽然已经发表&#xff0c;但…