C语言变量的作用域分为
- 代码块作用域(代码块是{}之间的一段代码)
- 函数作用域
- 文件作用域
局部变量
局部变量也叫auto自动变量(auto可写可不写),一般情况下函数内部定义的变量都是局部变量
#include<stdio.h>
int main(void){
int a = 10;
printf("%d\n",a);
}
以上就定义了一个局部变量
作用域:从变量定义到函数结束
生命周期:从创建到函数结束
形参也是局部变量
存放在栈区
全局变量
- 在函数外定义,可被本文件及其他文件中的函数所共用,若其他文件中的函数调用此变量,必须用extern声明
- 全局变量的生命周期和程序运行周期一样
- 不同文件的全局变量不可重复
- 全局变量存放在数据区
- 在同一文件中,允许全局变量和局部变量同名,在局部变量的作用域内,全局变量不起作用
#include<stdio.h>
int a = 10; 定义一个全局变量
int main(void){
int a = 100; 局部变量可以和全局变量重名
printf("%d\n",a); 运行结果:100
}
#include<stdio.h>
int a = 10;
int main(void){
printf("%d\n",a); 运行结果:10
下面这种直接用大括号括起来的代码,叫匿名内部函数,存放在栈区,大括号结束即出栈,占用的内存会从内存中销毁
{
int a = 123;
printf("%d\n",a); 运行结果:123
}
printf("%d\n",a); 运行结果:10
int a = 100;
printf("%d\n",a); 运行结果:100
}
#include<stdio.h>
int a = 10;
int main(void){
printf("%d\n",a);
{
a = 123; 这里少写了一个int,表示使用的是全局变量,而不是局部变量,a的值不会被回收
printf("%d\n",a); 运行结果:123
}
printf("%d\n",a); 运行结果:123
int a = 100;
printf("%d\n",a); 运行结果:100
}
静态(static)局部变量
定义一个静态局部变量
#include<stdio.h>
int main(void){
static int a = 10; 定义一个静态局部变量
printf("%d\n",a);
}
- static局部变量的作用域只在定义的函数内有效
#include<stdio.h>
int main(void){
static int a = 10; 定义一个静态局部变量
printf("%d\n",a);
}
void fun1(){
printf("%d\n",a); 在这里直接使用main中定义的静态局部变量a,会报错
}
- 静态局部变量只会初始化一次,可以多次赋值
看下面的两个例子:
#include<stdio.h>
void fun(){
int a = 10; 定义局部变量a
a++;
printf("%d\n",a);
}
int main(void){
for(int i = 0;i<10;i++){
fun();
}
}
运行结果为 打印10次 11
因为主函数调用了10次fun函数,每次fun结束都会在栈内存中销毁,再次调用,
只会再次重新创建局部变量a,并赋值为10,因此每次打印结果都为11
#include<stdio.h>
void fun(){
static int a = 10; 定义静态局部变量a
a++;
printf("%d\n",a);
}
int main(void){
for(int i = 0;i<10;i++){
fun();
}
}
运行结果为11 12 13 14 ......
因为静态局部变量只会初始化一次,可以多次赋值,static int a =10之后,再次运行fun函数,这一行代码不会再执行了,
静态局部变量的初始化要优于函数,断点查看过程的时候,第一次进入fun,会直接执行a++,因为初始化静态局部变量的操作会优先执行,而且只执行一次
- 静态局部变量是保存在数据区的
函数是保存在栈区的,所以静态局部变量的值不会因为函数出栈而销毁,这个值是一直存在的 - 生命周期:从程序创建到程序销毁
静态(static)全局变量
静态全局变量的定义和使用
#include<stdio.h>
static int a = 10; 定义和初始化静态全局变量
void fun(){
a=20;
printf("%d\n",a); 打印结果为20,修改成功
}
int main(void){
printf("%d\n",a); 运行结果为10
fun(); 调用函数改变static全局变量的值
}
作用域:可以在本文件中使用,不可以在其他文件中使用
生命周期:从程序创建到程序销毁
存放在数据区
未初始化变量的值
局部变量:
#include<stdio.h>
int main(void){
int a;
printf("%d\n",a);
}
打印结果为乱码
全局变量:
#include<stdio.h>
int a;
int main(void){
printf("%d\n",a);
}
打印结果为0
静态局部变量:
#include<stdio.h>
int main(void){
static int a;
printf("%d\n",a);
}
打印结果为0
静态全局变量:
#include<stdio.h>
static int a;
int main(void){
printf("%d\n",a);
}
打印结果为0
全局函数和静态函数
在C语言中函数默认都是全局的,使用关键字static可以将函数声明为静态,函数定义为static就意味着这个函数只能在定义这个函数的文件中使用,在其他文件中不能调用,即使在其他文件中声名了。
全局函数
假如新建一个项目,有主入口main.c然后新建了一个test.c:
#include<stdio.h>
void func(){
printf("here is test.c func()\n");
}
在main.c中:
#include<stdio.h>
int main(void){
printf("Hello\n");
func();
}
运行结果为:
这里注意到,main函数中调用的func函数是一个外部定义的函数,但是没有经过声明也可以使用,说明在同一个项目中,函数可以不经过声明直接调用,但是在main.c中,选择func()点右键,转到定义,发现转不过去,当在main.c中,增加声明func函数之后,就可以转到定义了,说明函数调用前还是要声明一下的。
但是变量不声明是找不到的,变量必须声明。
在C语言中,不支持一个函数名,后面有不同的参数,如下:
void func(int* arr,int a){}
void func(int* arr,int a,int b){} C语言中不可以这样
以上的写法,在C++中,是两个完全不同的函数,完全独立的函数,这种形式叫多态
总结:
全局函数的名称是作用域中唯一的。
作用域:在整个项目中所有文件中使用
生命周期:从程序创建到程序销毁
静态函数
静态函数可以和全局函数重名
作用域:当前文件中
生命周期:从程序创建到程序销毁
#include<stdio.h>
static void func(){ 定义一个静态函数
printf("hello this is func\n");
}
int main(void){
func(); 调用静态函数,可以执行
}
如果将静态函数func定义在其他文件中,则在main中无法调用到它,
思考这样一个问题,如果func是定义在其他文件中的全局函数,在main.c中可以调用到,这个时候,如果在main.c中创建一个静态函数func(),在main函数中调用func(),他会调用哪个呢?
test.c
#include<stdio.h>
void func(){
printf("hello 1 \n");
}
main.c
#include<stdio.h>
static void func(){
printf("hello 2 \n");
}
int main(void){
func();
}
运行结果为:
调用的是本文件中的静态函数
总结:无论是全局函数,还是静态函数,都存储在代码区,被唤醒的时候,进入栈区,函数结束,从栈区销毁,再次调用的话,会再次进入栈区