Why does C language generally not define functions or variables in .h? (Essence)

1. The role of the header file

Most C programming enthusiasts know that in our .h files, we often see function declarations, variable declarations, and various macros, etc., and I also mentioned in my previous article In the modular design of C language, it is often said that the corresponding .h and .c files are considered as an object, then the .h file is mainly some external interfaces, some private data and other implementations will be encapsulated in our .c , if we explain our .h more vividly, it is equivalent to the box composed of recommended article links under the article, click in and you will arrive at the corresponding specific article, and the specific article is our .c file.

Come back to our program here, as shown in the following code:

  1. #include <stdio.h>

  2. #include <stdlib.h>

  3. int sAdd(int a,int b);

  4. int sSub(int a,int b);

  5. //...

  6. int main(int argc, char *argv[]) {

  7. printf("Add: %d\n",sAdd(1 , 1));

  8. printf("Sub: %d\n",sSub(1 , 1));

  9. printf("公众号:最后一个bug\n");

  10. return 0;

  11. }

  12. /***************************************

  13. * Fuction:sAdd

  14. * Author : (公众号:最后一个bug)

  15. ***************************************/

  16. int sAdd(int a,int b)

  17. {

  18. return (a + b);

  19. }

  20. /***************************************

  21. * Fuction:sSub

  22. * Author : (公众号:最后一个bug)

  23. ***************************************/

  24. int sSub(int a,int b)

  25. {

  26. return (a - b);

  27. }

  28. //...

Let’s analyze it:  the above is what most friends do when they first learn programming, then we put the declaration in front of the main function into a corresponding .h file, and put the specific implementation of addition and subtraction into the corresponding .c file, and then Use #include "xxx.h" in front of the main function, that's all. To put it simply, .h can be expanded directly at #include so that we can understand and analyze it.

2. Define functions or variables in the header file

Friends who read a lot of code should have seen the practice of defining functions or variables directly in the header file, so here we directly modify the above to get the following code:

  1. //Filename: main.c

  2. #include <stdio.h>

  3. #include <stdlib.h>

  4. #include "Add.h"

  5. int main(int argc, char *argv[]) {

  6. printf("Add: %d\n",sAdd(global_Var1 , global_Var2));

  7. printf("Sub: %d\n",sSub(global_Var1 , global_Var2));

  8. printf("公众号:最后一个bug\n");

  9. return 0;

  10. }

 
  
  1. //Filename : Add.h

  2. /***************************************

  3. * Fuction:sAdd

  4. * Author : (公众号:最后一个bug)

  5. ***************************************/

  6. int global_Var1 = 2;

  7. int global_Var2 = 2;

  8. /***************************************

  9. * Fuction:sAdd

  10. * Author : (公众号:最后一个bug)

  11. ***************************************/

  12. int sAdd(int a,int b)

  13. {

  14. return (a + b);

  15. }

  16. /***************************************

  17. * Fuction:sSub

  18. * Author : (公众号:最后一个bug)

  19. ***************************************/

  20. int sSub(int a,int b)

  21. {

  22. return (a - b);

  23. }

 

Let's analyze it: the above program can also be compiled and run successfully, and the correct result can be obtained, which further proves that it is understandable to directly expand #include "xxx.h".

3. Why not choose to define variables or functions in the header file

1) Multiple source file declarations.h will be defined repeatedly 

If we explain it according to the above expansion method, it is actually easy to understand that multiple source file declarations #include "xxx.h" will result in multiple identical global variables and functions, which will inevitably lead to repeated definition failures. If you don’t believe me Type the code directly to see the result:

 

 
  
  1. #include <stdio.h>

  2. #include <stdlib.h>

  3. #include "APP1.h"

  4. #include "APP2.h"

  5. /*********************************************

  6. * Fuction:main

  7. * Author : (公众号:最后一个bug)

  8. ********************************************/

  9. int main(int argc, char *argv[]) {

  10. printf("%d\n",add_APP1(1,1));

  11. printf("%d\n",add_APP2(1,1));

  12. return 0;

  13. }

 
  
  1. //Filename:Add.h

  2. /*********************************************

  3. * Fuction:add

  4. * Author : (公众号:最后一个bug)

  5. ********************************************/

  6. int add(int a,int b)

  7. {

  8. return (a + b);

  9. }

 
  
  1. //Filename:App1.h

  2. int add_APP1(int a,int b);

 
  
  1. //Filename:App1.c

  2. #include "Add.h"

  3. /*********************************************

  4. * Fuction:add_APP1

  5. * Author : (公众号:最后一个bug)

  6. ********************************************/

  7. int add_APP1(int a,int b)

  8. {

  9. return add(a,b);

  10. }

 

 

