C现代方法(第21章)笔记——标准库

文章目录

  • 第21章 标准库
    • 21.1 标准库的使用
      • 21.1.1 对标准库中所用名字的限制
      • 21.1.2 使用宏隐藏的函数
    • 21.2 C89标准库概述
    • 21.3 C99标准库更新
    • 21.4 <stddef.h>:常用定义
    • 21.5 <stdbool.h>:布尔类型和值(C99)
    • 21.6 C11标准更新(C1X)
    • 21.7 <stdalign.h>:地址的对齐(C1X)
    • 21.8 <stdnoreturn.h>:宏noreturn的定义(C1X)
    • 问与答
    • 写在最后

第21章 标准库

——每个程序都可以是其他程序的一部分,但很少是正合适的

前面几章中零散地介绍了一些C语言标准库的相关知识。本章将完整地讨论标准库。21.1节列举使用库的一些通用的指导原则,并介绍了会在一些库的头中发现的技巧:使用宏来“隐藏”函数21.2节会对C89库的每个头分别做概述性介绍,21.3节会对C99库的新头做概述性介绍,21.4节会对C11库的新头做概括性介绍。

随后几章将深入讨论标准库的头,并将相关联的头放在一起讨论。其中<stddef.h><stdbool.h><stdalign.h><stdnoreturn.h>非常简短,所以会在本章中加以讨论(分别在21.5节21.6节21.7节21.8节)。


21.1 标准库的使用

C89标准库总共划分成15个部分,每个部分用一个头描述。C99新增了9个头,C11新增了5个头,总共有29个:

  1. <assert.h>
  2. <ctype.h>
  3. <errno.h>
  4. <float.h>
  5. <limits.h>
  6. <locale.h>
  7. <math.h>
  8. <setjmp.h>
  9. <signal.h>
  10. <stdarg.h>
  11. <stddef.h>
  12. <stdio.h>
  13. <stdlib.h>
  14. <string.h>
  15. <time.h>

C99开始引入(9个):

  1. <complex.h>
  2. <fenv.h>
  3. <inttypes.h>
  4. <iso646.h>
  5. <stdbool.h>
  6. <stdint.h>
  7. <tgmath.h>
  8. <wchar.h>
  9. <wctype.h>

C11开始引入(5个):

  1. <stdalign.h>
  2. <stdatomic.h>
  3. <stdnoreturn.h>
  4. <threads.h>
  5. <uchar.h>

大多数编译器会使用更大的库,其中包含很多上述列表中没有的头额外添加的头当然不属于标准库的范畴,因此不能假设其他的编译器也支持这些头。这类头通常提供一些针对特定机型或特定操作系统的函数(这也解释了为什么它们不属于标准库),它们可能会提供允许对屏幕或键盘做更多控制的函数。用于支持图形或窗口界面的头也是很常见的。

标准头主要由函数原型、类型定义以及宏定义组成。如果我们的文件中调用了头中声明的函数,或是使用了头中定义的类型或宏,就需要在文件开头将相应的头包含进来。当一个文件包含多个标准头时,#include指令的顺序无关紧要。多次包含同一个标准头也是合法的


21.1.1 对标准库中所用名字的限制

任何包含了标准头的文件都必须遵守2条规则。

  • 第一,该文件不能将头中定义过的宏的名字用于其他目的。例如,如果某个文件包含了<stdio.h>,就不能重新定义NULL了,因为使用这个名字的宏已经在<stdio.h>中定义过了。
  • 第二,具有文件作用域的库名(尤其是typedef名)也不可以在文件层次重定义。因此,一旦文件包含了<stdio.h>,由于<stdio.h>中已经将size_t定义为typedef名,在文件作用域内都不能将size_t重定义为任何标识符。

上述这些限制是显而易见的,但C语言还有一些其他的限制,可能是你想不到的:

  • 由一个下划线和一个大写字母开头或由两个下划线开头的标识符是为标准库保留的标识符。程序不允许为任何目的使用这种形式的标识符。
  • 由一个下划线开头的标识符被保留用作具有文件作用域的标识符和标记。除非在函数内部声明,否则不应该使用这类标识符。
  • 在标准库中所有具有外部链接的标识符被保留用作具有外部链接的标识符。特别是所有标准库函数的名字都被保留。因此,即使文件没有包含<stdio.h>,也不应该定义名为printf的外部函数,因为在标准库中已经有一个同名的函数了。

