你了解C语言static关键字的3个作用吗?
Posted 努力学习游泳的鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了你了解C语言static关键字的3个作用吗?相关的知识,希望对你有一定的参考价值。
static这个关键字是“静态”的意思,在C语言里有3个作用。分别是:
- 修饰局部变量,该局部变量称为静态的局部变量。
- 修饰全局变量,该全局变量称为静态的全局变量。
- 修饰函数,该函数称为静态的函数。
1.修饰局部变量
一个“正常”的局部变量,不被static修饰时,是在内存中的栈区上创建的。在栈区上创建的变量的特点是:进入作用域时创建,出作用域时销毁。比如:
void func()
int i = 1;
++i;
printf("%d ", i);
int main()
for (int i=0; i<10; ++i)
func();
return 0;
main函数和func函数里的i变量都是“正常”的局部变量,进入作用域创建,出作用域销毁。对于main函数里的i,代码执行到for循环时创建,一旦for循环结束,就会被销毁。不过,我们重点看func函数里的i,这个i也是局部变量,并且和main函数里的i不是一个变量,因为在不同的作用域里。每次调用func函数,都会创建一个i,调用结束后,这个i就被销毁了。
本质上,“正常”的局部变量的生命周期被作用域限定,进入作用域创建,出作用域销毁。所以每次调用func时,都是先创建一个i并初始化成1,i自增变成2,打印i的值(即2),func函数执行结束时把i给销毁。下次调用时还会重新创建一个i,重复上次调用的过程。如果调用10次,屏幕上就会打印10个2。
如果func里的i是被static修饰的呢?
void func()
static int i = 1; // 静态的局部变量
++i;
printf("%d ", i);
int main()
for (int i=0; i<10; ++i)
func();
return 0;
当一个局部变量被static修饰时,该局部变量称为静态的局部变量。静态的局部变量和“正常”的局部变量不同,不是在栈区上创建的,而是在静态区上创建的。在静态区上创建的变量,生命周期是全局的,也就是说,静态局部变量的生命周期和程序的生命周期相同。
第一次调用func函数时,会在func函数内部创建一个静态的局部变量i,这个i是存储在静态区的。接着i++,打印2。当func函数执行结束时,由于i是存储在静态区的,并不会被销毁,也就是说,这个i还在。所以下次调用func函数时,并不会重新创建i,此时使用的i变量还是上次留下来的i,会保留上次的值,即2,++后打印3。再下次调用,++后打印4,以此类推。输出结果:
总结一下:static修饰局部变量,改变了变量的存储位置,本来一个局部变量是存储在栈区的,被static修饰之后就存储在静态区了。而静态区的变量的生命周期是全局的,出了作用域不会被销毁,下次进入作用域时还在。
注意:静态的局部变量虽然生命周期和“正常”的局部变量不同,但是作用域并没发生改变,仍然是在其局部范围内可以被使用。
2.修饰全局变量
一个“正常”的全局变量是具有外部链接属性的,也就是说,在一个文件内定义的全局变量,其他文件内是可以使用的,这个变量是跨文件的。当然,跨文件使用全局变量必须先声明。比如我创建2个文件,分别是test.c和main.c:
// test.c
int g_val; // 全局变量
// main.c
extern int g_val; // 跨文件使用需用extern声明
int main()
g_val = 2023; // 可以跨文件使用
return 0;
全局变量如果被static修饰,称为静态的全局变量。静态的全局变量具有内部链接属性,换句话说,静态的全局变量不能跨文件使用。比如:
// test.c
static int g_val; // 静态的全局变量
// main.c
extern int g_val; // 哪怕用extern声明了
int main()
g_val = 2023; // 不能使用了,这么写会报错
return 0;
此时的g_val是不能跨文件使用的。以上的写法会报错:找不到g_val。
总结一下:static修饰全局变量,改变了其链接属性。本来一个“正常”的全局变量是具有外部链接属性的,可以跨文件使用。但是被static修饰之后,具有内部链接属性,只能在所在的文件使用,不能跨文件使用了。相当于改变了变量的作用域。
注意:虽然静态的全局变量的作用域和“正常”的全局变量不同,但是其生命周期并没有被static改变,仍然和程序的生命周期相同。
3.修饰函数
一个“正常”的函数也是具有外部链接属性的,也能够跨文件使用。举个例子:
// test.c
int Add(int x, int y)
return x + y;
// main.c
extern Add(int x, int y); // 声明时extern关键字、形参名x和y可以省略
int main()
int sum = Add(2, 3);
return 0;
一旦一个函数被static修饰,称为静态的函数。静态的函数和静态的全局变量类似,其链接属性从外部变为内部,不能跨文件使用了。比如:
// test.c
static int Add(int x, int y)
return x + y;
// main.c
extern Add(int x, int y); // 哪怕声明了
int main()
int sum = Add(2, 3); // 不能跨文件使用了,这么使用会报错
return 0;
总结一下:本来一个“正常”的函数具有外部链接属性,可以跨文件使用,被static修饰后,其链接属性变成内部的链接属性,不能跨文件使用了,只能在自己所在的源文件内部使用。
总结
- static修饰局部变量,称为静态的局部变量,改变了局部变量的存储位置(栈区->静态区),相当于改变了其生命周期,出了作用域不会被销毁,下次进入作用域时还在,但是其作用域仍然是其所在的局部范围。
- static修饰全局变量,称为静态的全局变量,改变了全局变量的链接属性(外部的->内部的),相当于改变了其作用域,使得其不能跨文件使用了,但是其生命周期仍然是全局的。
- static修饰函数,称为静态的函数,改变了函数的链接属性(外部的->内部的),使得其不能跨文件使用。
感谢大家的阅读!
C语言关键字及进制的转换你都知道吗?
前面我们讲过
C语言简洁、紧凑
使用方便、灵活
那是什么使得C语言这么方便呢?
那就是关键字,或称保留字
C语言的关键字共有32个
根据关键字的作用
可分为
数据类型关键字
控制语句关键字
存储类型关键字
其他关键字
01
数值类型关键字
数值类型关键字有12个,包括void、char、short、int、long、float、double、signed、unsigned、struct、enum、union
02
控制语句关键字
控制语句关键字也有12个,包括if、else、switch、case、default、break、for、do、while、goto、continue、return
03
存储类型关键字
存储类型关键字有4个,包括auto、extern、register、static
04
其他关键字
其他关键字包括const、sizeof、typedef、volatile
以上就是C语言常用关键字
那么计算机有哪几种进制表示法呢?
进制之间又是如何转换的呢?
一起来看一下
计算机语言中有十进制、二进制、八进制、十六进制,但是C语言常量中没有二进制。
01
十进制与二进制、八进制、十六进制间的转换
02
二进制与八进制、十六进制间的转换
二进制转八进制
二进制转换成八进制的方法是,取3合1法,即从二进制的小数点为分界点,向左(或向右)每三位取成一位。
二进制转十六进制
二进制转换成八进制的方法是,取4合1法,即从二进制的小数点为分界点,向左(或向右)每四位取成一位。
以上就是有关C语言关键字及计算机进制转换的相关知识,同学们你们学到了吗?
以上是关于你了解C语言static关键字的3个作用吗?的主要内容,如果未能解决你的问题,请参考以下文章