C语言的static关键字到底是个啥

在 C 语言中,static 关键字不仅可以用来修饰变量,还可以用来修饰函数。在使用 static
关键字修饰变量时,我们称此变量为静态变量。

静态变量的存储方式与全局变量一样,都是静态存储方式。但这里需要特别说明的是,静态变量属于静态存储方式,属于静态存储方式的变量却不一定就是静态变量。例如,全局变量虽然属于静态存储方式,但并不是静态变量,它必须由 static 加以定义后才能成为静态全局变量。

在了解C语言这个玩意儿之前,咱们需要先知道知道汇编语言是怎么分内存的,内存大概是怎么分的??
猜测一下啊,首先知道cpu中有寄存器,然后cpu从内存中拿数据进行处理,那么就需要指令
指令又由什么组成呢??那肯定是

指令–>操作码+操作数

而且我们知道汇编代码存放在代码段中,并且在代码运行时会开辟一块栈空间用来存放代码段正在运行的私有数据,另外,运行时汇编代码段之间的共享数据会存放在堆内存里,而像一些静态的数据,会另外由数据段内存直接保存
因此,对于一个特定的程序来说,可以得到内存大致的图如下:
在这里插入图片描述
这里没有考虑OS的内存空间

可以猜测到,static规定的数据肯定是放在数据段内存里

我写了一个test.c进行测试

#include<stdio.h>
static int stdata1=10;
int data1 = 51;
int ttt(){
	static int stdata2=20;
	int data2=52;
	return 1;
}

如此来看,stdata肯定是属于全局的数据,而stdata1呢?

	.file	"test.c"
	.text
	.data
	.align 4
	.type	stdata1, @object
	.size	stdata1, 4
stdata1:
	.long	10
	.globl	data1
	.align 4
	.type	data1, @object
	.size	data1, 4
data1:
	.long	51
	.text
	.globl	ttt
	.type	ttt, @function
ttt:
.LFB0:
	pushq	%rbp
	movq	%rsp, %rbp
	; 开辟栈帧空间
	movl	$52, -4(%rbp)
	; 开辟4字节空间存放 52
	movl	$1, %eax
	popq	%rbp
	ret

.LFE0:
	.size	ttt, .-ttt
	.data
	.align 4
	.type	stdata2.2362, @object
	.size	stdata2.2362, 4
stdata2.2362:
	.long	20


很显然,stdata和stdata1都不是在ttt方法的代码段中开辟的,而是在main之外就创建了,说明C语言里用static修饰的不在栈内存里,但是,stdata1没有.globl字段,说明这个stdata1不是全局的,但是,他不会随着方法帧的ret而从内存里消失
而且,从汇编层面来看全局data1和stdata并没有什么差别,这不就说明
C语言里的全局变量其实就是和全局静态变量是一样的
那这两个具体有什么不同呢??
我这里另外写了一个test2.c文件,并且尝试用gcc将两者的汇编文件弄在一起
test2.c如下:

#include<stdio.h>

extern int stdata;
extern int data1;
int sum(){
	int c = stdata+data1;
	return 1;
}

	.file	"test2.c"
	.text
	.globl	sum
	.type	sum, @function
sum:
.LFB0:
	pushq	%rbp
	movq	%rsp, %rbp
	movl	stdata(%rip), %edx
	movl	data1(%rip), %eax
	addl	%edx, %eax
	movl	%eax, -4(%rbp)
	movl	$1, %eax
	popq	%rbp
	ret
.LFE0:
	.size	sum, .-sum

使用gcc命令时出现以下问题:
在这里插入图片描述
好,那么我把test2.c中的stdata清除掉,再执行同样的步骤
这时就不报错了
这说明了什么??
说明全局变量被static修饰后,无法被另外的文件引用,也就是说,在将两个汇编文件整合的时候这个被static修饰的变量不会被汇编器撸出来给另外一个汇编文件看
被static修饰的全局变量,就只能在当前文件里使用

而被static修饰的方法,和变量一样,只不过是代码段而已

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值