
往往需要包含的头文件中含有变量、函数、类的定义,在其它使用的地方又不得不多次包含之,如果头文件中没有相关的宏等防止重复链接的措施,那么就会产生lnk2005错误。把内联函数的定义放在头文件中,可以确保在调用函数时所使用的定义是相同的全局变量 重复定义,并保证在调用点该函数的定义对调用点可见.在头文件中加入或修改内敛函数时,使用了该头文件的所有源文件都需要重新编译.2)类中的成员函数作为内联函数.在类内声明的成员函数,如果在类中实现,则自动转化为内联函数,但若违反上面所述的情况时,则将其作为一般函数对待.若在类定义外面实现该函数,则需要显示指定inline.类定义写在头文件中时,如果需要内联函数,函数也应在头文件中实现.参考:c+。如果你声明没有inline,却在定义时inline了.这时,如果其它要调用该函数的文件看到了它的声明,就认为该函数不是内联的,所以,到了调用处,转到该函数实现的地方,却意外地看到了inline声明,这时,会导致链接出错.若要改正的话,就要让调用该函数的文件也看到有inline的定义,而不是在调用时才看到.你可以在每个文件都加上有inline的定义.(如果不加inline,则会出现重复定义的错误,因为内联函数才可以被重复定义).或者另一种修改方法,你将定义时的inline去掉,这样就成为普通函数,链接不会出错.如果是前一种改法,仍是内联的,因为符合了看到了inline且随处可见其定义的条件.。

你的头文件就是对用户的说明。函数参数各种各样的接口的说明。那既然是说明那么头文件里面放的自然就是关于函数变量类的“声明”了。记着是“声明”不是“定义”。那么我假设大家知道声明和定义的区别。所以最好不要傻嘻嘻的在头文件里定义什么东西。比如全局变量:#ifndefXX头文件H#defineXX头文件HintA#endif会那么很糟糕的是这里的intA是个全局变量的定义所以如果这个头文件被多次引用的话你的A被重复定义显然语法上错了。只不过有了这个#ifndef的条件编译所以能保证你的头文件只被引用一次不过也许还是会岔子但若多个c文件包含这个头文件时还是会出错的因为宏名有效范围仅限于本c源文件所以在这多个c文件编译时是不会出错的但在链接时就会报错说你多处定义了同一个变量Linkinginclobj:errorLNK:"intglb"(glbHA)alreadydefinedininclobjDebuginclexe:fatalerrorLNK:oneormoremultiplydefinedsymbolsfound注意~~~extern这个关键字真的比较可恶在声明的时候这个extern居然可以被省略所以会让你搞不清楚到底是声明还是定义下面分变量和函数两类来说:()变量尤其是对于变量来说。

externinta声明一个全局变量ainta定义一个全局变量aexterninta=定义一个全局变量a并给初值。inta=定义一个全局变量a,并给初值第四个等于第三个都是定义一个可以被外部使用的全局变量并给初值。糊涂了吧他们看上去可真像。但是定义只能出现在一处。也就是说不管是inta还是externinta=还是inta=都只能出现一次而那个externinta可以出现很多次。当你要引用一个全局变量的时候你就要声明externinta这时候extern不能省略因为省略了就变成inta这是一个定义不是声明。()函数函数函数对于函数也一样也是定义和声明定义的时候用extern说明这个函数是可以被外部引用的声明的时候用extern说明这是一个声明。但由于函数的定义和声明是有区别的定义函数要有函数体声明函数没有函数体所以函数定义和声明时都可以将extern省略掉反正其他文件也是知道这个函数是在其他地方定义的所以不加extern也行。两者如此不同所以省略了extern也不会有问题。比如:intfun(void){return}很好我们定义了一个全局函数intfun(void)我们对它做了个声明然后后面就可以用了加不加extern都一样我们也可以把对fun的声明放在一个头文件里最后变成这样intfun(void)函数声明所以省略了extern完整些是externintfun(void)intfun(void){return}一个完整的全局函数定义因为有函数体extern同样被省略了。

