论证在C头文件中定义的变量的奥秘

简介: function.h #ifndef _FUNCTION_H_ #define _FUNCTION_H_ void test_extern1_print(); void test_extern2_print(); #endif header.
function.h
  1. #ifndef _FUNCTION_H_
  2. #define _FUNCTION_H_


  3. void test_extern1_print();
  4. void test_extern2_print();

  5. #endif
header.h
  1. #ifndef _HEADDER_H_
  2. #define _HEADDER_H_

  3. extern int test_extern1_val;
  4. extern int test_extern2_val;
  5. static int tmp_vale = 3;

  6. #endif
 
test_extern1.c
  1. #include stdio.h>
  2. #include "header.h"

  3. int test_extern1_val = 1;

  4. void test_extern1_print()
  5. {
  6.     printf("In test_extern1.c:\n");
  7.     printf("______________________________________________________________________________________________\n");
  8.     printf("| test_extern1_val | address | test_extern2_val | address | tmp_vale | address |\n");
  9.     printf("______________________________________________________________________________________________\n");
  10.     printf("| %d | %p | %d | %p | %d | %p |\n",\
  11.            test_extern1_val,&test_extern1_val,test_extern2_val,&test_extern2_val,tmp_vale,&tmp_vale);
  12.     printf("______________________________________________________________________________________________\n");
  13. }
 
test_extern2.c
  1. #include stdio.h>
  2. #include "header.h"

  3. int test_extern2_val = 2;

  4. void test_extern2_print()
  5. {
  6.     printf("In test_extern2.c:\n");
  7.     printf("______________________________________________________________________________________________\n");
  8.     printf("| test_extern1_val | address | test_extern2_val | address | tmp_vale | address |\n");
  9.     printf("______________________________________________________________________________________________\n");
  10.     printf("| %d | %p | %d | %p | %d | %p |\n",\
  11.            test_extern1_val,&test_extern1_val,test_extern2_val,&test_extern2_val,tmp_vale,&tmp_vale);
  12.     printf("______________________________________________________________________________________________\n");
  13. }
 
main.c
  1. #include stdio.h>
  2. #include stdlib.h>
  3. #include "founctions.h"
  4. #include "header.h"


  5. int main()
  6. {
  7.     system("clear");
  8.     printf("\n\n****************************************** Head *****************************************\n\n");
  9.     test_extern1_print();
  10.     printf("\n\n");
  11.     test_extern2_print();
  12.     printf("\n\n");
  13.     printf("In main.c:\n");
  14.     printf("______________________________________________________________________________________________\n");
  15.     printf("| test_extern1_val | address | test_extern2_val | address | tmp_vale | address |\n");
  16.     printf("______________________________________________________________________________________________\n");
  17.     printf("| %d | %p | %d | %p | %d | %p |\n",\
  18.            test_extern1_val,&test_extern1_val,test_extern2_val,&test_extern2_val,tmp_vale,&tmp_vale);
  19.     printf("______________________________________________________________________________________________\n");
  20.     printf("\n\n");
  21.     printf("\n\n****************************************** Tail *****************************************\n\n");
  22.     return 0;
  23. }
Makefile
  1. o_file := test_extern1.o test_extern2.o

  2. all: main
  3. main : main.o $(o_file)
  4.     $(CC) main.o $(o_file) -o main

  5. clean:
  6.     rm -rvf ./*.o main
 
编译效果:
  1. ****************************************** Head *****************************************

  2. In test_extern1.c:
  3. ______________________________________________________________________________________
  4. | test_extern1_val | address   | test_extern2_val | address   | tmp_vale | address   |
  5. ______________________________________________________________________________________
  6. |          1       | 0x8049ca0 |          2       | 0x8049ca8 |      3   | 0x8049c9c |
  7. ______________________________________________________________________________________


  8. In test_extern2.c:
  9. ______________________________________________________________________________________
  10. | test_extern1_val | address   | test_extern2_val | address   | tmp_vale | address   |
  11. ______________________________________________________________________________________
  12. |          1       | 0x8049ca0 |          2       | 0x8049ca8 |      3   | 0x8049ca4 |
  13. ______________________________________________________________________________________


  14. In main.c:
  15. ______________________________________________________________________________________
  16. | test_extern1_val | address  | test_extern2_val | address   | tmp_vale | address   |
  17. ______________________________________________________________________________________
  18. |          1       |0x8049ca0 |          2       | 0x8049ca8 |      3   | 0x8049c98 |
  19. ______________________________________________________________________________________




  20. ****************************************** Tail *****************************************

  21. [root@localhost test_extern]#
 上面注意到,tmp_vale值虽然一样,但是地址是不一样的。
  所以,在头文件中定义static变量,代码中好像使用了相同的变量,但是实际上使用的是不同的变量,在每个源文件中都有单独的变量。会造成变量多次定义,造成内存空间的浪费,而且也不是真正的全局变量。应该避免使用这种定义方式
相关文章
|
7月前
|
Java Spring
使用枚举定义常量更好点儿
使用枚举定义常量更好点儿
|
2月前
|
编译器 C语言
C语言常见编译错误分类及其解决方案
C语言常见编译错误分类及其解决方案
199 1
C语言常见编译错误分类及其解决方案
|
编译器 C语言
【C语言航路外传】如何隐藏代码及声明和定义的在工程中真正的使用场景
【C语言航路外传】如何隐藏代码及声明和定义的在工程中真正的使用场景
128 1
|
6月前
|
编译器 C语言 C++
【海贼王编程冒险 - C语言海上篇】自定义类型:结构体,枚举,联合怎样定义?如何使用?
【海贼王编程冒险 - C语言海上篇】自定义类型:结构体,枚举,联合怎样定义?如何使用?
37 0
|
存储 C语言
C语言深度解剖-关键字(4)
C语言深度解剖-关键字(4)
76 0
|
C语言
C语言深度解剖-关键字(2)
C语言深度解剖-关键字(2)
74 0
|
C语言 C++
C语言深度解剖-关键字(5)
C语言深度解剖-关键字(5)
74 0
|
存储 编译器 C语言
C语言深度解剖-关键字(1)
C语言深度解剖-关键字(1)
62 0
|
存储 C语言
C语言深度解剖-关键字(3)
C语言深度解剖-关键字(3)
73 0
|
C语言
C语言深度解剖-关键字(7)
C语言深度解剖-关键字(7)
68 0