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

本文探讨了C语言中static关键字在变量和函数修饰时的不同作用。静态变量存储在数据段,不随函数结束而消失,但不可被其他文件直接引用。通过分析汇编代码,展示了static变量与全局变量的内存布局和访问方式的异同,强调了static在作用域和链接属性上的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 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修饰的方法,和变量一样,只不过是代码段而已

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值