这些规则对程序的所有文件都起作用,不论文件包含了哪个头都是如此。虽然这些规则并不总是强制性的,但不遵守这些规则可能会导致程序不具有可移植性

上面列出的规则不仅适用于库中现有的名字,也适用于留作未来使用的名字。至于哪些名字是保留的,完整的描述太冗长了,你可以在C标准的“future library directions”中找到。例如,C保留了以str和一个小写字母开头的标识符,使得具有这类名字的函数可以被添加到<string.h>头中。


21.1.2 使用宏隐藏的函数

C程序员经常会用带参数的宏来替代小的函数,这在标准库中同样很常见C标准允许在头中定义与库函数同名的宏,为了起到保护作用,还要求有实际的函数存在。因此,对于库的头,声明一个函数并同时定义一个有相同名字的宏的情况并不少见。

我们已经见过宏与库函数同名的例子。getchar是声明在<stdio.h>中的库函数,具有如下原型:

int getchar(void);

<stdio.h>通常也把getchar定义为一个宏:

#define getchar() getc(stdin) 

在默认情况下,对getchar的调用会被看作宏调用(因为宏名会在预处理时被替换)。

在大多数情况下,我们喜欢使用宏来替代实际的函数,因为这样可能会提高程序的运行速度。然而在某些情况下,我们需要一个真实的函数,可能是为了尽量缩小可执行代码的大小。

如果确实存在这种需求,可以使用#undef指令(14.3节)来删除宏定义。例如,可以在包含<stdio.h>后删除宏getchar的定义:

#include <stdio.h> 
#undef getchar

即使getchar不是宏,这样的做法也不会带来任何坏处,因为当给定的名字没有被定义成宏时,#undef指令不会起任何作用

此外,也可以通过给名字加圆括号来禁用个别宏调用:

ch = (getchar)(); /* instead of ch = getchar(); */ 

预处理器无法分辨出带参数的宏,除非宏名后跟着一个左圆括号。编译器则不会这么容易被欺骗,它仍可以将getchar识别为函数。


21.2 C89标准库概述

现在简单讨论一下C89标准库中的头。本节可以作为一张“路线图”,帮助你分辨出需要的是C标准库的哪一部分。本章及后续各章节会对每个头做更详细的介绍:

  1. <assert.h>诊断(断言)

    <assert.h>头(24.1节)仅包含assert宏,它允许我们在程序中插入自我检查。一旦任何检查失败,程序就会被终止。

  2. <ctype.h>字符处理

    <ctype.h>头(23.5节)提供用于字符分类及大小写转换的函数。

  3. <errno.h>错误

    <errno.h>头(24.2节)提供了errno(“error number”)errno是一个左值(lvalue),可以在调用特定库函数后进行检测,从而判断调用过程中是否有错误发生。

  4. <float.h>浮点类型的特性

    <float.h>头(23.1节)提供了用于描述浮点类型特性的宏,包括值的范围及精度。

  5. <limits.h>整数类型的大小

    <limits.h>头(23.2节)提供了用于描述整数类型(包括字符类型)特性的宏,包括它们的最大值和最小值。

  6. <locale.h>本地化

    <locale.h>头(25.1节)提供一些函数来帮助程序适应针对某个国家或地区的特定行为方式。这些与本地化相关的行为包括显示数的方式(如用作小数点的字符)、货币的格式(如货币符号)、字符集以及日期和时间的表示形式。

  7. <math.h>数学计算

    <math.h>头(23.3节)提供了常见的数学函数,包括三角函数、双曲函数、指数函数、对数函数、幂函数、邻近舍入函数、绝对值运算函数以及取余函数。

  8. <setjmp.h>非本地跳转

    <setjmp.h>头(24.4节)提供了setjmp函数和longjmp函数。setjmp函数会“标记”程序中的一个位置,随后可以用longjmp返回被标记的位置。这些函数可以用来从一个函数跳转到另一个(仍然在活动中的)函数中,而绕过正常的函数返回机制。setjmp函数和longjmp函数主要用来处理程序执行过程中出现的严重问题。

  9. <signal.h>信号处理

    <signal.h>头(24.3节)提供了用于处理异常情况(信号)的函数,包括中断和运行时错误。signal函数可以设置一个函数,使系统会在给定信号发生后自动调用该函数;raise函数用来产生信号。

  10. <stdarg.h>可变参数

    <stdarg.h>头(26.1节)提供了一些工具用于编写参数个数可变的函数,就像printfscanf函数一样。

  11. <stddef.h>常用定义

    <stddef.h>头(21.4节)提供了经常使用的类型和宏的定义。

  12. <stdio.h>输入/输出

    <stdio.h>头(22.1节~22.8节)提供了大量的输入/输出函数,包括对顺序访问和随机访问文件的操作。

  13. <stdlib.h>常用实用程序

    <stdlib.h>头(26.2节)包含了大量无法归入其他头的函数。包含在<stdlib.h>中的函数可以将字符串转换成数、产生伪随机数、执行内存管理任务、与操作系统通信、执行搜索与排序,以及在多字节字符与宽字符之间进行转换。

  14. <string.h>字符串处理

    <string.h>头(23.6节)提供了用于进行字符串操作(包括复制、拼接、比较及搜索)的函数以及对任意内存块进行操作的函数。

  15. <time.h>日期和时间

    <time.h>头(26.3节)提供相应的函数来获取时间(和日期)、操纵时间,以及格式化时间的显示。


