C语言学习第011课——变量和函数的作用域

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();
    }
}
运行结果为 打印1011 
因为主函数调用了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();
}

运行结果为:
在这里插入图片描述
调用的是本文件中的静态函数

总结:无论是全局函数,还是静态函数,都存储在代码区,被唤醒的时候,进入栈区,函数结束,从栈区销毁,再次调用的话,会再次进入栈区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值