问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C语言中的static与extern关键字详解

创作时间:
作者:
@小白创作中心

C语言中的static与extern关键字详解

引用
CSDN
1.
https://m.blog.csdn.net/Annaka918/article/details/143817523

在讲解 staticextern 关键字之前,要先了解两个重要概念:作用域生命周期

作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效(可用)的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

通俗的说,一个变量在哪里可以使用,哪里就是它的作用域。

1.局部变量的作用域就是变量所在的局部范围。

2.全局变量的作用域是整个工程(项目)。

生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的一个时间段。

1.局部变量的生命周期是:进入作用域变量创建,生命周期开始,出作用域生命周期结束。

2.全局变量的生命周期是:整个程序的生命周期。

标题

了解了以上概念之后,接下来我们将正式开始 static 和 extern 关键字的学习。

在C语言中,**static****extern**是两个非常重要的关键字,它们用于控制变量和函数的链接属性和生命周期。下面我将详细解释这两个关键字:

1.static 关键字

**static**关键字可以用来修饰变量和函数,它有以下几个用途:

局部静态变量:

• 当**static**用于函数内部的局部变量时,它会改变变量的生命周期。没有static的局部变量在函数调用结束后会被销毁,而加了**static**的局部变量会保持其值,直到程序结束。

• 例如:

void func() 
{
    static int count = 0; // 局部静态变量
    count++;
    printf("%d\n", count);
}

每次调用**func**时,**count**的值都会累加。

结论:static修饰局部变量改变了变量的生命周期,生命周期改变的本质是改变了变量的存储类型,本来一个局部变量是存储在内存的栈区的,但是被 static 修饰后存储到了静态区。存储在静态区的变量和全局变量是⼀样的,生命周期就和程序的生命周期⼀样了,只有程序结束,变量才销毁,内存才回收。但是作用域是不变的。

全局静态变量:

• 当**static**用于全局变量时,它会限制变量的链接属性,使得变量只在定义它的文件内可见,即具有文件内链接(file scope linkage),而不是外部链接(external linkage)。

• 例如:

// file1.c
static int global_var = 10; // 只在 file1.c 可见
// file2.c
extern int global_var; // 错误:无法访问,因为 global_var 只在 file1.c 可见

全局变量默认是具有外部链接属性的,可以在适当的声明后跨文件使用。

不过一旦被static修饰,就使得这个全局变量的外部链接属性变成内部链接属性。在外部的源文件中就无法直接使用了,只能在自己所在的 源文件 中使用。 相当于改变了全局变量的作用域,但是没有改变其生命周期。

使用建议:如果一个全局变量,只想在所在的源文件内部使用,不想被其他文件发现,就可以使用static修饰。

静态函数:

正常使用来自外部的函数时,只需要进行正确的声明便可正常使用。

• 当**static**用于函数时,与修饰全局静态变量同理,它会限制函数的链接属性,使得函数只在定义它的文件内可见,从而不能在其他文件中正常的链接使用了。

• 例如:

// file1.c
static void func() 
{
    // ...
}
// file2.c
void func(); // 错误:无法访问,因为 func 只在 file1.c 可见

使用建议:一个函数只想在所在的源文件内部使用,不想被其他的源文件使用,就可以使用 static 修饰。

2.extern 关键字

**extern**关键字用于声明全局变量或函数(外部符号),它有以下几个用途:

声明全局变量:

**extern**用于在多个文件中共享全局变量。它告诉编译器该变量在其他地方定义。

• 例如:

// file1.c
int global_var = 10; // 定义全局变量
// file2.c
extern int global_var; // 声明全局变量,告诉编译器在其他地方定义
printf("%d\n", global_var); // 可以访问 global_var

声明函数:

**extern**也用于在多个文件中共享函数。如果一个函数在一个文件中定义,并在其他文件中使用,那么在其他文件中需要用**extern**来声明这个函数。

• 例如:

// file1.c
void func() 
{
    // ...
}
// file2.c
extern void func(); // 声明 func 函数,告诉编译器在其他地方定义
func(); // 可以调用 func 函数

3.总结

**static**用于控制变量和函数的生命周期和链接属性,使其具有文件内链接。

**extern**用于在多个文件中共享全局变量和函数,使其具有外部链接。

如果一个变量或函数同时被声明为 staticextern ,那么 static 的链接属性会覆盖 extern 的链接属性,这意味着该变量或函数将只在定义它的文件内部可见,即使它被声明为 extern 。这种组合通常用于头文件中,以防止同一个头文件被多次包含时造成重复定义的问题。

这两个关键字在C语言中非常重要,正确使用它们可以有效地管理程序的内存和链接属性。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号