21.3 C99标准库更新

C99对标准库的改变主要分为以下三类:

  • 新增头。在C99标准库中有9个头是C89中没有的。事实上其中3个(<iso646.h><wchar.h><wctype.h>) 在1995年修订C89时就增加到C中,另外6个(<complex.h><fenv.h><inttypes.h><stdbool.h><stdint.h><tgmath.h>)是C99新增的。
  • 新增宏和函数C99标准在一些已有的头中增加了宏和函数,这些头主要有<float.h><math.h><stdio.h><math.h>头中增加了非常多的内容,将专门用一节(即23.4节)来讲述。
  • 对已有函数的改进。一些已存在的函数(包括printfscanf)在C99中具有了更多的功能。

接下来快速浏览一下C99标准库中新增的9个头,就像在21.2节中浏览C89库中的头一样:

  1. <complex.h>复数算术

    <complex.h>头(27.4节)定义了complexI宏,这两个宏对于复数运算来说非常有用。该头还提供了对复数进行数学运算的函数。

  2. <fenv.h>浮点环境

    <fenv.h>头(27.6节)提供了对浮点状态标志和控制模式的访问。例如,程序可以测试标志来判断浮点数运算过程中是否发生了溢出,或者设置控制模式来指定如何进行舍入。

  3. <inttypes.h>整数类型格式转换

    <inttypes.h>头(27.2节)定义了可用于<stdint.h>中声明的整数类型输入/输出的格式化字符串的宏,还提供了处理最大宽度整数的函数。

  4. <iso646.h>拼写转换

    <iso646.h>头(25.3节)定义了可代表特定运算符(包含字符&|~!^的运算符)的宏。当编程环境的本地字符集没有这些字符时,这些宏非常有用。

  5. <stdbool.h>布尔类型和值

    <stdbool.h>头(21.5节)定义了booltruefalse宏,同时还定义了一个可以用于测试这些宏是否已被定义的宏。

  6. <stdint.h>整数类型

    <stdint.h>头(27.1节)声明了指定宽度的整数类型,并定义了相关的宏(例如指定每种类型的最大值和最小值的宏),同时也定义了用于构建具体类型的整型常量的带参数的宏。

  7. <tgmath.h>泛型数学

    C99中,<math.h><complex.h>头中的许多数学函数有多个版本。<tgmath.h>头(27.5节)中的泛型宏可以检测传递给它们的参数类型,并替代为相应的<math.h><complex.h>中函数的调用。

  8. <wchar.h>扩展的多字节和宽字符实用工具

    <wchar.h>头(25.5节)提供了宽字符输入/输出和宽字符串操作的函数。

  9. <wctype.h>宽字符分类和映射实用工具

    <wctype.h>头(25.6节)<ctype.h>的宽字符版本,提供了对宽字符进行分类和修改的函数。


21.4 <stddef.h>:常用定义

<stddef.h>头提供了常用类型和宏的定义,但没有声明任何函数。定义的类型包括以下几个:

  • ptrdiff_t。指针相减运算结果的类型。
  • size_tsizeof运算符返回的类型。
  • wchar_t。一种足够大的、可以用于表示所有支持的地区的所有字符的类型。

