C语言作用域和可见性
作用域和可见性
局部变量定义:定义在函数内部的变量
全局变量定义:定义在函数之外的变量
static关键字
如果定义变量时前面加static关键字修饰,表示此变量为静态变量
如果定义变量时前面没有加static关键字修饰,表示此变量为非静态变量
例如
#include <stdio.h>
int main(void){
int a,b,c; //局部非静态变量
static int d,e,f; //局部静态变量
return 0;
}
局部非静态变量
1.局部非静态变量的使用范围:从定义开始依次向下直到最近的花括号结束
2.局部非静态变量的内存生命周期:从定义的地方操作系统就会给变量分配内存,直到最近的花括号操作系统立马释放变量的内存,只能等下次运行这些代码才能给变量重新分配内存
例如
#include <stdio.h>
extern void add(void);
int main(void){
//printf("%d\n",a); //定义前不发访问,报错未定义
//定义并初始化局部非静态变量
int a=100;
printf("%d\n",a); //能访问
if(1){
int b=200;
printf("%d\n",b); //能访问
}
//printf("%d\n",b); //无法访问,报错未定义
{
int d=300;
printf("%d\n",d); //能访问
}
//printf("%d\n",d); //无法访问,报错未定义
switch(1){
case 1:
{
int c=300;
printf("%d\n",c); //能访问
}
//printf("%d\n",c); //无法访问,报错未定义
break;
}
//printf("%d\n",c); //无法访问,报错未定义
return 0;
}
void add(void){
//printf("%d\n",a); //无法访问,报错未定义
}
局部静态变量
1.局部静态变量的使用范围:从定义开始依次向下直到最近的花括号结束.
2.局部静态变量的内存生命周期:从定义开始操作系统就会给变量分配内存,直到程序结束,一次分配,程序不结束,下次不会分配,可以继续使用
例如
#include <stdio.h>
extern int *ret_array(const int [],const int);
int main(void){
//定义并初始化局部非静态变量
int a[10]={1,2,3,4,5,6,7,8,9,10};
int len=sizeof(a)/sizeof(a[0]);
int *ret=ret_array(a,len);
for(int index=0;index<len;index++){
printf("%d ",*(ret+i));
//或者 printf("%d ",ret[i]);
}
printf("\n");
if(1){
static int b=100;
printf("%d\n",b); //可以使用
}
//printf("%d\n",b); //无法使用,报错未定义
switch(1){
case 1:{
static c=300;
printf("%d\n",c); //可以使用
}
//c += 100; //无法使用,报错未定义
break;
}
//printf("%d\n",c); //无法使用,报错未定义
{
static int d=0;
++d;
}
//d--; //无法使用,报错未定义
return 0;
}
int *ret_array(const int a[],const int len){
//b=a;定义前无法使用
//定义局部静态数组
static int b[10];//只会分配一次内存空间
for(int i=0;i < len;i++){
b[i] = a[i];
}
return b;
}
全局非静态变量
1.全局非静态变量分两种形式:
a.同文件
b.不同文件:在不同文件访问只需声明该全局非静态变量,
c.声明全局非静态变量的语法格式:extern 数据类型 全局非静态变量名;
2.全局非静态变量的使用范围:
a.如果是相同文件,从定义开始依次向下全部的函数都可以使用,前面的函数无法使用
b.如果是不同文件,从声明开始依次向下全部的函数都可以使用,前面的函数无法使用
3.全局非静态变量的内存声明周期:从启动运行程序时操作系统就会为其变量分配内存空间,直到程序结束操作系统释放内存
注意:乱序访问,需要互斥访问保护
例如
CScope1.c
int g_a=100;
int g_b=200;
CScope2.c
#include <stdio.h>
extern int g_a;
extern int g_b;
int g_c=300;
extern int sub(void);
int main(void){
int c=g_a+g_b;
printf("%d\n",c);
{
g_a += g_b; //能访问
g_a *= g_c;
}
if(1){
printf("%d\n",g_a + g_b); //能访问
g_b -= g_c;
}
switch(1){
case 1:
printf("%d",g_a); //能访问
g_c++;
break;
}
return 0;
}
int sub(void){
g_c--;
return g_a - g_b;
}
全局静态变量
全局静态变量定义和访问都是在同一个文件,并且只能用于本文件
1.全局静态变量的使用范围:只能用于定义的文件中,从定义开始依次向下全部的函数都可以使用,前面的函数无法使用
2.全局静态变量的内存生命周期:从启动运行程序时操作系统就会为其变量分配内存,直到程序结束操作系统就会释放内存
注意:乱序访问,需要互斥访问保护
例如
#include <stdio.h>
static int g_a=100;
static int g_b=200;
extern int sub(void); //能访问
int main(void){
int add=g_a+g_b;
printf("%d\n",add);
{
g_a += g_b; //能访问
}
if(1){
printf("%d\n",g_a + g_b); //能访问
}
switch(1){
case 1:
printf("%d",g_a); //能访问
break;
}
return 0;
}
int sub(void){
return g_a - g_b;
}