论证在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变量,代码中好像使用了相同的变量,但是实际上使用的是不同的变量,在每个源文件中都有单独的变量。会造成变量多次定义,造成内存空间的浪费,而且也不是真正的全局变量。应该避免使用这种定义方式
相关文章
|
1月前
|
Java Spring
使用枚举定义常量更好点儿
使用枚举定义常量更好点儿
14 1
|
1月前
|
算法 Serverless 数据安全/隐私保护
【C++ 函数 基本教程 第三篇 】深度解析C++函数类型:探寻全局函数、成员函数与静态函数的奥秘
【C++ 函数 基本教程 第三篇 】深度解析C++函数类型:探寻全局函数、成员函数与静态函数的奥秘
40 1
|
5月前
|
编译器 C语言
【C语言航路外传】如何隐藏代码及声明和定义的在工程中真正的使用场景
【C语言航路外传】如何隐藏代码及声明和定义的在工程中真正的使用场景
59 1
|
10月前
|
存储 算法 编译器
抽丝剥茧C语言(高阶)结构体,枚举,联合+练习
抽丝剥茧C语言(高阶)结构体,枚举,联合+练习
|
11月前
|
存储 Java 编译器
【C语言】关于我回头学的那些预处理等(五)(重点)
我的第一门语言就是C,但是学艺不精,中途跑去学了C#和Java后,感觉到了C的重要性,毕竟是最接近底层的语言,又跑回来学C。 毕竟前两门的控制语句,变量什么的都是类似的,回到C后只需要学习一些特定C的语法,比如宏,预编译指令等等,这些对我来说都是陌生的词汇。 所以边学边记录一下以前的知识。
101 0
|
测试技术 Java Scala