【编程好习惯】永远将头文件作为定义和引用的桥梁
2010-04-06 08:10
323 查看
在现实项目中,有时为了省事在引用一个变量或函数时,会直接采用extern关键定在.c文件中进行声明。图1中reference.c的第3行是对一个变量采用extern关键字进行声明,图2中reference.c的第1行则是对一个函数采用extern关键字进行声明。[align=left]define.c[/align]00001: char g_name [] = {’Y’, ’u’, ’n’, ’\0’};reference.c00001: #include <stdio.h>00002: 00003: extern char *g_name;00004: 00005: int main ()00006: {00007: printf ("%c\n", g_name [0]);00008: return 0;00009: }图1[align=left]define.c[/align]00001: #include <stdio.h>00002: 00003: void foo (const char *_p_arg1, const char *_p_arg2)00004: {00005: printf ("%s,%s\n", _p_arg1, _p_arg2);00006: }reference.c00001: extern void foo (int, const char *_p_arg);00002: 00003: int main ()00004: {00005: foo (-1, "Haha!");00006: return 0;00007: }图2通过使用图3所示的命令分别编译图1和图2中的代码并运行之,读者将发现两个程序都将出现崩溃的结果。其原因就是变量的真实定义与被引用时的声明出现了不匹配,《混淆指针和数组所导致的错误》一文对这类问题进行了分析,以及解释了为什么编译器发现不了这类问题。yunli.blog.51cto.com~$gcc -g define.c reference.c -o example.exe图3
为了杜绝类似事情的发生,需要通过使用头文件来作为变量或是函数的定义和引用的桥梁。图4和图5是分别采用头文件的实现方式。两个实现各自都定义了一个define.h头文件用于声明变量或是函数的原型,接着在define.c和reference.c中都包含这一头文件。如果采用图3所示的命令再一次编译两个程序,些时编译器将报错。[align=left]define.h[/align]00001: extern char *g_name;define.c00001: #include ”define.h”00002:00003: char g_name [] = {’Y’, ’u’, ’n’, ’\0’};reference.c00001: #include <stdio.h>00002: #include ”define.h”00003: 00004: int main ()00005: {00006: printf ("%c\n", g_name [0]);00007: return 0;00008: }图4[align=left]define.h[/align]00001: extern void foo (int, const char *_p_arg);define.c00001: #include <stdio.h>00002: #include ”define.h”00003: 00004: void foo (const char *_p_arg1, const char *_p_arg2)00005: {00006: printf ("%s,%s\n", _p_arg1, _p_arg2);00007: }reference.c00001: #include ”define.h”00002: 00003: int main ()00004: {00005: foo (-1, "Haha!");00006: return 0;00007: }图5
在项目中之所以会出现直接采用extern进行外部变量或函数的引用,无非存在两种原因。其一是图省事;其二则是由于项目中的头文件规划得太乱,以至于要包含一个头文件会引入更多其它没完没了的头文件需要包含,当然其本质还是图省事。要使得项目组做到永远采用将头文件作为定义和引用的桥梁,必须做到整个项目中的头文件都组织得可以被方便的包含,而要做到这一点,必须运用《精确包含头文件》这一编程好习惯。
为了杜绝类似事情的发生,需要通过使用头文件来作为变量或是函数的定义和引用的桥梁。图4和图5是分别采用头文件的实现方式。两个实现各自都定义了一个define.h头文件用于声明变量或是函数的原型,接着在define.c和reference.c中都包含这一头文件。如果采用图3所示的命令再一次编译两个程序,些时编译器将报错。[align=left]define.h[/align]00001: extern char *g_name;define.c00001: #include ”define.h”00002:00003: char g_name [] = {’Y’, ’u’, ’n’, ’\0’};reference.c00001: #include <stdio.h>00002: #include ”define.h”00003: 00004: int main ()00005: {00006: printf ("%c\n", g_name [0]);00007: return 0;00008: }图4[align=left]define.h[/align]00001: extern void foo (int, const char *_p_arg);define.c00001: #include <stdio.h>00002: #include ”define.h”00003: 00004: void foo (const char *_p_arg1, const char *_p_arg2)00005: {00006: printf ("%s,%s\n", _p_arg1, _p_arg2);00007: }reference.c00001: #include ”define.h”00002: 00003: int main ()00004: {00005: foo (-1, "Haha!");00006: return 0;00007: }图5
在项目中之所以会出现直接采用extern进行外部变量或函数的引用,无非存在两种原因。其一是图省事;其二则是由于项目中的头文件规划得太乱,以至于要包含一个头文件会引入更多其它没完没了的头文件需要包含,当然其本质还是图省事。要使得项目组做到永远采用将头文件作为定义和引用的桥梁,必须做到整个项目中的头文件都组织得可以被方便的包含,而要做到这一点,必须运用《精确包含头文件》这一编程好习惯。
相关文章推荐
- keil 中——C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法
- 未能加载文件或程序集Office, Version=2.2.0.0, Culture=neutral, PublicKeyToken=null或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
- C++ 头文件(十五)--定义成员属性、引用、避免多次包含
- 详解keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法!
- 【编程好习惯】减少搜索头文件的目录数
- 定义Point(点)类,由Point类派生出Circle(圆)类,再由Circle类派生出Cylinder(圆柱体)类。将类的定义部分分别作为3个头文件
- 类模块中定义的变量能否同自定义类型那样作为文件记录存取?
- 头文件中定义struct时候出现相互引用如何抑制告警?
- C++ 关于声明,定义,类的定义,头文件作用,防止头文件在同一个编译单元重复引用,不具名空间
- 未能加载文件或程序集“System.Web.Http, Version=5.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)解决办法
- class”类型重定义 || 防止头文件重复加载 || 两个类之间互相引用
- C++ 关于声明,定义,类的定义,头文件作用,防止头文件在同一个编译单元重复引用,不具名空间
- 详解keil采用C语言模块化编程时全局变量、结构体的定义、声明以及头文件包含的处理方法!
- (vs2008链接错误LK200x:xxx在yyy.obj中已定义或xxx在yyy中以被引用):一个全局的变量想在多个cpp文件中使用
- C\C++小知识: 如何引用一个已经定义过的全局变量 与 全局变量可不可以定义在可被多个.C文件包含的头文件中
- C++ : 编译单元、声明和定义、头文件作用、防止头文件在同一个编译单元重复引用、static和不具名空间
- 优化网站设计(八):将脚本文件和样式表作为外部文件引用
- 【编程技巧】头文件不能定义全局变量+模板的实现应该头文件中
- codeblocks 多线程编程时出现:对pthread_create未定义的引用,解决方法
- Revit中Dynamo编程——在Python Script中引用Python的py文件