C语言中static的使用

C语言作为当今使用最多的编程语言之一,无论是计算机编程还是单片机编程都占据着重要的地位。C语言中一共有32个关键字,其中static作为最常见使用最多的关键字之一,只有充分理解其使用方法与作用才能在编程中灵活运用,提高代码的执行效率与阅读性。一个完成的C语言项目主要由数据+程序组成。其中数据的主要表现形式为变量,程序的主要表现形式为函数,static可以对变量与函数进行修饰。

1. 修饰函数

static修饰函数主要是限定函数的作用域一个C语言项目往往有多个C文件构成,有时我们希望一个文件中的某些特殊方法只限于在本文件中使用不能在其他文件中被调用又或者在不同文件中存在函数名相同的函数,如果不限定函数的作用域,程序编译过程中就会报错。当遇到这两种情况时,我们可以使用static进行修饰,限定函数的作用域为函数所在文件。使用VC++6.0测试如下:

test.c文件:

 
  
  1: #include "test.h" 
  2: 
  3: void static printf1(void) 
  4: { 
  5:     printf("hello word"); 
  6: } 
  7: 
  8: void printf2(void) 
  9: { 
 10:     printf1(); 
 11: }
 
  

test.h文件

 
  
  1: #include <stdio.h>
  2: 
  3: void static printf1(void);
  4: void printf2(void);
 
  

main.c文件

 
  
  1: #include "test.h"
  2: 
  3: int main(void)
  4: {
  5:      printf1();
  6:      printf2();
  7:      return 0;
  8: }

编译工程此时项目报错:

Compiling...

main.c

C:\Users\lzhitwh\Desktop\CTest\Test\main.c(9) : error C2129: static function 'void __cdecl printf1(void )' declared but not defined 
       c:\users\lzhitwh\desktop\ctest\test\test.h(3) : see declaration of 'printf1'

执行 cl.exe 时出错.

Test.exe - 1 error(s), 0 warning(s)

根据错误信息可知,造成错误的原因是main.c文件的第9行中printf1()函数没有被定义。在mian.c文件中注释掉printf1();函数时,工程能正常编译。说明没有被static修饰的printf2()函数作用域是整个项目,可以被其他源文件中的函数调用。而被static修饰的printf1()函数的作用域是其所在文件,无法被其他源文件中的函数调用。

2.修饰变量

static修饰变量分为两种情况:

  • 修饰全局变量
  • 修饰局部变量
修饰全局变量

被static修饰的全局变量被称为静态全局变量,static修饰全局变量与修饰函数的作用相同,限定变量的的作用域。静态全局变量与不被修饰的全局变量唯一区别为作用域不同。被static修饰的全局变量作用于定义变量的文件,不被static修饰的全局变量则作用于整个C语言项目。可以限定某些变量不被外部函数改变,提高程序的安全性。

修饰局部变量

被static修饰的局部变量被称为静态局部变量,与局部变量有较大的差异。主要包括以下几个方面:

  • 生命周期:静态局部变量存在于程序整个生命周期,而局部变量只存在于函数的某一时期。静态局部变量的生命周期不会随着定义他的函数的生命周期发生变化。
  • 作用域:虽然静态局部变量存在于程序的整个生命周期,但是其作用域与局部变量的作用域相同,无法在定义变量的函数外部使用。
  • 存储空间:静态局部变量存储空间与局部变量存储空间不同。局部变量随着函数执行被定义和初始化,其空间被分配到栈或堆中,而静态局部变量则分配到全局存储区,在程序编译时就被分配好。
  • 值:静态局部变量如果没有人为初始化,编译器会默认初始化为0。静态局部变量初始化过程是在编译阶段完成,程序运行过程中不在进行初始化,每次读取变量值时都是获取上次改变的值。 值的差异是static修饰局部变量区别的重点。

注:想要充分理解静态局部变量与布局变量在存储空间与值的差异,需要具有一定的C语言段的知识。

局部变量程序示例,主要说明值的差异。Test.c文件:

 
  
  1: #include <stdio.h>
  2: 
  3: void Test()
  4: {
  5: 	static int a;
  6: 	static int b=0;
  7: 	int c=0;
  8: 
  9: 	printf("a=%d; &a=%d \r\n",a++,&a);
 10: 	printf("b=%d; &b=%d \r\n",b++,&b);
 11: 	printf("c=%d; &c=%d \r\n",c++,&c);
 12: }
 13: 
 14: int main(void)
 15: {
 16: 	Test();
 17: 	printf("-------------- \r\n");
 18: 	Test();
 19: 	getchar();
 20: 	return 0;
 21: }

运行结果如下:

BZNOQR`6{FV`K}L1Z9KPUH1

其中:a与b第一次结果相同,说明a与b都被初始化了相同的初始值0,而两次执行过程中a和b的地址都没有变化,说明其存储空间固定。而a第二次执行结果与第一次不同,说明静态局部变量没有在函数第二次执行时初始化。使用的是上一次改变的值。c两次的值都是0,且地址不同,说明函数每执行一次函数,就要重新分配地址空间,并初始化话变量。

总结:C/C++中,static修饰全局变量和函数作用是限制其作用域,被static修饰的函数与全局变量只能在被定义文件中被使用,有利于挺高代码安全性,防止全局变量被意外修改,函数被错误执行。static修饰局部变量则会造成局部变量的生命周期(由程序中的某一时期变为程序整个生命周期)、存储空间(由存在于栈或者堆变为全局存储区的.data区)、值的不同(默认初始化为0),可以使用静态局部变量实现同一函数的数据共享。

猜你喜欢

转载自blog.csdn.net/lzhitwh/article/details/73290188