📄 第02章 编程环境.htm
字号:
head的意思,所以被称为头文件。这个文件在哪里呢?在你的机器里,在C++ Builder安装后的文件夹内的某个子文件夹内。在那个文件夹内,C++
Builder为我们提供了上千个头文件。头文件起什么作用呢?我们做个比喻,设想你家很富,但不幸四周的邻居都穷。今天李四推门而入,四下搜索一番,借走一把钳子,明天张三不请自来,抬走一台电视……天天有人直接进入你家,这显示是危险的。于是你在门口贴了各式清单,其一为五金工具,其二为家用电器清单……当别人需要某种东西时,先从清单上找一找是否存在,如果有,则在清单上作个登记……
</P>
<P>Borland C++ Builder为我们提供了函数库(RTL /runtime
library),类库(VCL);而Windows操作系统(Windows用C写成),则向我们提供了API函数库;库“储存”大量实用的解决各种问题,实现各种功能的“工具”,它们都通过头文件列出清单。
</P>
<P>当我们写上#include <stdio.h> 这一行时,我们是在向编译器说明:本文件中的程序需要用到 stdio.h
头文件中所列的某些函数。include正是包含之意。 </P>
<P>printf("Hello,world!"); </P>
<P>getchar(); </P>
<P>现在看这两句。printft和getchar正是两个在stdio.h中列出的函数。如果没有#include
<stdio.h>这一行,编译器便会报错说不认识这两个符号。换句话说:include语句让编译知道我们要用的库函数在哪一个库里。我们会在下一节“简单程序调试”中做相应试验。
</P>
<P>print 是打印之意,而f 则为 format,二者结合意为“有格式地打印”。我们的Hello
World不需要任何格式。至于getchar,从字面上理解是“得到字符”?事实上就是程序会在此处停下来,等待用户输入字符,直到输入一个回车符,程序继续执行。在我们的这个程序里,继续执行的结果是碰上这一行:
</P>
<P>return 0; </P>
<P>return是返回。当主函数main返回时,整个程序就结束了。所以,要这个getchar()的目的很明显:让程序在结束之前可以等我们一下(因为我们需要看一眼输出的“Hello
World”)。 </P>
<P>printf是输出(output)内容,而getchar()则是等待你输入,从这一点看,我们也可以理解前面include的为什么是
stdio.h了:std是英文标准的前三个字符,而I和O分别是input和output的首字母。 </P>
<P>说了很长,但程序运行结果却很简单,这是按F9后的运行结果: </P>
<P><IMG height=127 src="第02章 编程环境.files/DosHelloWord.jpg" width=316
border=0> </P>
<P>按回车,结束。结束后,别忘了保存我们的第二个程序。 </P>
<H3>2.4 <A name=简单程序调试>简单程序调试</A> </H3>
<H4>2.4.1 <A name=编译期错误与运行期错误>编译期错误与运行期错误</A> </H4>
<P>如果我在上面的程序输出时,打出的字幕不是“Hello,world”,而是“Hello,word”。你一定会说“哎,哥们,程序错了!”。于是,我就要去代码中查找有关输出的那一句,一看,哟,真少写了一个‘l’。将这一错改正,重新运行,检查结果。
</P>
<P>这就是一个调试过程,发现错误;查找出错原因;改正;再运行。当然,由于很多时候我们也不是非要等到发现错误了才去检查,有时我们会主动一步步去事先主动检查是否有错。必竟BUG总是常见的。
程序错误(BUG)表现上各式各样,但若是从其“发作”的时间上分,则可分为“编译期错误”和“运行期错误”。如上面说的错误,属于后者,因为它对编译过程并不产生什么阻碍,编译可以顺得通过。错误在运行中表现出来。(按时间分还有一种为“链接期错误”,这里不说)
</P>
<P>我们来故意制造一个编译期的BUG。 </P>
<P>这是上一节的代码: </P>
<P>int main(int argc, char* argv[]) </P>
<P>{ </P>
<P>printf("Hello,world!"); </P>
<P>getchar(); </P>
<P>return 0; </P>
<P>} </P>
<P>现在我们故意将最后一句代码: return 0; 行末的分号删除,结果为: </P>
<P>int main(int argc, char* argv[]) </P>
<P>{ </P>
<P>printf("Hello,world!"); </P>
<P><B><I>getchar();</I></B> </P>
<P>return 0 </P>
<P>} </P>
<P><I>(约定:我们用<B>粗斜体</B>表示修改过的代码)</I> </P>
<P>现在按F9,程序并没有跑起来。但在代码编器窗口下面,出现一消息框(如果你没有发现,请在代码窗口中点鼠标右键,将出现右键菜单,选:Message
View) </P>
<P><IMG height=248 src="第02章 编程环境.files/ls026.jpg" width=386 border=0>
</P>
<P>编译过程是一个相当复杂的过程,在编译之前,代码会被做很多格式上的转换,另一边,人写代码出错的原因也五花八门,所以,想让编译器为判断到底你犯了什么错事实上是很难的。但CB的编译出错消息竭尽全力让我们找到出错原因:
</P>
<P>[C++ Error]:
错误类型。这是在告诉我们,这是一个C++语言语法方面的错误。编译器说对了,因为我们少写一个分号,确实是犯了语法错误。</P>
<P>Unit.cpp(13):错误位置。说是在Unit.cpp这个文件内的第13行。文件显然是说对了,但行数却稍有偏差,少了分号的那行其实是第12行。(从状态栏可以看到当前光标位置的行列数。
</P>
<P>E2378:错误编号。CB对各错误消息加进行了编号。 </P>
<P>Return statement missing; 错误消息。很好,这个消息100%正确:return 语句丢了分号。 </P>
<P>并不是每回都能幸运得到这样准确的错误报告消息。比如同样是去掉分号,但这回把return 0那一句的分号补上,去掉它</P>
<P>printf(“Hello world!”)这一行的分号,编译出错消息是这样: </P>
<P><IMG height=248 src="第02章 编程环境.files/ls027.jpg" width=386 border=0>
</P>
<P>错误消息说我们调用了一个“非函数”,为什么呢?答案是因为没有了分号,编译将两句连成一句:printf(</P>
<P>“Helo,world!”)getchar();这样,它就把printf(“Helo,world!”)getchar整个儿认为一个是一个函数名,于是就不认识它了。
</P>
<P>下面我们做一个实验,结果报错也同样为“Call of
nonfunction”,但原因不是因为我们写错了函数名,而是因为我们使用了库函数,<B>但没有通过include语句来告诉编译器:这些函数在哪个库里。</B>
</P>
<P>//---------------------------------------------------------------------------
</P>
<P>//#include <stdio.h> </P>
<P>#pragma hdrstop </P>
<P>//---------------------------------------------------------------------------
</P>
<P>#pragma argsused </P>
<P>int main(int argc, char* argv[]) </P>
<P>{ </P>
<P>printf("Hello,world!"); </P>
<P>getchar(); </P>
<P>return 0; </P>
<P>} </P>
<P>//---------------------------------------------------------------------------
</P>
<P>代码中,我们故意有 // 将#include <stdio.h>
从一行代码摇身一变成为一行注释。前面说过注释是仅给人看的,编译看不到这一行,相当于你删除了这一行。现在编译这一行,错误如下: </P>
<P><IMG height=248 src="第02章 编程环境.files/include.jpg" width=386 border=0>
</P>
<P>两行同样类型的错误消息。编译一下子不认识printf和getchar两个函数了。 </P>
<H4>2.4.2 <A name=学会使用帮助文档>学会使用帮助文档</A> </H4>
<P>经过上一节,同学可能会问三个问题: </P>
<P>第一,“老师,你怎么知道有printf和getchar这个两个函数呢?” </P>
<P>回答:两个途径:常用的函数会在课程里讲到。其它函数则根据需要在各上文档中查找”。 </P>
<P>第二,你怎么会知道printf是用来输出而getchar则可以用于等待输入? </P>
<P>回答和上面一致,从课程和文档中获得。 </P>
<P>第三,就算知道了printf这个函数,我又怎么才能知道它在 stdio这个头文件对应的库里? </P>
<P>回答还是一样。 </P>
<P>学会使用文档看来很重要。文档有多种,比如有专门的函数大全之类的书,不过现在的文档是帮助文档。初学者在调试程序时,很多人由于英文不佳,于是根本不去动帮助文档。其实当你带些具体的目的去看帮助文档,你会发现就算英文不好,你可以从中获得帮助,解决大部分程序问题。
</P>
<P>我们用一节的那个BUG来说明问题。假如你用了printf和getchar这两个函数,但你不知它们包含在哪个库里(也就是说你不知道在#include
之后应该写”stdio.h”)。 </P>
<P>菜单:Help | C++ Builder Help </P>
<P>出现Windows标准的帮助索引窗口,我们在索引内键入:printf。 </P>
<P><IMG height=428 src="第02章 编程环境.files/HelpprfIdx.jpg" width=434
border=0> </P>
<P>如此,我们找到了有关printf 的帮助: </P>
<P><IMG height=319 src="第02章 编程环境.files/Help_printf.jpg" width=361
border=0> </P>
<P>看,红圈内的内容清楚地说明了什么? </P>
<P>(提高英语水平对学习编程的帮助是很大的。如果你需要学习英语,就不妨听我做一句广告: </P>
<P><B>英语学万<FONT color=#ff0000>句</FONT>,开口如有<FONT
color=#ff0000>神</FONT></B>——<A
href="http://www.bcbschool.com/v4_softs.htm">点击此处查看我们的最新英语学习产品《句神英语2002》介绍</A>)
</P>
<P>在广告的喧哗声中,我们结束了第二章的学习。 </P></TD></TR></TBODY></TABLE></CENTER>
<P align=center>[<A
href="http://www.d2school.com/bcyl/bhcpp/newls/ls02.htm#页首">到页首</A>]</P></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -