关于c的头文件的几个问题

学c很多年来只是知道、那些律法般的规则,直到实战才知道其真正的含义。

问题1. 关于防止嵌套包含宏定义开关

在每个头文件的开头和结尾是头文件的宏定义开关:

#ifndef XXXX

#define XXXX

----

----

#endif

这是为了防止在一个源文件中重复引用同一个头文件造成的重引用。我可以理解在同一个问题中防止嵌套的功用,但是如果两个源文件同时引用同一个头文件呢,毕竟XXXX是一个开关,当第一次已经被定义后,第二个引用的源文件岂不是被开关挡在内容之外?但是我们平时使用并没有出现这种现象,那么原因何在?

看一个例子就知道了。

定义2个文件a.h a.c 

扫描二维码关注公众号,回复: 4007064 查看本文章

//a.h

  1 #ifndef __aaa__
  2 #define __aaa__ 11
  3 int a;
  4 #endif


//a.c

  1 #include "aa.h"
  2 int main()
  3 {
  4     a=__aaa__;
  5     return 0;
  6 }
 

预编译一下

#gcc -E a.c -o a.i

打开a.i

  1 # 1 "aa.c"
  2 # 1 "<built-in>"
  3 # 1 "<command-line>"
  4 # 1 "/usr/include/stdc-predef.h" 1 3 4
  5 # 1 "<command-line>" 2
  6 # 1 "aa.c"
  7 # 1 "aa.h" 1
  8
  9
 10 int a;
 11 # 2 "aa.c" 2
 12 int main()
 13 {
 14  a=11;
 15
 16  return 0;
 17 }
我们可以看到在预编译完成的文件中并没有__aaa__,在我们引用的地方已经被替换成了11,这样在后续的编译链接阶段,__aaa__是不存在的,也就不会有冲突的问题了,毕竟重定义的冲突要到链接阶段才会别发现。于是问题解决。

问题2. 关于定义变量的问题

应该是我没学好c,我一直以为要把全局变量定义或声明在头文件中。指定我在大型工程中出现重定义的错误。

原因是显然的,一个供超过2个源文件引用的头文件里面定义或声明的变量会被copy多份,这样在链接的时候就会出现多重定义的错误。解决办法是在某个.c文件中定义和声明全局变量而在头文件中加extern,这样头文件就可以被多源文件引用而不会报错了。

问题3. 关于声明函数的问题

在我没接触大型c工程时,认为在头文件中声明函数是不容置疑的正确。而且就是把在源文件中的声明照搬到头文件的那种。事实并非如此。

声明函数同样会遇到问题2中的情形。被引用的头文件会被copy多次,进而产生多重声明的错误。

解决办法是,如果一个头文件只会被某个源文件引用,那么可以将它直接放在头文件中,不用做修改,也不会出问题,这个同样适用于上一个问题。对于一般的情形,有一种办法是在声明函数前加static或static inline。这样就会使得函数只在引用的源文件中起作用,使其scope变成文件内可见而非全局的。加inline就是将函数直接展开,加不加要看情况。

最后,送给自己:纸上得来终觉浅,绝知此事要躬行。

猜你喜欢

转载自blog.csdn.net/wujianyongw4/article/details/83820057