以上这3种类型都是整数类型。其中ptrdiff_t必须是有符号类型,size_t必须是无符号类型。关于wchar_t的更多细节见25.2节

<stddef.h>头中还定义了两个宏。一个宏是NULL,用来表示空指针。另一个宏是offsetof,需要两个参数:类型(一种结构类型)和成员指示符(结构的一个成员)。offsetof宏会计算结构的起点到指定成员间的字节数

考虑下面的结构:

struct s { char a; int b[2]; float c; 
}; 

offsetof(struct s, a)的值一定是0C语言确保结构的第一个成员的地址与结构自身地址相同。我们无法确定地说出bc的偏移量是多少。一种可能是offsetof(struct s, b)1(因为a的长度是1字节),而offsetof(struct s, c)9(假设整数是32位)。然而,一些编译器会在结构中留下一些空洞(不使用的字节,见第16章“问与答”部分),从而会影响到offsetof产生的值。例如,如果编译器在a后面留下了3字节的空洞,那么bc的偏移量分别是412。但这正是offsetof宏的魅力所在:对任意编译器,它都能返回正确的偏移量,从而使我们可以编写可移植的程序。

offsetof有很多用途。例如,假如我们需要将结构s的前两个成员写入文件,但忽略成员c。我们不使用fwrite函数(22.6节)来写sizeof(struct s)字节,因为这样会将整个结构写入。我们只需要写offsetof(struct s, c)字节。

最后一点:一些在<stddef.h>中定义的类型和宏在其他头中也会出现。(例如,NULL宏不仅在C99的头<wchar.h>中有定义,在<locale.h><stdio.h><stdlib.h><string.h><time.h>中也有定义。)因此,只有少数程序的确需要包含<stddef.h>


21.5 <stdbool.h>:布尔类型和值(C99)

<stdbool.h>头定义了4个宏:

  • bool(定义为_Bool);
  • true(定义为1);
  • false(定义为0);
  • __bool_true_false_are_defined(定义为1)。

