⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 第14章 程序的文件结构.htm

📁 用非常通俗的语言介绍了C++和C
💻 HTM
📖 第 1 页 / 共 4 页
字号:
      <P> </P>
      <P>今天的情况有点不一样。我们需要在某个源文件中定义一个变量,然后,在另外一个源文件中使用这个变量。</P>
      <P> </P>
      <P>仍以前面 age 变量为例:</P>
      <P> </P>
      <P>//我们在 A.cpp 文件中定义了这个变量:</P>
      <P>int age;</P>
      <P> </P>
      <P>//然后,在 B.cpp 文件中要使用这个变量:</P>
      <P>age = 18;</P>
      <P>cout &lt;&lt; age &lt;&lt; endl;</P>
      <P> </P>
      <P>问题就出来了:在编译 B.cpp 文件时,编译器会说:“age 这个变量没有定义啊?”——当编译器在编译 
      B.cpp时,它并不懂得去A.cpp里去找有关 age 的定义。</P>
      <P>那么,能不能在B.cpp里再定义一次age变量呢?</P>
      <P> </P>
      <P>//A.cpp文件中:</P>
      <P><B>int age;</B></P>
      <P> </P>
      <P>//B.cpp文件中:</P>
      <P><B>int age;</B></P>
      <P>age = 18;</P>
      <P>cout &lt;&lt; age &lt;&lt; endl;</P>
      <P> </P>
      <P>这样,单独编译A.cpp,或B.cpp,都可以通过。但一旦要编译整个工程,编译器又会报错:“怎么有两个 age 变量的定义啊”?</P>
      <P>不要嘲笑编译器为什么这么笨笨。C,C++是一门严谨的的计算机语言,我们不能指望编译器会“智能”地猜测程序员的企图。</P>
      <P> </P>
      <P>解决方法是,仅在一处<B>定义变量</B>,别的代码需要用到该变量,但无法看到前面的定义时,则改为“声明变量”。</P>
      <P> </P>
      <P><B>声明变量的语法:</B></P>
      <P><B>extern</B> 数据类型 变量名</P>
      <P> </P>
      <P>和定义变量的语法相比,多了前面的 <B>extern </B>这个关键字。</P>
      <P> </P>
      <P>extern 