然后一个客户一个要使用你的fun的客户把这个头文件包含进去ok一个全局的声明。没有问题。但是对应的如果是这个客户要使用全局变量那么要extern某某变量不然就成了定义了。总结下:对变量而言如果你想在本源文件中使用另一个源文件的变量就需要在使用前用extern声明该变量或者在头文件中用extern声明该变量对函数而言如果你想在本源文件中使用另一个源文件的函数就需要在使用前用声明该变量声明函数加不加extern都没关系所以在头文件中函数可以不用加extern。C程序采用模块化的编程思想需合理地将一个很大的软件划分为一系列功能独立的部分合作完成系统的需求在模块的划分上主要依据功能。模块由头文件和实现文件组成对头文件和实现文件的正确使用方法是:规则头文件(h)中是对于该模块接口的声明接口包括该模块提供给其它模块调用的外部函数及外部全局变量对这些变量和函数都需在h中文件中冠以extern关键字声明规则模块内的函数和全局变量需在c文件开头冠以static关键字声明规则永远不要在h文件中定义变量许多程序员对定义变量和声明变量混淆不清定义变量和声明变量的区别在于定义会产生内存分配的操作是汇编阶段的概念而声明则只是告诉包含该声明的模块在连接阶段从其它模块寻找外部函数和变量。

如:inta=#include“moduleh”#include“moduleh”#include“moduleh”以上程序的结果是在模块、、中都定义了整型变量aa在不同的模块中对应不同的地址单元这明显不符合编写者的本意。正确的做法是:externinta#include“moduleh”inta=#include“moduleh”#include“moduleh”这样如果模块、、操作a的话对应的是同一片内存单元。规则如果要用其它模块定义的变量和函数直接包含其头文件即可。许多程序员喜欢这样做当他们要访问其它模块定义的变量时他们在本模块文件开头添加这样的语句:externintexternVar抛弃这种做法吧只要头文件按规则完成某模块要访问其它模块中定义的全局变量时只要包含该模块的头文件即可。共享变量声明就像在函数间共享变量的方式一样变量可以在文件中共享。为了共享函数要把函数的定义放在一个源文件中然后在需要调用此函数的其他文件中放置声明。共享变量的方法和此方式非常类似。在此之前不需要区别变量的声明和它的定义。为了声明变量i写成如下形式:inti这样不仅声明i是int型的变量而且也对i进行了定义从而使编译器为i留出了空间。
为了声明没有定义的变量i需要在变量声明的开始处放置关键字extern:externintiextern提示编译器变量i是在程序中的其他位置定义的(大多数可能是在不同的源文件中)因此不需要为i分配空间。顺便说一句extern可以用于所有类型的变量。在数组的声明中使用extern时可以忽略数组的长度:externinta因为此刻编译器不用为数组a分配空间所以也就不需要知道数组a的长度了。为了在几个源文件中共享变量i首先把变量i的定义放置在一个文件中:inti如果需要对变量i初始化那么可以在这里放初始值。在编译这个文件时编译器将会为变量i分配内存空间而其他文件将包含变量i的声明:externinti通过在每个文件中声明变量i使得在这些文件中可以访问或修改变量i。然而由于关键字extern使得编译器不会在每次编译其中某个文件时为变量i分配额外的内存空间。当在文件中共享变量时会面临和共享函数时相似的挑战:确保变量的所有声明和变量的定义一致。为了避免矛盾通常把共享变量的声明放置在头文件中。需要访问特殊变量的源文件可以稍后包含适当的头文件。此外含有变量定义的源文件包含每一个含有变量声明的头文件这样使编译器可以检查两者是否匹配。
在使用头文件包含的时候,所包含头文件php很容易被扫描器扫描到,这时候可以使用file_put_content创建一个文件,里面写如php的一句话马。把这些头文件全部写到一个头文件里面去,比如写到preh.h。创建一个控制台程序,因为用到了textout,已经实现了字体颜色和背景的改变,所以想改变字体,看了网上的,需要用到cfont类,后来加上了,但是提示没有定义,找原因说,cfont是mfc的类全局变量 重复定义,所以需要加上afxwin.h头文件,但是又提示不是mfc工程之类的错误,然后找了原因,把工程属性的use of mfc改为use mfc in a shared dll.但是还是有问题,程序中包含了windows.h头文件,因为afxwin.h已经包含了windows.h头文件了,所以会提示重复定义,所以,现在只要把windows,h删除(但是必须要把afxwin.h放在头文件的最前面,因为我的工程里要用到windows.h的函数,如果放在后面,有可能会提示一些函数未定义)。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-116317-1.html
我在台服玩过网游