详细了解 static 和 extern 关键字的用法
C语言 static 和 extern关键字
static
一、 static
函数 和 普通函数 区别
总的来说,static
函数和普通函数的区别就是体现在作用域上面。static
函数只是在本文件起作用。不可以被其他文件调用。先举个例子
例一
math.c
static int add(int a,int b){
return a+b;
}
main.c
#include <stdio.h>int main() {
int a = 10,b=22;
printf("%d!\n",add(a,b));
return 0;
}
对上面文件用gcc
进行编译
$ gcc main.c math.c
结果如下
main.c:15:20: warning: implicit declaration of function 'add' is invalid in C99 [-Wimplicit-function-declaration]
printf("%d!\n",add(a,b));
^
1 warning generated.
Undefined symbols for architecture x86_64:
"_add", referenced from:
_main in main-eaa78d.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
很明显的错误就是main.c
文件中的函数 add
未定义。
我们做一下修改,加一个.h头文件
math.h
static int add(int a,int b);
在main.c
中引入
#include <stdio.h>#include "math.h"
int main() {
int a = 10,b=22;
printf("%d!\n",add(a,b));
return 0;
}
再次使用gcc
进行编译
$ gcc main.c math.c
结果是一样的
./math.h:8:12: warning: function 'add' has internal linkage but is not defined [-Wundefined-internal]
static int add(int a,int b);
^
main.c:15:20: note: used here
printf("%d!\n",add(a,b));
^
1 warning generated.
Undefined symbols for architecture x86_64:
"_add", referenced from:
_main in main-c5f44a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
这说的是add
函数已经声明了,但是在main.c
中并没有定义(虽然在 math.c中有定义,但是函数是static
类型的,只在math.c
文件中可见)。
有两种方式修改
一)将math.c
中的函数改成普通函数
int add(int a,int b){
return a+b+10;
}
gcc
编译会产生警告
main.c:15:20: warning: implicit declaration of function 'add' is invalid in C99 [-Wimplicit-function-declaration]
printf("%d!\n",add(a,b));
^
1 warning generated.
但是程序是可以正常执行的。要去除警告可以在math.h
中声明普通函数,然后在main.c
中引入math.h
int add(int a,int b);
二)在main.c
中定义add()
函数
#include <stdio.h>static int add(int a,int b)
{
return a+b;
}
int main() {
int a = 10,b=22;
printf("%d!\n",add(a,b));
return 0;
}
千万注意的是,不可以同时在两个文件中定义普通的add
函数。例如
例二
math.c
int add(int a,int b){
return a+b+10;
}
main.c
#include <stdio.h>int add(int a,int b)
{
return a+b;
}
int main() {
int a = 10,b=22;
printf("%d!\n",add(a,b));
return 0;
}
这样是会报错的,函数被重复定义。所以说,从另一方面,static
允许在不同文件中定义同名函数,这也是static
函数除作用域之外的另一用途。
二、static
变量 和 普通变量区别
static
变量和static
函数异曲同工,也是对作用域的限定。
extern
一、变量前加extern
关键字
对于函数有声明
和定义
两步。同样对于变量严格来说也是分声明
和定义
。定义一个变量就要为其分配内存并赋值。如果没指定值则根据变量类型赋相应的默认值。
int var1; // 相当于是 声明和定义合成为一步extern int var2; // 仅仅是声明
也就是说在变量前面如果加上了extern
关键字,对于这个变量来说只是进行了声明并没有定义。下面举几个例子进行对extern
的用法进行说明
例一
main.c
#include <stdio.h>int var1;
extern int var2;
int main()
{
var1 = 11;
var2 = 12;
printf("var1=%d; var2=%d\n",var1,var2);
return 0;
}
gcc
进行编译
$ gcc main.cUndefined symbols for architecture x86_64:
"_var2", referenced from:
_main in main-179d3c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
链接的时候没有找到变量var2
。因为var2
只是进行了声明,并没有定义,所以编译能通过,到了链接的时候就找不到了。
例二
main.c
#include <stdio.h>int var1 = 11;
extern int var2 = 12;
int main() {
printf("var1=%d; var2=%d\n",var1,var2);
return 0;
}
gcc
进行编译
$ gcc main.cmain.c:5:12: warning: 'extern' variable has an initializer [-Wextern-initializer]
extern int var2 = 12;
^
1 warning generated.
只是一个警告,程序是可以正确执行的。也就是说 extern int var2 = 12
这种方式也是对变量进行了定义,但这是不合规则的,所以给你个警告。
extern
主要是对外部变量进行引用。所以正确合规的用法举例如下
例三
math.c
int var = 12;
main.c
#include <stdio.h>extern int var;
int main()
{
printf("var = %d\n",var);
return 0;
}
gcc
进行编译
$ gcc main.c math.c
没有问题。 因为 var 变量是进行了定义的。 所以在main.c
中是可以找到var
变量的。
例四
math.c
extern int var = 12;
main.c
#include <stdio.h>extern int var;
int main()
{
printf("var = %d\n",var);
return 0;
}
gcc
进行编译
$ gcc main.c math.cstatic/math.c:61:12: warning: 'extern' variable has an initializer [-Wextern-initializer]
extern int var = 12;
^
1 warning generated.
也是可以通过的,只是多了一个警告。参照 例二
总的来说,只要是一个全局变量进行了定义。在其他文件中通过extern
关键字就可以进行引用。
二、extern
函数
函数默认都是extern
类型的。也就是说函数前面没有static
关键字修饰,那就都是extern
int add(int a, int b);// 等价于
extern int add(int a, int b);
上面关于 extern 修饰的变量,必须要是定义的全局变量,在其他文件中才能通过 extern 进行引用。 函数内定义的变量是没法被其他文件进行引用的。
本文转载自:迹忆客(https://www.jiyik.com)
以上是 详细了解 static 和 extern 关键字的用法 的全部内容, 来源链接: utcz.com/z/290174.html