意为“外来的”···它的作用在于告诉编译器:有这个变量,它可能不存在当前的文件中,但它肯定要存在于工程中的某一个源文件中。</P>
      <P> </P>
      <P>这就好像:微软公司在北京招人,微软的报名方法是:在北京的应聘者必须当天去面试,而外地应聘者则通过发e-mail先报名,然后以后再去面试。 
      在C,C++里,不处于当前源文件中的变量被称为外部变量。比喻中,发e-mail就相当于外部变量在某一个源中写个声明。声明什么呢?就是声明“我存在啊!虽然我现在不在这里,但是我真的存在!”</P>
      <P> </P>
      <P>上例中,正确的代码应该这样写:</P>
      <P> </P>
      <P>//A.cpp文件中:</P>
      <P><B>int age;</B></P>
      <P> </P>
      <P>//B.cpp文件中:</P>
      <P><B><FONT color=#ff0000>extern</FONT> int age;</B></P>
      <P>age = 18;</P>
      <P>cout &lt;&lt; age &lt;&lt; endl;</P>
      <P> </P>
      <P>变量 age 是在A.cpp文件里定义的,当B.cpp文件要使用它时,必须先声明。这就是我们讲半天课的核心。</P>
      <P> </P>
      <P>(有些教材并不认为 extern int age; 
      是在声明一个变量,它们把这也称为是“定义变量”的一种,只不过它是定义了一个名部变量。我认为这样认为不好,一来它造成了学习者认为“变量可以重复定义”的错误认为,二来它也造成了不统一,函数有“定义”和“声明”两种形式,而变量都没有“声明”。</P>
      <P>可能你会说,现在也不统一啊?函数声明没有“extern",而变量却需要?呵呵,其实恰恰相反。函数声明本来也是需要一个“extern”的,比如:</P>
      <P> </P>
      <P>extern void CalcTotal(int n);</P>
      <P>你在代码里这样完全正确!只不过由于函数声明和函数定义的格式区别很大,(声明没有函数体,定义则必须有函数体),所以这个extern就算不写,也可以让编译器认出来它是一个“声明”。结果就规定可以不写"extern"了。</P>
      <P>而变量呢?</P>
      <P>extern int age;&nbsp;&nbsp;&nbsp;&nbsp; //这是声明</P>
      <P>int 
      age;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      //这是定义</P>
      <P>你看看,不写"extern"可不行! 就靠它来区分是定义还是声明了。</P>
      <P>如此而已。)</P>
      <P> </P>
      <H4><A name=14.5.2>14.5.2</A> 多个文件中共享变量的实例</H4>
      <P> </P>
      <P>做一个最简单的例子。新建一个控制台工程。然后再加一个单元文件。把工程存盘为Project1.bpr,把两个源文件分别存盘为Unit1.cpp、Unit2.cpp 
      (即,都采用默认文件名)。</P>
      <P> </P>
      <P>程序内容是:在 Unit1.cpp 内定义一个变量,即:int 
      age,并且,要求用户输入。在Unit2.cpp里,写一函数,OutputAgeText(),它根据 age 的值, 输出一些文本。</P>
      <P> </P>
      <P>请问,变量 age 在哪里定义?又在哪里声明?</P>
      <P> </P>
      <P>定义指定是在 Unit1.cpp 文件里,而声明,则可以在 Unit2.cpp内直接声明(如上例中的红色代码),也可以是在头文件 
      Unit1.h 里声明,然后在 Unit2.cpp 内使用 include 来包含 Unit1.h。 事实让,声明也可以放在 
      Unit2.h内。只要能让Unit2.cpp“看到”这个声明即可。这一点和函数的声明一个道理。</P>
      <P> </P>
      <P>我们采用放在Unit2.cpp中的方法,该方法所需代码如下:</P>
      <P> </P>
      <P>//Unit1.cpp 内的主要代码:</P>
      <P> </P>
      <P><B>#include &lt;iostream.h&gt;</B></P>
      <P><B>#include &lt;conio.h&gt;</B></P>
      <P>#pragma hdrstop</P>
      <P><B>#include "Unit2.h"</B></P>
      <P>... ...</P>
      <P>//--------------------------------------------------------------------------- 
      </P>
      <P><B>int age; //全局变量,年龄</B></P>
      <P>#pragma argsused </P>
      <P>int main(int argc, char* argv[]) </P>
      <P>{ </P>
      <P>&nbsp;<B>&nbsp; cout &lt;&lt; "请输入您的年龄:" ;</B></P>
      <P><B>&nbsp;&nbsp; cin &gt;&gt; age;</B></P>
      <P> </P>
      <P><B>&nbsp;&nbsp; //调用Unit2.cpp中的函数,该函数根据age,作出相应输出</B></P>
      <P><B>&nbsp;&nbsp; OutAgeText();&nbsp;&nbsp; </B></P>
      <P><B>&nbsp;&nbsp; </B></P>
      <P><B>&nbsp;&nbsp; getch();</B></P>
      <P>&nbsp;&nbsp; return 0; </P>
      <P>} </P>
      <P>//--------------------------------------------------------------------------- 
      </P>
      <P> </P>
      <P> </P>
      <P>//Unit2.cpp 中的主要代码:</P>
      <P>#include &lt;iostream.h&gt;</P>
      <P>... ...</P>
      <P>extern int age;&nbsp; //需要Unit1.cpp内定义的变量</P>
      <P> </P>
      <P>//报名参加“没有弯路”的学员各行业,年龄段也各处不同,在此,我们用这个函数作为共勉!</P>
      <P>void OutAgeText()</P>
      <P>{</P>
      <P>&nbsp;&nbsp; if(age &lt; 15)</P>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout&nbsp; &lt;&lt; "计算机要从娃娃抓起!" 
      &lt;&lt; endl;</P>
      <P>&nbsp;&nbsp; else if(age &lt; 25)</P>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; "青春年华,正是学习编程的黄金时代!" 
      &lt;&lt; endl;</P>
      <P>&nbsp;&nbsp; else if(age &lt; 35)</P>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; 
      "学习编程需要热情,更需要理性!我和您一样,也在这个年龄段!"&lt;&lt; endl;</P>
      <P>&nbsp;&nbsp; else if(age &lt; 45)</P>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt; 
      "活到老,学到老!何况您还未老。杀毒王王江民,不也在这个时候才开始学习电脑吗?" &lt;&lt; endl;</P>
      <P>&nbsp;&nbsp; else </P>
      <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cout &lt;&lt;&nbsp; 
      "前辈,只要您像学书法一样潜心学编程!您一定会有收获!" &lt;&lt; endl;</P>
      <P>}</P>
      <P>//---------------------------------------------------------------------------<BR> </P>
      <P> </P>
      <P>//Unit2.h 的主要代码:</P>
      <P> </P>
      <P>//声明OutAgeText()函数,供Unit1.cpp使用</P>
      <P>void OutAgeText();</P>
      <P>//---------------------------------------------------------------------------<BR> </P>
      <P>请大家完成这个工程,直到能正确运行。</P>
      <P> </P>
      <P>现在我们得到一个印象:当我们定义了一个函数或变量之后,似乎所有的源代码文件中都可以使用它,只要你在使用之前写一下相应的声明。</P>
      <P>这样会不会带来麻烦了?想象一下,你在A文件定义了一个变量: int i, 
      那么以后你在别的文件里就不能再定义这个变量了!原因前面已经说过,编译器(或链接器)会说有两个变量重名。函数也一样,尽管它有重载机制,便那也只能是有限制地允许函数重名。</P>
      <P> </P>
      <P>事实上,上例中的 int age 
      是一个全局变量。关于“全局”的解释,需要引起C,C++程序的另一话题:作用范围。这是下一章的内容。在那一章里,我们将看到,大部分变量只在它一定的作用范围内“生存”,不同的作用范围的变量就可以毫无障碍地重名了。</P>
      <P>休息休息(该点眼药水了···),然后学习本章附加一节。</P>
      <P> </P>
      <H3><A name=14.6>14.6</A> 附:如何单独生成一个头文件</H3>
      <P> </P>
      <P>在 14.5.2 试一试在多个文件中共享变量 小节中,我们说,变量的声明可以像函数声明一样放在某个头文件中,然后使用者通过 
      include语句包含该头文件,从而获得变量的声明。</P>
      <P> </P>
      <P>如果你想自已再写一次那个例子(建议),并且改用上述的方法,那么你可能会发现一个小小的故障: Unit1.cpp竟然没有配套的头文件?</P>
      <P> </P>
      <P>CB 
      在生成一个空白的控制台工程时,会自动主函数(main())文件,即默认文件名为:Unit1.cpp的源文件,但它没有为该文件生成对应Unit1.h。</P>
      <P>这是因为作为控制台程序,一般都是小程序,一个源文件即可全部解决。</P>
      <P> </P>
      <P>现在,作为一个课程例子,我们要来讲讲如何为Unit1.cpp生成一个头文件。</P>
      <P> </P>
      <P>CB6中选择菜单:New | Other,CB5中选择 New...,或直接点“<IMG 
      src="第14章 程序的文件结构.files/ls14.h7.gif" border=0>”,出现New Item...对话框,选择 New页内的 
      Header File:</P>
      <P><IMG src="第14章 程序的文件结构.files/ls14.h5.jpg" border=0></P>
      <P> </P>
      <P>确认后,CB生成头文件: File1.h,其内容为空白,我们需要手工加入以下内容:</P>
      <P> </P>
      <P>#ifndef unit1H</P>
      <P>#define unit1H</P>
      <P> </P>
      <P>#endif </P>
      <P> </P>
      <P>然后,选择主菜单 File | Save As... 将其另存为: Unit1.h。 
      完后成,在Unit1.cpp或Unit1.h内,按Ctrl + F6,你就可以看到二者之间的切换了。</P>
      <P> </P>
      <P>下一章见!</P></TD></TR></TBODY></TABLE></CENTER></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -