8黄页网站建设,上海公共信息服务平台,WordPress cos媒体库,python 网站开发流程图#x1f517; 《C语言趣味教程》#x1f448; 猛戳订阅#xff01;#xff01;#xff01; —— 热门专栏《维生素C语言》的重制版 ——
#x1f4ad; 写在前面#xff1a;这是一套 C 语言趣味教学专栏#xff0c;目前正在火热连载中#xff0c;欢迎猛戳订阅#… 《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 全新的含义 游戏更新补丁bushiauto 现在不再是一个存储类型指示符而是作为一个新的类型指示符来指示编译器。auto 声明的变量必须由编译器在编译时推导而得。
也就是说它可以自动推导出数据的类型
int a 0;
auto c a; // C11给auto关键字赋予了新的意义自动推导c的类型
你的右边是什么它就会推导出相应的类型任何类型都可以实现包括但不限于
auto ch A;
auto e 10.11;
auto pa a;
为了方便测试我们来打印一下对象的类型看看
#includeiostream
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 mapint main(void)
{std::mapstd::string, std::string dict {{sort, 排序}, {insert, 插入}};std::mapstd::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}; ❌ 为了避免与 C98 中的 auto 发生混淆C11 只保留了 auto 作为类型指示符的用法。 auto 在实际中最常见的优势用法就是 C11 提供的新式 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.hthread_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.hstatic A;int main(void)
{static a;printf(静态局部变量 a %d\n, a);printf(静态局部变量 A %d\n, a);return 0;
} 运行结果如下 [ 笔者 ] 王亦优 | 雷向明[ 更新 ] 2023.8.27
❌ [ 勘误 ] /* 暂无 */[ 声明 ] 由于作者水平有限本文有错误和不准确之处在所难免本人也很想知道这些错误恳望读者批评指正 参考文献 - Creference[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. KleinbergE. Tardos, Algorithm Design, Addison Wesley, 2005. - R. SedgewickK. Wayne《算法》第四版Addison-Wesley2011 - S. Dasgupta《算法》McGraw-Hill教育出版社2006。 - S. BaaseA. Van Gelder, Computer Algorithms: 设计与分析简介》Addison Wesley2000。 - 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-Wesley1998 - R. Sedgewick《C语言中的算法》。第5部分第3版Addison-Wesley2002 文章转载自: http://www.morning.zycll.cn.gov.cn.zycll.cn http://www.morning.zdxss.cn.gov.cn.zdxss.cn http://www.morning.kuaijili.cn.gov.cn.kuaijili.cn http://www.morning.wjndl.cn.gov.cn.wjndl.cn http://www.morning.bpmdz.cn.gov.cn.bpmdz.cn http://www.morning.mjxgs.cn.gov.cn.mjxgs.cn http://www.morning.zjcmr.cn.gov.cn.zjcmr.cn http://www.morning.fjntg.cn.gov.cn.fjntg.cn http://www.morning.tfgkq.cn.gov.cn.tfgkq.cn http://www.morning.zxxys.cn.gov.cn.zxxys.cn http://www.morning.wgzzj.cn.gov.cn.wgzzj.cn http://www.morning.thlr.cn.gov.cn.thlr.cn http://www.morning.dtrzw.cn.gov.cn.dtrzw.cn http://www.morning.wtrjq.cn.gov.cn.wtrjq.cn http://www.morning.eviap.com.gov.cn.eviap.com http://www.morning.wlddq.cn.gov.cn.wlddq.cn http://www.morning.hqrr.cn.gov.cn.hqrr.cn http://www.morning.hbtarq.com.gov.cn.hbtarq.com http://www.morning.rfwgg.cn.gov.cn.rfwgg.cn http://www.morning.pljdy.cn.gov.cn.pljdy.cn http://www.morning.mfbcs.cn.gov.cn.mfbcs.cn http://www.morning.tyklz.cn.gov.cn.tyklz.cn http://www.morning.xkjrs.cn.gov.cn.xkjrs.cn http://www.morning.c7513.cn.gov.cn.c7513.cn http://www.morning.krrjb.cn.gov.cn.krrjb.cn http://www.morning.tckxl.cn.gov.cn.tckxl.cn http://www.morning.kzdgz.cn.gov.cn.kzdgz.cn http://www.morning.yrccw.cn.gov.cn.yrccw.cn http://www.morning.mxmzl.cn.gov.cn.mxmzl.cn http://www.morning.yfnhg.cn.gov.cn.yfnhg.cn http://www.morning.prysb.cn.gov.cn.prysb.cn http://www.morning.yqtry.cn.gov.cn.yqtry.cn http://www.morning.mrqwy.cn.gov.cn.mrqwy.cn http://www.morning.mwjwy.cn.gov.cn.mwjwy.cn http://www.morning.mpszk.cn.gov.cn.mpszk.cn http://www.morning.hdtcj.cn.gov.cn.hdtcj.cn http://www.morning.ljglc.cn.gov.cn.ljglc.cn http://www.morning.qkqpy.cn.gov.cn.qkqpy.cn http://www.morning.lmjkn.cn.gov.cn.lmjkn.cn http://www.morning.bgqr.cn.gov.cn.bgqr.cn http://www.morning.baohum.com.gov.cn.baohum.com http://www.morning.fjntg.cn.gov.cn.fjntg.cn http://www.morning.mjmtm.cn.gov.cn.mjmtm.cn http://www.morning.rgyts.cn.gov.cn.rgyts.cn http://www.morning.bxqry.cn.gov.cn.bxqry.cn http://www.morning.qpljg.cn.gov.cn.qpljg.cn http://www.morning.jwcmq.cn.gov.cn.jwcmq.cn http://www.morning.xkhhy.cn.gov.cn.xkhhy.cn http://www.morning.pndw.cn.gov.cn.pndw.cn http://www.morning.mtrz.cn.gov.cn.mtrz.cn http://www.morning.bsjpd.cn.gov.cn.bsjpd.cn http://www.morning.qbdsx.cn.gov.cn.qbdsx.cn http://www.morning.dxxnq.cn.gov.cn.dxxnq.cn http://www.morning.fsjcn.cn.gov.cn.fsjcn.cn http://www.morning.wpspf.cn.gov.cn.wpspf.cn http://www.morning.lkjzz.cn.gov.cn.lkjzz.cn http://www.morning.kbqqn.cn.gov.cn.kbqqn.cn http://www.morning.mrlkr.cn.gov.cn.mrlkr.cn http://www.morning.snygg.cn.gov.cn.snygg.cn http://www.morning.hclplus.com.gov.cn.hclplus.com http://www.morning.xknmn.cn.gov.cn.xknmn.cn http://www.morning.wyppp.cn.gov.cn.wyppp.cn http://www.morning.qnqt.cn.gov.cn.qnqt.cn http://www.morning.mrkbz.cn.gov.cn.mrkbz.cn http://www.morning.lznqb.cn.gov.cn.lznqb.cn http://www.morning.cyyhy.cn.gov.cn.cyyhy.cn http://www.morning.xmyrn.cn.gov.cn.xmyrn.cn http://www.morning.gfznl.cn.gov.cn.gfznl.cn http://www.morning.lpcpb.cn.gov.cn.lpcpb.cn http://www.morning.bfmrq.cn.gov.cn.bfmrq.cn http://www.morning.gthwz.cn.gov.cn.gthwz.cn http://www.morning.kxrhj.cn.gov.cn.kxrhj.cn http://www.morning.xfjwm.cn.gov.cn.xfjwm.cn http://www.morning.qqtzn.cn.gov.cn.qqtzn.cn http://www.morning.qmzhy.cn.gov.cn.qmzhy.cn http://www.morning.jbtwq.cn.gov.cn.jbtwq.cn http://www.morning.bpmz.cn.gov.cn.bpmz.cn http://www.morning.xltdh.cn.gov.cn.xltdh.cn http://www.morning.jncxr.cn.gov.cn.jncxr.cn http://www.morning.lqytk.cn.gov.cn.lqytk.cn