Analysis: I will not paste the .c and .h corresponding to APP2, after all, the code is relatively simple. The last picture is the compilation result, and the second line shows that the add function is repeatedly defined. Similarly, the author also performed the same method for variables, and it also showed repeated definitions of related variables, so it also verified our previous theory.

2) Add conditional compilation #ifndef 

Most of our friends may think that we can directly add conditional compilation #ifndef to the function and variable definitions of the header file to avoid repeated inclusion? Well, the author also conducted this experiment. Let’s take a look at the code and results. , I will explain later:

  1. //Filename:Add.h

  2. /*********************************************

  3. * Fuction:add

  4. * Author : (公众号:最后一个bug)

  5. ********************************************/

  6. #ifndef __ADD_H__

  7. #define __ADD_H__

  8. int add(int a,int b)

  9. {

  10. return (a + b);

  11. }

  12. #endif

 

Let's analyze it: After adding the precompiler, the result is consistent with the result in the previous section, and it still prompts to define the function repeatedly. Why is that? I described a generation process from C program to machine code in the previous "Embedded Programming - C Language (1)". App1.c and App2.c are compiled separately, and then #include are expanded separately , a function and variable with the same name was found in the final linking process, so the compilation will still fail.

3) static can help us get rid of this dilemma 

We all know that static means static, and it can also be said to restrict the text of variables and functions. There can be static functions and variables with the same name in multiple files, but they represent different functions and variables. Pay special attention to this point. If the header file uses a large number of variables and functions in different files, it will also cause the increase of the program and the increase of memory. The following author will use the program to prove these points:

 
  
  1. //Filename:Add.h

  2. #ifndef __ADD_H__

  3. #define __ADD_H__

  4. static int add(int a,int b)

  5. {

  6. return (a + b);

  7. }

  8. #endif

 
  
  1. //filename:App1.c

  2. #include <stdio.h>

  3. #include "Add.h"

  4. /*********************************************

  5. * Fuction:add_APP1

  6. * Author : (公众号:最后一个bug)

  7. ********************************************/

  8. int add_APP1(int a,int b)

  9. {

  10. printf("add_APP1_addFuc:0x%x\n",(int*)add);

  11. return add(a,b);

  12. }

 

 Let’s analyze it: only two important paragraphs are posted above, and the code is relatively simple. We found that both of them call add, but their addresses are different, indicating that they are not a function. So you can also divide the Add.h file into a .c and a .h form with our modular design idea, and the final printed address is the same, so I won’t post the code for you to see the result. The address is the same, which means that they are the same function. Similarly, everyone can modify variables with static, and get similar results.

 

4. Section

In the last section, in fact, there are many reasons why people generally do not define variables or functions in .h files. The most important one is that they do not meet the relevant design requirements. For example, if the code is changed, the compilation will cause a chain reaction and cause the compilation time to restart. There are problems such as long compilation time, and the analysis of the code is more troublesome, so you can actually study this kind of problem in your spare time, and you will gain a lot of unexpected knowledge points in it. Know why", in fact, defining functions or variables in the header file is not without such design requirements. You can consider that the use of static defined in the header file has disadvantages, and will there be any advantages? Haha, here I am I won’t reveal the secret, please listen to the next chapter to break it down!


Resource exchange and gain attention Official account: Qiniu Programming

Guess you like

Origin blog.csdn.net/weixin_55751709/article/details/129567452