存储类别、链接和内存管理(二)

简介: 存储类别、链接和内存管理

上期我们介绍了作用域、链接和存储期。这期我们继续介绍。

一、自动变量

   自动存储类别的变量具有自动存储期、块作用域且无链接。默认情况下,声明在块或函数头中的任何变量都属于自动存储类别。使用auto作为存储类别说明符。

再复习一下:

无链接意味着这些变量属于定义它们的块、函数或原型私有。

二、寄存器变量

在函数头中使用关键字register,便可请求寄存器变量。

它们都是块作用域、无链接和自动存储期。通常变量储存在内存中,寄存器变量储存在CPU的寄存器中,换句话说,储存在最快的可用内存中。与普通变量相比,访问这些变量的速度更快

三、块作用域的静态变量

静态变量(static variable)听起来自相矛盾,像是一个不可变的变量。实际上,静态的意思是该变量在内存中原地不动,并不是说它的值不变。具有文件作用域的变量自动具有(也必须是)静态存储期。前面提到过,可以创建具有静态存储期、块作用域的局部变量。这些变量和自动变量一样,具有相同的作用域,但是程序离开它们所在的函数后,这些变量不会消失。也就是说,这种变量具有块作用域、无链接,但是具有静态存储期。计算机在多次函数调用之间会记录它们的值。在块中(提供块作用域和无链接)以存储类别说明符static(提供静态存储期)声明这种变量。来看下面例子:

3 int test (void)4 {
5 static int i = 1. 
6 i=i+1:  
>
return i;
8}9
10 int test1 (void)11 {
12  int j = 1;  
13  j=i+1:  
14  return i; 
15} 
16 int main (void)17 {
18  int a,b;  
19  a=test(); 
20  printf("a = *d\n",a); 
21  a=test(); 
22  printf("a =ad\n",a);  
23  a =test();  
24  printf("a = *d\n",a); 
25
26  b =test1(); 
27  printf("b = *d\n",b); 
28  b=test1();  
29  printf("b =*d\n",b);  
30  b =test1(); 
31  printf("b = *d\n",b); 
32
33}
a =2
a=3
a=4
b =2 b =2 b=2
请按任意键继续...

四、外部链接的静态变量

外部链接的静态变量具有文件作用域、外部链接和静态存储期。该类别有时称为外部存储类别(external storage class),属于该类别的变量称为外部变量(external variable)。把变量的定义性声明(defining declaration)放 在在所有函数的外面便创建了外部变量。当然,为了指出该函数使用了外部 变量,可以在函数中用关键字extern再次声明。

1 #include "stdio.h"
2 int units = 0; /* 外部变量 */3 void critic(void);
5 int main(void)6{
extern int units; /* 可选的重复声明 */
7
8 printf("How many pounds to a firkin of butter? n"); 
9 scanf("*d",&units); 
10  while (units !=56)  
11  critic(); 
12  printf("You must have looked it up! n"),  
13  return 0; 
14 }15
16 void critic(void)17 {
18 /* 删除了可选的重复声明 */
19  printf("No luck, my friend. Try again. n"), 
20  scanf("*d",&units); 
21}
How many pounds to a firkin of butter?13
No luck, my friend. Try again.56
You must have looked it up!
请按任意键继续.

units具有文件作用域、外部链接和静态存储期。所以即使我们在main函数里没有声明uints,程序一样可行。来看看注释掉extern声明。

1 #include "stdio.h'
2 int units = 0; /* 外部变量 */3 void critic(void);
4 5 int main (void) 注释掉 
6{
7 //extern int units; /* 可选的重复声明 */ 
8 printf("How many pounds to a firkin of butter?\n"): 
scanf("*d",&units);
10  while (units != 56) 
11  critic(); 
12  printf("You must have looked it up!\n");  
13  return 0; 
14}15
16 void critic(void)17 {
18 /* 删除了可选的重复声明 */
19  printf("No luck, my friend. Try again.\n"); 
20  scanf("*d",&units); 
21}
How many pounds to a firkin of butter?45
No luck, my friend. Try again.56
You must have looked it up!
请按任意键继续..

再看看

#include  "stdio  
2 int units = 0; /* 外部变量 */3 void critic(void);
4
int main(void){
6
int units; /* 可选的重复声明 */
printf("How many pounds to a tirkin of butter?\n"); scanf("ad",&units); while(units != 56)
11  critic(); 
12  printf("You must have looked it up!\n");  
13  return 0; 
14}15
16 void critic(void)17 {
18 /* 删除了可选的重复声明 */
19  printf("No luck, my friend. Try again. n"); 
20  scanf("*d",&units); 
21 }  
How many pounds to a firkin of butter?45
No luck, my friend. Try again.12
No  luck, my friend. Try again. 
56
No luck, my friend. Try again.56
No luck, my friend. Try again.56
No luck, my friend. Try again.56
No  luck, my friend. Try again. 
56
No  luck, my friend. Try again. 
56
No luck, my friend. Try again 

为什么会这样?因为在函数里面定义的units是局部变量,具有块作用域、自动存储期、无链接属性。相当于外部变量units和局部变量units是独立的。

5 int main(void)
6 { int units,  默认初始化为0 
8 9 scanf("sd",&units); printf("How many pounds to a firkin of butter?  判断0不等于56,一直调甪 
0
11  critic(); while (units !=56 critic  

五、内部链接的静态变量

该存储类别的变量具有静态存储期、文件作用域和内部链接。这种变量过去称为外部静态变量(external static variable),但是这个术语有点自相矛盾(这些变量具有内部链接)。但是,没有合适的新简称, 所以只能用内部链接的静态变量(static variable with internal linkage)。普通的外部变量可用于同一程序中任意文件中的函数,但是内部链接的静态变量只能用于同一个文件中的函数。

号主:一枚机械专业本科生,经历了转行,从外包逆袭到芯片原厂的Linux驱动开发工程师,深入操作系统的世界,贯彻终身学习、终身成长的理念。平时喜欢折腾,寒冬之下,抱团取暖,期待你来一起探讨技术、搞自媒体副业,程序员接单和投资理财。【对了,不定期送闲置开发板、书籍、键盘等等】。

如果你想了解我的转行经验,欢迎找我交流~gongzhong号【哆哆jarvis】

一起不断探索自我、走出迷茫、找到热爱,希望和你成为朋友,一起成长~

相关文章
|
4月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
389 0
|
2月前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
64 1
|
2月前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
2月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
2月前
|
存储 编译器
数据在内存中的存储
数据在内存中的存储
42 4
|
2月前
|
存储 Java
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
这篇文章详细地介绍了Java对象的创建过程、内存布局、对象头的MarkWord、对象的定位方式以及对象的分配策略,并深入探讨了happens-before原则以确保多线程环境下的正确同步。
57 0
JVM知识体系学习四:排序规范(happens-before原则)、对象创建过程、对象的内存中存储布局、对象的大小、对象头内容、对象如何定位、对象如何分配
|
2月前
|
存储 机器学习/深度学习 人工智能
数据在内存中的存储
数据在内存中的存储
|
2月前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储
|
2月前
|
存储
整型在内存中的存储
本文详细解释了计算机中整型数据的三种二进制表示方法:原码、反码和补码,并展示了如何将正数和负数的原码转换为反码和补码。
38 0
|
4月前
|
存储 监控 Docker
如何限制docker使用的cpu,内存,存储
如何限制docker使用的cpu,内存,存储