作者:低调
作者宣言:认真写好每一篇博客
前言
Hello各位佬们,好久不见,已经有很长一段时间没有更新优质好文了,并不是作者放弃了,最近学校课程任务比较中,加上参加一个省赛,在备战的状态,所以没有太多的时间的时间来更新好的文章了,希望各位佬能重新记起我(开个小玩笑),废话不多说,接下来欣赏文章吧
这是C语言为我们提供许多丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的,比如int,定义整型变量的。char,定义字符变量的等等一系列关键字。每一个关键字都有自己的用途,我们今天主要介绍的关键字是static。进入正文!!!
以下是本篇文章正文内容:
一、static与常见关键字的区别
在C语言中:static是用来修饰变量和函数的
相信大家看到这里是完全不懂这个关键字什么用途,接下来看一个代码:
//代码1
#include<stdio.h>
int main()
{
int a=0;//用int定义一个整型变量
char b=0;//用char定义一个字符变量。
return 0;
}
相信大家看到这个代码,我猜测大家接下来会这么使用static
//代码2
#include<stdio.h>
int main()
{
static a=0;
return 0;
}
用来修饰变量的呗,但这里作者想告诉你修饰变量个创建变量是不同,代码1就是在系统内存上创建一个变量,代码2的用法是错误的,修饰变量是在创建好的基础上进行修饰
//代码2修改后
#include<stdio.h>
int main()
{
static int a=0;//这才是修饰变量
return 0;
}
相信大家看到这里,也知道了static和我们初学知道的关键字是有所不同的,并且还了解了原来关键字还可以这么使用。
二、static的三大用途
1.修饰局部变量
修饰局部变量也称修饰静态局部变量
大家先来看一下这个图,我们常常把内存分为这三个部分,栈区,堆区,静态区。大家可以清晰从图中看到每个部分的用途,如果大家对作用域这方面的知识不太了解的话,就需要先取百度一下,这里作者就不做过多的说明了,想代码1用int创建一个整型变量a就是在栈区里创建的,出了作用域就被销毁了
//代码3
#include<stdio.h>
int mian()
{
{
int a=0;//作用域就在这个代码块内起作用
}
{
a=10;//这个错误赋值就是错误,因为a在这个变量只在上一个代码块有作用,出来这个代码块a这个变量就不存在了;
}
return 0;
}
//代码4
#include<stdio.h>
int mian()
{
{
static int a=0;
}
{
a=10;//这样的赋值又是正确的
}
return 0;
}
这就是static的作用用来修饰局部变量,因为修饰的局部变量,在栈区创建的变量的位置改到了静态区,放到静态区的变量知道程序结束后才释放。
不懂没有关系,让我们再来看两个直观代码:
//代码5
#include <stdio.h>
void test()
{
int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
这是用一个函数实现的test()函数里面的i当这个函数结束后i就被释放了,每次循环进去之后,都要重新创建变量i,所以i一直为0;
此次打印的结果为1 1 1 1 1 1 1 1 1 1 。
#include <stdio.h>
void test()
{
static int i = 0;//用static修饰的局部变量
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
此次打印的结果为1 2 3 4 5 6 7 8 9 10
为什么结果为这个呢?我之前说过静态区的局部变量知道程序结束后才被释放。而static修饰的局部变量就是把栈区的位置改到静态区。所以每次进入static函数时,出来第一次进入创建了i。之后的每一次进入就会直接跳过static int a=0;这条语句,因为已经创建过,没有被释放,所以不需要重新被创建,才会跳过这个语句。相当于保留了上一次i的值,才会打印出这样的结果。
static修饰局部变量改变了变量的生命周期让静态局部变量出了作用域依然存在,到程序结束生命周期才结束。
看到这里相信大家对Static修饰静态的局部变量有了更深的了解了吧,那接下来就开始将第二个作用了哦
2.修饰全局变量
从上面的那个图来看,全局变量放在静态区,程序停止之后才会被释放。
什么是全局变量,来看一下下面的代码:
#include<stdio.h>
int g_val=0;//全局变量
int main()
{
int g_val=0;//局部变量,在代码块中
return 0;
}
全局变量的作用域时整个工程。
在一个工程里我们可以创建多个文件,而想在test.c文件里想使用add.c文件里的变量,需要用extern声明外部符号,所以说全局变量的作用域是很大的,那跟static有什么关系呢?
那我们在g_val前面加一个static进行修饰,此时的g_val已经全局变量了,那我们来看看错误列表,无法解析的外部符号,为什么会出现这样的错误呢?是因为全局变量本身具有外部链接属性,A文件中定义的变量,在B文件中可以通过(链接)使用。全局变量在被static修饰时,这个外部链接属性就变成内部链接属性,这个全局变量只能在自己所在的文件内部使用。
结论:
1.最终使全局变量的作用域变小了。
2.一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。
大家看到这里对于static修饰全局变量是不是又更加了解了!!
三、修饰函数
修饰函数几乎和修饰全局变量一样,直接上代码:
//代码1
//add.c
int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//代码2
//add.c
static int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
代码1正常,代码2在编译的时候会出现连接性错误.
extern是声明外部符号的,这里是函数,因此不需要使用extern。
一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用。
道理和修饰全局变量形相同的,读者可以自己下来用自己的编译器来测试一下,看看效果。
总结
通过本篇文章,我们对static都有了更深的了解,一个小小的关键字居然又这么多的作用,可见C语言的强大,希望读者学习完这篇文章能够收获多多,这也算是我的回归文章了吧,只要有时间作者就会更新好的文章,相信老粉可以经常回访!!
我们一起来努力!!