(1)编译单元(模块)
第一步,将每个.cpp(.c)和相应的.h文件编译成obj文件;
第二步,将工程中所有的obj文件进行LINK,生成最终.exe文件。
那么,错误可能在两个地方产生:
一个,编译时的错误,这个主要是语法错误;
一个,链接时的错误,主要是重复定义变量等。
编译单元指在编译阶段生成的每个obj文件。
一个obj文件就是一个编译单元。
一个.cpp(.c)和它相应的.h文件共同组成了一个编译单元。
一个工程由很多编译单元组成,每个obj文件里包含了变量存储的相对地址等。
(2)声明与定义
函数或变量在声明时,并没有给它实际的物理内存空间,它有时候可保证你的程序编译通过;
函数或变量在定义时,它就在内存中有了实际的物理空间。
如果你在编译单元中引用的外部变量没有在整个工程中任何一个地方定义的话,那么即使它在编译时可以通过,在连接时也会报错,因为程序在内存中找不到这个变量。
函数或变量可以声明多次,但定义只能有一次。
(3)extern作用
作用一:当它与"C"一起连用时,如extern"C"voidfun(inta,intb);,则编译器在编译fun这个函数名时按C的规则去翻译相应的函数名而不是C++的。
作用二:当它不与"C"在一起修饰变量或函数时,如在头文件中,externintg_nNum;,它的作用就是声明函数或变量的作用范围的关键字,其声明的函数和变量可以在本编译单元或其他编译单元中使用。
即B编译单元要引用A编译单元中定义的全局变量或函数时,B编译单元只要包含A编译单元的头文件即可,在编译阶段,B编译单元虽然找不到该函数或变量,但它不会报错,它会在链接时从A编译单元生成的目标代码中找到此函数。
(4)全局变量(extern)
有两个类都需要使用共同的变量,我们将这些变量定义为全局变量。比如,和分别来声明和定义全局变量,类ProducerThread和ConsumerThread来使用全局变量。(以下是QT工程代码)
/**********声明全局变量************/includeQSemaphoreconstintg_nDataSize=1000;//生产者生产的总数据量constintg_nBufferSize=500;//环形缓冲区的大小externcharg_szBuffer[];//环形缓冲区externQSemaphoreg_qsemFreeBytes;//控制环形缓冲区的空闲区(指生产者还没填充数据的区域,或者消费者已经读取过的区域)externQSemaphoreg_qsemUsedBytes;//控制环形缓冲区中的使用区(指生产者已填充数据,但消费者没有读取的区域)/**************************/
上述代码中g_nDataSize、g_nBufferSize为全局常量,其他为全局变量。
/**********定义全局变量************/include""//定义全局变量charg_szBuffer[g_nBufferSize];QSemaphoreg_qsemFreeBytes(g_nBufferSize);QSemaphoreg_qsemUsedBytes;/**************************/
在其他编译单元中使用全局变量时只要包含其所在头文件即可。
/**********类ConsumerThread使用全局变量************/include""include""换成externcharg_szBuffer[];。但是这样做很不好,因为你无法使用pragmaonce,或include""include""includeiostreamusingnamespacestd;voidfun1(){fun();for(inti=0;i6;i++){g_szBuffer[i]='a'+i;}coutg_szBufferl;}/************************/
/*********************/voidfun2();/************************/
/*********************/include""include""#include""intmain(){fun1();fun2();system("PAUSE");return0;}/************************/运行结果如下:
按我们的直观印象,认为fun1()和fun2()输出的结果都为abcdef,可实际上fun2()输出的确是初始值。然后我们再跟踪调试,发现res、test1、test2中g_szBuffer的地址都不一样,分别为0x0041a020、0x0041a084、0x0041a040,这就解释了为什么不一样。
注:一般定义static全局变量时,都把它放在.cpp文件中而不是.h文件中,这样就不会给其他编译单元造成不必要的信息污染。
(6)全局常量(const)
const单独使用时,其特性与static一样(每个编译单元中地址都不一样,不过因为是常量,也不能修改,所以就没有多大关系)。
const与extern一起使用时,其特性与extern一样。
externconstcharg_szBuffer[];//写入.h中
constcharg_szBuffer[]="123456";//写入.cpp中
最后,如果你想学C/C++可以私信小编“01”获取素材资料以及开发工具和听课权限哦!