我们已经见过很多使用booltruefalse的例子。对__bool_true_false_are_defined宏的应用相对少一些。在尝试定义自己的booltruefalse之前,可以使用预处理指令(如#if或者#ifdef)来测试这个宏。


21.6 C11标准更新(C1X)

C11开始对标准库的改变主要体现在以下几个方面:

  • 新增头。在C11标准库中有5个头是之前没有的,它们分别是<stdatomic.h><threads.h><stdalign.h>、<uchar.h><stdnoreturn.h>
  • 新增宏和函数C11标准在一些已有的头中增加了宏和函数,这些头主要有<float.h><complex.h><time.h>等。
  • 对已有函数的改进和移除。一些已存在的函数(包括printfscanf)在C11中具有了更多的功能。同时,出于对安全性的考虑,从头<stdio.h>中移除了gets函数,并将它从新标准中废除。

接下来我们快速浏览一下C11标准库中新增的5个头:

  1. <stdatomic.h>原子类型和原子操作

    <stdatomic.h>头定义了现有数据类型的原子类型,并提供了大量的宏用于执行原子类型变量的初始化和读写操作。

  2. <threads.h>多线程环境

    <threads.h>头提供了线程的创建和管理函数,以及互斥锁、条件变量和线程局部存储的功能。

  3. <stdalign.h>数据对齐

    <stdalign.h>头提供了4个宏定义(21.7节)。

  4. <uchar.h>新的宽字符类型和实用工具

    <uchar.h>头定义了新的宽字符类型char16_tchar32_t,并提供了从多字节字符到这些宽字符类型的转换函数。

  5. <stdnoreturn.h>函数指定符_Noreturn相关

    <stdnoreturn.h>头非常简单,只定义了一个宏noreturn(21.8节)


21.7 <stdalign.h>:地址的对齐(C1X)

<stdalign.h>头定义了4个宏:

  • alignas(定义为_Alignas);
  • alignof(定义为_Alignof);
  • __alignas_is_defined(定义为整型常量1);
  • __alignof_is_defined(定义为整型常量1)。

以上的后两个宏适合在预处理指令#if中使用。如果已经定义了这两个宏,则说明另外两个宏alignasalignof也被定义(如果你想自行定义alignasalignof,应当先做这样的测试)


21.8 <stdnoreturn.h>:宏noreturn的定义(C1X)

<stdnoreturn.h>非常简单,它只是定义了宏noreturn(被定义为_Noreturn)。


问与答

问1:我注意到书中使用术语“标准头”,而不是“标准头文件”。不使用“文件”有什么具体原因吗?

答:是的。依据C标准,“标准头”不一定是文件。虽然大部分编译器确实将标准头以文件形式存储,但标准头实际上可以直接内置在编译器自身中

问214.3节描述了用带参数的宏替代函数的一些缺点。鉴于这些缺点,为标准库函数提供同名的宏版本不是很危险吗?

答:根据C标准,用于替代库函数的带参数的宏必须用圆括号“完全保护”起来,而且只能对参数进行一次求值。这些规则可以避免14.3节提到的大多数问题。


写在最后

本文是博主阅读《C语言程序设计:现代方法(第2版·修订版)》时所作笔记,日后会持续更新后续章节笔记。欢迎各位大佬阅读学习,如有疑问请及时联系指正,希望对各位有所帮助,Thank you very much!

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

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

相关文章

深入解析序列模型:全面阐释 RNN、LSTM 与 Seq2Seq 的秘密

探索序列建模的基础知识和应用。 简介 序列建模是许多领域的一个重要问题&#xff0c;包括自然语言处理 (NLP)、语音识别和语音合成、时间序列预测、音乐生成和「生物信息学」。所有这些任务的共同点是它们需要坚持。接下来的事情的预测是基于历史的。例如&#xff0c;在“哈桑…

Docker入门学习笔记

学习笔记网址推送&#xff1a;wDocker 10分钟快速入门_哔哩哔哩_bilibili docker是用来解决什么问题的&#xff1f; 例如当你在本地主机写了个web应用&#xff0c;而你打算将该应用发送给其他客户端进行案例测试和运行&#xff0c;若是传统做法&#xff0c;就比较复杂&#xf…

conda虚拟环境中安装的cuda和服务器上安装的cuda的异同

服务器上已安装Nvidia提供的cuda&#xff0c;nvcc -V时会出现已安装的CUDA版本。如下图所示&#xff0c;服务器上已安装好的cuda版本为10.1。 但是当我们在Anaconda虚拟环境下安装pytorch或者paddlepaddle等深度学习框架的GPU版本时&#xff0c;通常会选择较高版本的cuda&…

Git 简介及使用(1)

目录 一、在 Linux 环境中安装 Git 1. 先检查当前服务器中是否有 Git&#xff08;如果有显示如下图&#xff09; 2. 安装Git 3. 然后重复第一步&#xff1a;查看 Git 的版本信息即可 二、Git 的初始化及配置 1. 创建目录 2. 对仓库进行初始化 3. 新增两个配置项&#xff08…

理解Android线程基础与多线程编程模型

引言 在Android应用开发中&#xff0c;线程的合理使用对于保障应用的流畅性和性能至关重要。本文将带你深入了解Android线程的基础概念和多线程编程模型&#xff0c;同时将线程与进程进行比较&#xff0c;通过详细的解释和代码示例&#xff0c;使读者能够更全面地理解相关知识…

PyTorch神经网络-激励函数

在PyTorch 神经网络当中&#xff0c;使用激励函数处理非线性的问题&#xff0c;普通的神经网络出来的数据一般是线性的关系&#xff0c;但是遇到比较复杂的数据的话&#xff0c;需要激励函数处理一些比较难以处理的问题&#xff0c;非线性结果就是其中的情况之一。 FAQ:为什么要…

C# 32应用程序获取64位操作系统注册表

若C#的程序都是32位的&#xff0c;访问注册表的时候&#xff0c;会访问HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\&#xff0c; 而访问不到HKEY_LOCAL_MACHINE\SOFTWARE 适用版本&#xff1a;.NET 4.0及更高版本 public static Dictionary<string, string> GetInstalled…

【Java 进阶篇】Ajax 实现——JQuery 实现方式 `get` 与 `post`

嗨&#xff0c;亲爱的小白们&#xff01;欢迎来到这篇关于使用 jQuery 实现 Ajax 请求的博客。在前端开发中&#xff0c;Ajax 是一项非常重要的技术&#xff0c;它使我们能够在不刷新整个页面的情况下与服务器进行数据交互。而在 jQuery 中&#xff0c;get 和 post 方法提供了简…

vue之Error: Unknown option: .devServer.

背景 在使用内网穿透工具时&#xff0c;加入对应的配置&#xff0c;启动出现报错。 一、遇到的问题 报错&#xff1a; Error: Unknown option: .devServer. Check out https://babeljs.io/docs/en/babel-core/#options for more information about options. Error: Unknown …

全流量分析应用运行和访问情况

在当今数字化时代&#xff0c;应用程序的运行和访问情况对于企业和组织来说至关重要。无论是在线销售平台、移动应用还是企业内部系统&#xff0c;应用的性能和可用性直接影响着用户体验、业务流程以及组织效率。因此&#xff0c;对应用的运行和访问情况进行全面分析和评估&…

JZM-D30室温探针台技术参数

概况&#xff1a; JZM-D30室温探针台的诸多设计都是专用的&#xff0c;探针台的配置主要是根据用户的需求进行选配及设计。例如&#xff0c;要求的磁场型号&#xff0c;电源型号&#xff0c;磁场值&#xff0c;样品台的尺寸等&#xff0c;除此之外&#xff0c;该探针台和我司自…

Go 语言中的map和内存泄漏

map在内存中总是会增长&#xff1b;它不会收缩。因此&#xff0c;如果map导致了一些内存问题&#xff0c;你可以尝试不同的选项&#xff0c;比如强制 Go 重新创建map或使用指针。 在 Go 中使用map时&#xff0c;我们需要了解map增长和收缩的一些重要特性。让我们深入探讨这一点…

架构开发与优化咨询和实施服务

服务概述 得益于硬件平台算力的提升&#xff0c;汽车电子电气架构的集成度逐渐提高&#xff0c;从单体ECU、到功能域集成控制器、到区域集成控制器&#xff0c;多域融合成为了目前行业中软件工程的重要工作内容。同时&#xff0c;在传统控制器C代码开发的基础上&#xff0c;C、…

手把手从零开始训练YOLOv8改进项目(官方ultralytics版本)教程

手把手从零开始训练 YOLOv8 改进项目 (Ultralytics版本) 教程,改进 YOLOv8 算法 本文以Windows服务器为例:从零开始使用Windows训练 YOLOv8 算法项目 《芒果 YOLOv8 目标检测算法 改进》 适用于芒果专栏改进 YOLOv8 算法 文章目录 官方 YOLOv8 算法介绍改进网络代码汇总第…

CISP模拟试题(一)

免责声明 文章仅做经验分享用途,利用本文章所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担!!! 1.下面关于信息安全保障的说法错误的是:C A.信息安全保障的概念是与信息安全的概念同时产生的 …

ROS参数服务器(Param):通信模型、Hello World与拓展

参数服务器在ROS中主要用于实现不同节点之间的数据共享。 参数服务器相当于是独立于所有节点的一个公共容器&#xff0c;可以将数据存储在该容器中&#xff0c;被不同的节点调用&#xff0c;当然不同的节点也可以往其中存储数据。 使用场景一般存储一些机器人的固有参数&…

20、动态路由_下滑线为前缀的目录

创建文件 pages_question\index.vue pages_question\detail.vue 生成的对应路由&#xff1a; const _6bf6ece8 () > interopDefault(import(..\\pages\\_question\\index.vue /* webpackChunkName: "pages/_question/index" */)) const _a98c80aa () > in…

AIGC 技术在淘淘秀场景的探索与实践

本文介绍了AIGC相关领域的爆发式增长&#xff0c;并探讨了淘宝秀秀(AI买家秀)的设计思路和技术方案。文章涵盖了图像生成、仿真形象生成和换背景方案&#xff0c;以及模型流程串联等关键技术。 文章还介绍了淘淘秀的使用流程和遇到的问题及处理方法。最后&#xff0c;文章展望…

安全项目简介

安全项目 基线检查 密码 复杂度有效期 用户访问和身份验证 禁用administrator禁用guest认证失败锁定 安全防护软件操作系统安全配置 关闭自动播放 文件和目录权限端口限制安全审计… 等保测评 是否举办了安全意识培训是否有应急响应预案有无第一负责人 工作内容 测评准备…

Python实现精确控制asyncio并发过程中的多个任务(1)

前言 本文是该专栏的第37篇,后面会持续分享python的各种干货知识,值得关注。 asyncio是Python中并发编程的一种实现方式,它是Python3.4版本引入的标准库,直接内置了对异步IO的支持。异步,就是多个任务之间执行没有先后顺序,可以同时运行,执行的先后顺序不会有什么影响,…