当前位置:首页 > 健康 >

static关键字有哪些作用(static关键字的作用)

来源:原点资讯(www.yd166.com)时间:2022-11-25 14:19:59作者:YD166手机阅读>>

C语言代码是以文件为单位来组织的,在一个源程序的所有源文件中,一个外部变量(注意不是局部变量)或者函数只能在一个源程序中定义一次,如果有重复定义的话编译器就会报错。伴随着不同源文件变量和函数之间的相互引用以及相互独立的关系,产生了extern和static关键字。

下面,详细分析一下static关键字在编写程序时有的三大类用法:

一,static全局变量

我们知道,一个进程在内存中的布局如图1所示:

static关键字有哪些作用,static关键字的作用(1)

其中.text段保存进程所执行的程序二进制文件,.data段保存进程所有的已初始化的全局变量,.bss段保存进程未初始化的全局变量(其他段中还有很多乱七八糟的段,暂且不表)。在进程的整个生命周期中,.data段和.bss段内的数据时跟整个进程同生共死的,也就是在进程结束之后这些数据才会寿终就寝。

当一个进程的全局变量被声明为static之后,它的中文名叫静态全局变量。静态全局变量和其他的全局变量的存储地点并没有区别,都是在.data段(已初始化)或者.bss段(未初始化)内,但是它只在定义它的源文件内有效,其他源文件无法访问它。所以,普通全局变量穿上static外衣后,它就变成了新娘,已心有所属,只能被定义它的源文件(新郎)中的变量或函数访问。

static关键字有哪些作用,static关键字的作用(2)

以下是一些示例程序

file1.h如下:

#include <stdio.h> void printStr();

我们在file1.c中定义一个静态全局变量hello, 供file1.c中的函数printStr访问.

#include "file1.h" static char* hello = "hello cobing!"; void printStr() { printf("%s\n", hello); }

file2.c是我们的主程序所在文件,file2.c中如果引用hello会编译出错

#include "file1.h" int main() { printStr(); printf("%s\n", hello); return 0; }

报错如下:

[liujx@server235 static]$ gcc -Wall file2.c file1.c -o file2

file2.c: In function ‘main’:

file2.c:6: 错误:‘hello’ 未声明 (在此函数内第一次使用)

file2.c:6: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其

file2.c:6: 错误:所在的函数内只报告一次。)

如果我们将file2.c改为下面的形式:

#include "file1.h" int main() { printStr(); return 0; }

则会顺利编译连接。

运行程序后的结果如下:

[liujx@server235 static]$ gcc -Wall file2.c file1.c -o file2 [liujx@server235 static]$ ./file2 hello cobing!

上面的例子中,file1.c中的hello就是一个静态全局变量,它可以被同一文件中的printStr调用,但是不能被不同源文件中的file2.c调用。

二,static局部变量

普通的局部变量在栈空间上分配,这个局部变量所在的函数被多次调用时,每次调用这个局部变量在栈上的位置都不一定相同。局部变量也可以在堆上动态分配,但是记得使用完这个堆空间后要释放之。

static局部变量中文名叫静态局部变量。它与普通的局部变量比起来有如下几个区别:

1)位置:静态局部变量被编译器放在全局存储区.data(注意:不在.bss段内,原因见3)),所以它虽然是局部的,但是在程序的整个生命周期中存在。

2)访问权限:静态局部变量只能被其作用域内的变量或函数访问。也就是说虽然它会在程序的整个生命周期中存在,由于它是static的,它不能被其他的函数和源文件访问。

3)值:静态局部变量如果没有被用户初始化,则会被编译器自动赋值为0,以后每次调用静态局部变量的时候都用上次调用后的值。这个比较好理解,每次函数调用静态局部变量的时候都修改它然后离开,下次读的时候从全局存储区读出的静态局部变量就是上次修改后的值。

以下是一些示例程序:

file1.h的内容和上例中的相同,file1.c的内容如下:

#include "file1.h" void printStr() { int normal = 0; static int stat = 0; //this is a static local var printf("normal = %d ---- stat = %d\n",normal, stat); normal ; stat ; }

为了便于比较,我定义了两个变量:普通局部变量normal和静态局部变量stat,它们都被赋予初值0;

file2.c中调用file1.h:

#include "file1.h" int main() { printStr(); printStr(); printStr(); printStr(); printf("call stat in main: %d\n",stat); return 0; }

这个调用会报错,因为file2.c中引用了file1.c中的静态局部变量stat,如下:

[liujx@server235 static]$ gcc -Wall file2.c file1.c -o file2

file2.c: In function ‘main’:

file2.c:9: 错误:‘stat’ 未声明 (在此函数内第一次使用)

file2.c:9: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其

file2.c:9: 错误:所在的函数内只报告一次。)

编译器说stat未声明,这是因为它看不到file1.c中的stat,下面注掉这一行:

#include "file1.h" int main() { printStr(); printStr(); printStr(); printStr(); // printf("call stat in main: %d\n",stat); return 0; } [liujx@server235 static]$ gcc -Wall file2.c file1.c -o file2 [liujx@server235 static]$ ./file2 normal = 0 ---- stat = 0 normal = 0 ---- stat = 1 normal = 0 ---- stat = 2 normal = 0 ---- stat = 3

运行如上所示。可以看出,函数每次被调用,普通局部变量都是重新分配,而静态局部变量保持上次调用的值不变。

需要注意的是由于static局部变量的这种特性,使得含静态局部变量的函数变得不可重入,即每次调用可能会产生不同的结果。这在多线程编程时可能会成为一种隐患。需要多加注意。

static关键字有哪些作用,static关键字的作用(3)

三,static函数

相信大家还记得C 面向对象编程中的private函数,私有函数只有该类的成员变量或成员函数可以访问。在C语言中,也有“private函数”,它就是接下来要说的static函数,完成面向对象编程中private函数的功能。

当你的程序中有很多个源文件的时候,你肯定会让某个源文件只提供一些外界需要的接口,其他的函数可能是为了实现这些接口而编写,这些其他的函数你可能并不希望被外界(非本源文件)所看到,这时候就可以用static修饰这些“其他的函数”。

所以static函数的作用域是本源文件,把它想象为面向对象中的private函数就可以了。

下面是一些示例:

file1.h如下:

#include <stdio.h> static int called(); void printStr();

file1.c如下:

#include "file1.h" static int called() { return 6; } void printStr() { int returnVal; returnVal = called(); printf("returnVal=%d\n",returnVal); }

file2.c中调用file1.h中声明的两个函数,此处我们故意调用called():

#include "file1.h" int main() { int val; val = called(); printStr(); return 0; }

编译时会报错:

[liujx@server235 static]$ gcc -Wall file2.c file1.c -o file2

file1.h:3: 警告:‘called’ 使用过但从未定义

/tmp/ccyLuBZU.o: In function `main':

file2.c:(.text 0x12): undefined reference to `called'

collect2: ld 返回 1

因为引用了file1.h中的static函数,所以file2.c中提示找不到这个函数:undefined reference to 'called'

下面修改file2.c:

#include "file1.h" int main() { printStr(); return 0; }

编译运行:

[liujx@server235 static]$ gcc -Wall file2.c file1.c -o file2 [liujx@server235 static]$ ./file2 returnVal=6

static函数可以很好地解决不同原文件中函数同名的问题,因为一个源文件对于其他源文件中的static函数是不可见的

栏目热文

static的用途(c语言中static的作用)

static的用途(c语言中static的作用)

根据疫情管控级别及管控严格程度,由低到高依次分为:静态管理<静态管控<封城。什么是静态管理除了医院、药店、生...

2022-11-25 14:05:40查看全文 >>

static修饰的是声明还是定义(static修饰函数的意义)

static修饰的是声明还是定义(static修饰函数的意义)

static关键字含义1. 为什么要使用static有一些数据不必要隶属于每个对象, 例如Chinese类的countr...

2022-11-25 14:36:25查看全文 >>

static修饰类有啥用(static如何修饰类)

static修饰类有啥用(static如何修饰类)

static关键字的含义及使用场景static是Java50个关键字之一。static关键字可以用来修饰代码块表示静态代...

2022-11-25 14:25:04查看全文 >>

static的三个作用(什么时候用static方法)

static的三个作用(什么时候用static方法)

一、static代表着什么在Java中并不存在全局变量的概念,但是我们可以通过static来实现一个“伪全局”的概念,在...

2022-11-25 14:36:49查看全文 >>

clothes英语怎么说(clothes的英语正确发音)

clothes英语怎么说(clothes的英语正确发音)

今天分享一篇阅读理解。可以学习衣服的话题时进行同步阅读,也可以作为日常的阅读材料。每日10分钟英语阅读,养成习惯,孩子的...

2022-11-25 14:07:51查看全文 >>

static关键字的作用(c语言static关键字的作用)

static关键字的作用(c语言static关键字的作用)

前言之前讲到final关键字的作用是每次面试的时候我必问求职者的两个问题之一,另外一个问题就是文本会写到的static。...

2022-11-25 14:04:37查看全文 >>

c语言static关键字的作用(c语言static关键字作用)

c语言static关键字的作用(c语言static关键字作用)

嵌入式开发,离不开 C 语言,C语言中有很多语法会直接或间接影响你代码的质量,下面就来讲讲__attribute__ 关...

2022-11-25 14:01:35查看全文 >>

static用法(static的简单用法)

static用法(static的简单用法)

C中 static 的用法C语言中,根据 static 的使用位置可以分为两种:1、修饰函数内部的变量即函数内的静态变量...

2022-11-25 14:16:23查看全文 >>

static 的用途(static怎么使用)

static 的用途(static怎么使用)

1) 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。2) 在模块内(但在函数体外),一个被声明为静...

2022-11-25 14:47:44查看全文 >>

c语言static用法(c 语言static)

c语言static用法(c 语言static)

static静态变量C语言提供了static关键字来修饰变量的定义,static关键字修饰的变量称为:静态变量;该关键字...

2022-11-25 14:07:06查看全文 >>

文档排行