第五讲:(二)static和extern

本文详细解释了C语言中的static和extern关键字,讨论了它们如何影响变量的作用域、生命周期和外部链接性。static修饰局部变量和全局变量会改变其存储位置和链接属性,而extern用于声明外部符号。
摘要由CSDN通过智能技术生成

staticextern是C语言中的关键字。
其中static是静态的意思,它的作用是:

  1. 修饰局部变量。
  2. 修饰全局变量。
  3. 修饰函数。

extern则是用来声明外部符号的。

1. 作用域和生命周期。

在讲解staticextern之前,我们首先要了解下什么是作用域和生命周期。
**作用域(scope)**是程序设计理念,通常来说,一段程序代码中所用到变量并不是总是有效的(可用)的,而限定这个变量的有效性的代码范围就是这个变量的作用域。

  1. 局部变量的作用域是变量所在的局部范围。(一般是局部变量所在的大括号{}内。)
  2. 全局变量的作用域是整个工程(项目)。(不在任何大括号范围内,是任何的大括号。)

生命周期指的是变量在创建时(申请内存)到变量的销毁(释放内存)之间的一个时间段。

  1. 局部变量的生命周期是:进入作用域变量创建,生命周期开始,出作用域声明周期结束。
  2. 全局变量的生命周期:整个程序的生命周期,即程序不停止,变量就 一直存在。

2. static修饰局部变量

我们先看下下面的代码:

void test(void)
{
	int i = 0;
	i++;
	printf("%d ", i);
}

int main()
{
	int i = 0;
	for (i = 0; i < 5;i++)
	{
		test();
	}
	return 0;
}

上面的代码中我们看到我们定义了两次的变量i,根据上面我们所说的作用域和生命周期的讲解,我们知道for循环中用的变量i的作用域只是在函数main()中,对此代码运行后结果如下:
在这里插入图片描述
这是什么情况呢?我们看下它的运行顺序:
在这里插入图片描述
上面的代码在运行后,执行for循环中的语句,即调用5次test()函数,而test()函数中每执行一次,变量i就创建一次,函数体运行完毕后,变量i生命周期结束,释放内存,变量i销毁。所以这里的运行结果就是5个1。
那么我们把上面的代码test()函数中的变量i定义前面加上 static会怎样呢?

void test(void)
{
	static int i = 0;
	i++;
	printf("%d ", i);
}

int main()
{
	int i = 0;
	for (i = 0; i < 5;i++)
	{
		test();
	}
	return 0;
}

我们看下运行情况:
在这里插入图片描述
static修饰变量i以后,我们发现输出的数据不再是5个1,而是进行了累加自增。
我们在第二讲:(一)数据类型和变量中说到,全局变量的存放是在静态区,而局部变量的存放是在栈区内的,如图:
在这里插入图片描述
static在修饰局部变量i后,把变量i由栈区存放变成了静态区存放,这样就导致了变量i的生命周期由test()函数的大括号{}内,变成了整个工程的生命周期。
结论:static修饰局部变量以后,改变了局部变量的生命周期,生命周期的改变实质上就是改变了变量的存储位置,原本局部变量的存储是放在栈区临时存储,在static修饰以后存储到了静态区,存储在静态区的变量是和全局变量一样的,生命周期是和程序的生命周期一样的,只有程序结束,变量才会销毁。但是,大家要注意了,它只是生命周期延长了,作用域并没有发发生任何改变

3. static修饰全局变量

在说static修饰全局变量前,我们先说下全局变量和函数在C语言中是有外部链接属性的,什么是外部链接属性呢?意思就是在A文件中定义的全局变量和函数,我们用extern关键字在B文件中再次进行一次声明,就可以直接调用。
extern是用来声明外部符号的,如果⼀个全局的符号在A⽂件中定义的,在B⽂件中想使⽤,就可以使用extern进⾏声明,然后使⽤。
我们用下面的代码看下:
先创建一个新的源文件:add.c

//全局变量声明
int g_val = 3;

然后我们在test.c中写如下代码:

int main()
{
	extern int g_val;
	printf("%d\n", g_val);
	return 0;
}

运行上面的代码:
在这里插入图片描述
上面运行结果显示为add.c中定义的值,我们并没有在源文件test.c中给变量g_val赋予任何的值,可是输出的结果确实是源文件add.c中的值。
上面只是介绍了全局变量的外部链接属性,我们这里用static对全局变量进行修饰看下是什么效果:
我们把源文件add.c的内容修改如下:

//全局变量声明
static int g_val = 3;

此时我们在运行看下:
在这里插入图片描述
此时,编译器提示链接错误,无法解析外部符号。
总结: 全局变量在被static修饰以后,让这个全局变量只能在本源文件中使用,不能在其他源文件中调用,即把全局变量的外部链接属性改成内部链接属性,其他源文件无法调用。
使用建议: 如果一个全局变量我们只想让他在本文件中使用,不让其他文件调用,那么我们就可以使用static

4. static修饰函数

我们上面讲到全局变量和函数都是有外部链接属性的,static修饰函数和修饰全局变量的性质是一样的,都是把所修饰的对象由外部链接属性修改成内部链接属性。这里不再做演示,大家可以自己练习看下效果。
static修饰函数代码演示:

static int add(int a, int b)
{
 return a+b;
}

外部文件调用代码:

extern int add(int a, int b);

使用建议: 当我们定义一个函数时,只想让它在所在的文件可用,不想被其他文件调用,就可以用static对函数进行调用。

本博客只为学习使用,如有错误请大佬指出,感谢大家支持!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值