static关键字与extern关键字
C中的关键字extern是用来做变量声明的, 声明extern关键字的全局变量和全局函数可以使得它们的作用域得到扩展, 全局变量和全局函数默认是extern所以声明时我们一般不写
C中的关键字static主要用于修饰普通变量和函数(C++中则主要修饰类的成员变量和函数)
不管在C还是C++中static静态变量都存储在静态区(全局区)
extern关键字
一. extern修饰全局变量(大多数时候被省略的关键字)
- extern在一个文件内扩展全局变量的作用域(这种情况要发挥其作用的话不能被省略)
在C中, 如果全局变量不在文件开头定义, 其有效作用范围(作用域)只限于全局变量定义处到文件结束, 在定义处之前不能使用该变量 ,如需在定义处之前想用该全局变量的话, 需要在用之前用extern对该变量进行外部变量声明, 表示将此变量的作用域扩展到此位置, 这样就合法了
来看代码
main.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int Max();
int main() {
printf("请输入a和b的值\n");
scanf("%d %d", &a, &b);
printf("最大值为:%d\n", Max());
system("pause");
return 0;
}
int a, b;
int Max() {
return a > b ? a : b;
}
我们看到, 编译未通过
我们加上extern之后再看
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int Max();
int main() {
printf("请输入a和b的值\n");
extern a, b;
scanf("%d %d", &a, &b);
printf("最大值为:%d\n", Max());
system("pause");
return 0;
}
int a, b;
int Max() {
return a > b ? a : b;
}
这就可以了
- 将全局变量的作用域扩展到其他文件(可以省略, 一般不写)
一个C程序可以由一个或多个源文件组成, 如果由多个组成, 那么在想在一个文件用另一个文件中定义的全局变量怎么办呢?
如果在两个文件中都定义名字相同的变量, 会在连接时出现重复定义的错误, 正确的做法是, 在任意一个文件中在全局变量前加上extern修饰, 这样实际只定义了一个全局变量, 只是将其作用域扩展到了其他文件
来看代码:
int b = 2;//全局成员默认是extern,所以可以省略
extern int c = 3;
main.c
#include<stdio.h>
#include<stdlib.h>
extern b;//
int c;
int main() {
printf("b= %d\n", b);
printf("c= %d\n", c);
system("pause");
return 0;
}
将test.c和main.c放在同一个工程下 .
二. extern修饰函数(可以省略,一般不写)
在声明函数时, 在函数最左端加关键字extern, 此函数就成为了外部函数, 可供其他文件调用
(与之对应的是内部函数, 用staic修饰, 文章下面再来看)
来看看具体怎么用, 看代码 :
test1.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void input_a(int* pa) {
printf("请输入a的值\n");
scanf("%d", pa);
}
test2.c
#include<stdio.h>
extern void output_a(const int* pa) {
printf("a=%d\n", *pa);
}
main.c
#include<stdio.h>
#include<stdlib.h>
int main() {
int a;
int* pa = &a;
extern void input_a(int* pa);
void output_a(int* pa);
input_a(pa);
output_a(pa);
system("pause");
return 0;
}
static关键字
一 .static修饰变量
注意: 在用static声明变量时, 只能在声明变量的基础上加static修饰, 而不能单独使用, 例如 下面用法不对
int a;
static a;
在C中和static类似不能这样用的关键字还有auto ,register
- 修饰全局变量, 将全局变量的作用域限制在本文件
static修饰全局变量改变的是全局变量的作用域, 使全局变量只能在本文件中使用,
来看下面代码
test.c
static int a = 1;
main.c
#include<stdio.h>
#include<stdlib.h>
extern a;
int main() {
printf("a= %d\n", a);
system("pause");
return 0;
}
运行结果出错, 可以看到static确实把a的作用域限定到了test.c中
- 修饰局部变量, 改变局部变量的生命周期(将局部变量存储在静态区)
static修饰局部变量, 会将局部变量存储在静态区(全局区)(普通局部变量存储在栈区), 改变局部变量的生命周期, 使其伴随整个程序, 程序运行结束时才会被释放
注意 : 虽然static修饰的局部变量改变了生命周期, 使其伴随整个程序, 程序结束前为其分配的空间一直都在, 但作用域并未改变
来看代码
#include<stdio.h>
#include<stdlib.h>
void test() {
static int m = 1;
printf("m = %d\n", m);
++m;
}
int main() {
test();
test();
test();
system("pause");
return 0;
}
二. static修饰函数
在声明函数时在其最左边加static修饰, 这个函数就成了内部函数, 内部函数又称为静态函数, 会使函数作用域只限定于本文件., 这样在不同文件中就算有相同名字的函数也不会相互干扰
通常一个大的程序往往由多人分工来编写不同的文件模块, 在不同人编写代码时,很可能会出现相同名字的函数, 此时, 在自己写的函数前加static修饰, 就不会出现函数重名的问题了, 这就保证了程序的可靠性.
来看例子
static void test(int *pa) {
*pa++;
}
#include<stdio.h>
#include<stdlib.h>
void test(int *pa);
int main() {
int a = 0;
int* pa = &a;
test(pa);
printf("a= %d\n", a);
system("pause");
return 0;
}
我们看到, 在mian.c中确实访问不到test.c中的static函数了