static 关键词的使用

来源:互联网 发布:淘宝购物评级一颗星 编辑:程序博客网 时间:2024/06/05 17:09


static 关键词的使用

2.1  什么叫函数重复定义

我们经常会遇到报错,说变量或者函数重复定义。那么,在此,首先我举例说明一下什么叫函数的重复定义。

  1. //a.c文件 
  2.  
  3. void test() 
  4.     return
  5.  
  6. //b.c文件 
  7.  
  8. void test() 
  9.     return

那么,在编译的时候是不会报错的,但是,在链接的时候,会出现报错:

multiple definition of `test',因为在同一个工程里面出现了两个test函数的定义。

用static修饰函数,则表明该函数只能在本文件中使用,因此,当不同的文件中有相同的函数名被static修饰时,不会产生重复定义的报错。例如:

  1. //a.c文件 
  2.  
  3. static void test() 
  4.     return
  5.  
  6. void test_a() 
  7.     test(); 
  8.  
  9. //b.c文件 
  10.  
  11. static void test() 
  12.     return
  13.  
  14. void test_b() 
  15.     test(); 

编译工程时不会报错,但是test()函数只能被 a.c 和 b.c 中的函数调用,不能被 c.c 等其他文件中的函数调用。

那么,用static修饰 .h 文件中定义的函数,会有什么效果呢?

  1. //a.h文件 
  2.  
  3. static void test() 
  4.     return
  5.  
  6. //b.c文件 
  7.  
  8. #include "a.h" 
  9.  
  10. void test_b() 
  11.     test(); 
  12.  
  13. //c.c文件 
  14.  
  15. #include "a.h" 
  16.  
  17. void test_c() 
  18.     test(); 

这样的话,在预编译后,b.c 和 c.c 文件中,由于 #include "a.h" ,故在这两个文件开头都会定义 static void test() 函数,因此,test_b() 和 test_c() 均调用的是自己文件中的 static void test() 函数 , 因此不会产生重复定义的报错。

因此,结论,在 .h 文件中定义函数的话,建议一定要加上 static 关键词修饰,这样,在被多个文件包含时,才不会产生重复定义的错误。

  1. //a.h文件 
  2.  
  3. static void test_a() 
  4.     return
  5.  
  6. //b.h文件 
  7.  
  8. #include "a.h" 
  9.  
  10. //c.h文件 
  11.  
  12. #include "a.h" 
  13.  
  14. //main.c文件 
  15.  
  16. #include "b.h" 
  17. #include "c.h" 
  18.  
  19. void main() 
  20.     test_a(); 

这样就“不小心”产生问题了,因为 b.h 和 c.h 都包含了 a.h,那么,在预编译main.c 文件的时候,会展开为如下形式:

  1. //main.c 预编译之后的临时文件 
  2.  
  3. static void test_a() 
  4.     return
  5.  
  6. static void test_a() 
  7.     return
  8.  
  9. void main() 
  10.     test_a(); 

在同一个 .c 里面,出现了两次 test_a() 的定义,因此,会出现重复定义的报错。

但是,如果在 a.h 里面加上了 #ifndef……#define……#endif 的话,就不会出现这个问题了。

例如,上面的 a.h 改为:

  1. //a.h 文件 
  2.  
  3. #ifndef  A_H 
  4. #define A_H 
  5.  
  6. static void test_a() 
  7.     return
  8.  
  9. #endif 

预编译展开main.c则会出现:

  1. //main.c 预编译后的临时文件 
  2.  
  3. #ifndef A_H 
  4. #define A_H 
  5.  
  6. static void test_a() 
  7.     return
  8.  
  9. #endif 
  10.  
  11. #ifndef A_H 
  12. #define A_H 
  13.  
  14. static void test_a() 
  15.     return
  16.  
  17. #endif 
  18.  
  19. void main() 
  20.     test_a(); 

在编译main.c时,当遇到第二个 #ifndef  A_H ,由于前面已经定义过 A_H,故此段代码被跳过不编译,因此,不会产生重复定义的报错。这就是  #ifndef……#define……#endif 的精髓所在。

0 0
原创粉丝点击