📄 ls12.php
字号:
<P>好,我们说过“只看一眼”的。关于头文件,在讲完函数以后,还会专门讲到头文件在工程中应用。现在重复头文件的目的:</P>
<P><B>函数可以统一在一个头文件中声明,代码中需要使用这些函数,只需通过“include”语句包含这个头文件,就可以让编译器找到函数。</B></P>
<P>用一句大白话讲就是:要想用函数?请包含它所在的名片夹(头文件)。</P>
<P> </P>
<P>函数的“声明”有时被称为函数的“原型”,比如在讲到编译过程时。当我们阅读其它文章时,如果看到“函数原型”一说,希望大家也能明白。</P>
<P> </P>
<H4><B><A name=12.2.3>12.2.3</A> 调用者必须传递给被调用者正确的参数</B></H4>
<P>现在,我能找到修理工,而且他已经到我家。</P>
<P>“电视呢?”他说。</P>
<P>“就是它”我指着家里的苏泊尔高压锅,</P>
<P>“劳驾,把它修修,最近它总漏气。”</P>
<P>“可是,我好象是来修理电视的?”</P>
<P>“知道,现在你先修高压锅。”</P>
<P>“好吧,我试试……先用电笔试试它哪里短路。”</P>
<P> </P>
<P>显然我这是在胡搅蛮缠。电视修理工要开始干活,就得给他电视。给他一只高压锅他不能开工。</P>
<P>函数也一样,函数的目的是实现某个特定功能,当我们调用它时,我们一般需要给它一些数据,这些数据可能是让它直接处理,也可能是辅助它实现具体的功能。</P>
<P>当然有些函数不需要任何外部数据,它就能完成任务。这也很好理解,修理工修理电视是得有台电视,但叫一位歌手到家里随便哼几句歌,你就不用给他什么。</P>
<P>关键一句话:<B>函数要不要外部传给它数据,要什么类型的数据,要多少数据,由函数本身决定,而非调用者决定</B>。本例中,电视修理工需要一台电视,这是他决定的,不能由请他的人决定。</P>
<P>传给函数的数据,我们称为“参数”,英文为:parameter。</P>
<P> </P>
<P>基于此,我们发现所写的
XiuliDianshi()函数有很大的不足,那就是它没有参数。现在我们假设有一种数据类型为“电视机”,嗯,就假设这种数据类型叫作:TDianshi。</P>
<P>加入参数的XiuliDianShi()函数变为:</P>
<P> </P>
<P>XiuliDianshi (TDianshi ds)</P>
<P>{</P>
<P>}</P>
<P> </P>
<P>看一个实际的例子。上一章我们曾经学过sin()函数。现在我们来看看sin()函数的声明。看看它声明需要什么参数。</P>
<P>关闭刚才的工程,CB会问你是否存盘,统统不存(如果你要存,就存到别的什么地方去,不要存在CB默认的目录下)。然后重新创建一个空白的控制台工程。在代码窗口里加入以下两行黑体代码:</P>
<P>//---------------------------------------------------------------------------</P>
<P>//包含“数学库函数”的头文件,因为sin()函数的声明在这个头文件里:</P>
<P><B>#include <math.h></B></P>
<P>#pragma hdrstop</P>
<P>//---------------------------------------------------------------------------</P>
<P>#pragma argsused</P>
<P>int main(int argc, char* argv[])</P>
<P>{</P>
<P><B> double b = sin(3.14159);</B></P>
<P> return 0;</P>
<P>}</P>
<P>//---------------------------------------------------------------------------</P>
<P>并不需要编译及运行这个程序。因为我们只是想找到sin()函数的声明。</P>
<P>本来,我们可以通过老办法来找到sin函数声明。按Ctrl+回车键打开math.h文件,然后通过Ctrl+F打开查找对话框,找到sin函数。不过CB为我们提供了一种更方便的查找函数声明的方法,有点像我们在网页点击链接:</P>
<P>请按住Ctrl键不放,然后将鼠标移到代码中的 sin处,注意要准确在移到sin字母身上,发现什么?呵,sin出现了超链接效果:</P>
<P><IMG height=40 src="教学--第十二章 函数(一)_files/ls12.h8.gif" width=196
border=0></P>
<P>点一下,CB将自动打开math.h头文件,并且跳转到sin函数的声明处。</P>
<P>(以上操作的成功依赖于你正确地照我说的,在代码中加入#include<math.h>这一行,当然你在安装CB时也必须选择了安装源代码。最后,成功打动后,记得将math.h文件设置为只读。)</P>
<P><IMG height=166 src="教学--第十二章 函数(一)_files/ls12.h7.gif" width=443
border=0></P>
<P> </P>
<P>从图中我们看到,sin函数的参数只有一个:__x,类型要求是double(双精度浮点数,如果你忘了,复习<A
href="http://www.bcbschool.com/newls/ls04.php#4.4">第四章</A>)。</P>
<P>所以,当我们调用sin函数来求正弦值时,我们最好应该给它一个double类型的数,如:</P>
<P>double x = 3.1415926 * 2;</P>
<P>double y = sin(x);</P>
<P> </P>
<P>当然, 我们传给它一个整数:</P>
<P>double y = sin(0);</P>
<P>或者,传给它一个单精度浮点数:</P>
<P>float x = 3.14;</P>
<P>double y = sin(x);</P>
<P>这些都是可以的。这并不违反“参数类型由函数本身决定,不能由调用者决定”的原则。因为在<A
href="http://www.bcbschool.com/newls/ls07.php#7.2">第七章第二节讲算术类型转换</A>时,我们知道一个整数,单精度浮点数,都可以隐式地转换为双精度浮点数。并且属于安全的类型转换,即转换过程中,数据的精度不会丢失。(反过来。一个double类型转换为int类型,就是不安全的转换。比如3.14159转换为整型,就成了3。)</P>
<P>有些函数并不需要参数,比如,我们用了许多次的控制台函数:getchar();。这个函数要做的事就是:等待用户输入一个字符并回车。前面讲数学函数时,举的随机数例子。要想让程序能够产生真正的随机数,需要让程序事先做一些准备。所以我们调用randmize()函数。这个函数也没有参数。因为我们调它的目的,无非是:喂,告诉你,我一会儿可能要用到随机数,你做好准备吧。</P>
<H4><A name=12.2.4>12.2.4</A> 如何得到函数的运行结果</H4>
<P>函数总是要实现一定的功能,所以我们也可以认为函数执行起来就像是在做一件事。</P>
<P>做一件事一般会有个结果,当然,只是“一般会有”。有些事情真的会有结果吗?嗯?看来,这句话勾起某些同学一些旧事,他们陷入了深深的,似乎很痛苦的回忆之中……对此,为师我表示最大的理解,并有一言相送:“并非是一件事情不会有结果,只是,有时候,我们并不需要结果……”。</P>
<P> </P>
<P><B><FONT color=#ff0000>......[此处内容不发表在网页,请报名的学员使用</FONT><A
href="http://www.bcbschool.com/noused/v4_xiazai.htm"
target=_blank>课程下载器</A><FONT color=#ff0000>下载完整课程]......</FONT></B></P>
<P> </P>
<P>最后一点针对学过PHP,JavaScript,Perl等脚本语言的学员:在C,C++里,一个函数返回值的类型,必须是确定的。不像脚本语言中的函数,可以返回不定类型的结果。</P>
<H4><A name=12.2.5>12.2.5</A> 调用库函数的实例</H4>
<P><B>实例一:</B>使用库函数创建或删除文件夹。</P>
<P>(本例子中删除的文件夹将无法恢复!请大家操作时小心。)</P>
<P> </P>
<P>在本实例里,我们将“大胆地”在C盘根目录下创建指定的目录(文件夹),然后再把它删除。</P>
<P>使用到两个函数:</P>
<P>1、mkdir("文件夹名称")</P>
<P>参数是一个字符串,即指定的文件夹名称。</P>
<P>返回值比较特殊:整数:0表地成功,-1表示失败:比如那个文件夹已经存在,或者,你想让它一次创建多级目录,如:C:\abc\123,而C:\abc并不存在。</P>
<P>2、_rmdir("文件夹名称")</P>
<P>参数是一个字符串,即指定的文件夹名称。</P>
<P>返回同样是0或-1。删除一个文件夹比较容易失败:比如文件夹内还有文件或其它子文件夹,比如该文件夹正好是当前文件夹,另外你也不能删除一个根目录,比如你想删除:"c:\"
!!!(想删除整个C盘?病毒?)</P>
<P> </P>
<P>两个函数都在“dir.h”文件里声明,所以我们需要include它。</P>
<P> </P>
<P>下面是完整的代码:</P>
<P> </P>
<P><B><FONT color=#ff0000>......[此处内容不发表在网页,请报名的学员使用</FONT><A
href="http://www.bcbschool.com/noused/v4_xiazai.htm"
target=_blank>课程下载器</A><FONT color=#ff0000>下载完整课程]......</FONT></B></P>
<P> </P>
<P>代码里头有一个do...while循环,一个continue,和break;另有几个if...else,这些相信你可以边运行程序,边看明白其间的逻辑。惟一陌生的是最开头的一句:</P>
<P>char path[50];</P>
<P>这里涉及到了“数组”的知识。针对本例,你可以这样理解:</P>
<P>char ch; </P>
<P>这一行我们能看懂,定义了一个字符类型的变量,ch。ch变量的空间是1个字节,能存储一个字符,因此你可以用它存储诸如:'A','2','H'等,但现在我们要输入的是:"c:\abcd"这么一句话,所以变量ch无法胜任。C,C++提供了数组,我们可以通过定义数组来存储同一类型的多个数据。如:</P>
<P>char path[50];</P>
<P>本行定义了path这个数组,它可以存储50 个 char类型的数据。</P>
<P>注意,path只能存储最多50个字符。所以在运行本例时,不要输入太长的文件夹名称。</P>
<P>另外,Windows对新建文件夹的名称有一些特殊的要求,所以如果文件夹名称含了一些非法字符,操作将失败。</P>
<P>以下是我运行的一个结果:<BR></P>
<P><IMG height=220 src="教学--第十二章 函数(一)_files/ls12.h8.jpg" width=416
border=0></P>
<P> </P>
<H3><A name=12.3>12.3</A> 自定义函数</H3>
<P>学会如何调用别人的函数,现在我们来学习如何自已写一个函数。首先迅速看看函数的格式:</P>
<H4><A name=12.3.1>12.3.1</A> 函数的格式</H4>
<P>定义一个函数的语法是:</P>
<P> </P>
<P>返回类型 函数名(函数参数定义)</P>
<P>{</P>
<P> 函数体</P>
<P> </P>
<P> return 结果;</P>
<P>}</P>
<P> </P>
<P>其中:</P>
<P>1、返回类型: 指数据类型,如:int ,float,double, bool char ,void
等等。表示所返回结果的类型。如果是void则表示该函数没有结果返回。</P>
<P>2、函数名:命名规则和变量命名一样。注意要能够表达出正确的意义。如果说一个变量命名重在说明它“是什么”的话,则一个函数重在说明它要“做什么”。比如一个函数要实现两数相加,则可以命名为:AddTwoNum,这样有助于阅读。</P>
<P>3、函数参数定义:关于参数的作用,我们前面已说。现在看它的格式:</P>
<P>int AddTwoNum(int a,int b);</P>
<P>函数参数的定义有点类似定义变量,先写参数的数据类型,上例中是int,然后再写参数名。下面是不同之处:</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">3.1
多个参数之间用逗号隔开,而不是分号。最后一个变量之后则不需要符号。 请对比:</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">普通变量定义:</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">int a;
//<--以分号结束</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">int b;</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">函数中参数定义:</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">(int a, int b )
//以逗号分隔,最后不必以分号结束</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px"> </P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">3.2
两个或多个参数类型相同时,并不能同时声明,请对比:</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">普通变量定义:</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">int a,b;
//多个类型相同的变量可以一起定义。</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">函数中参数定义:</P>
<P style="MARGIN-LEFT: 10px; TEXT-INDENT: 40px">AddTwoNum(int a, b)
//这是错误的。</P>
<P>4、函数体:函数体用一对{}包括。里面就是函数用以实现功能的代码。</P>
<P>5、return 结果:return
语句其实属于函数体。由于它的重要性,所以单独列出来讲。“return”即“返回”,用来实现返回一个结果。“结果”是一个表达式。记住:当函数体内的代码执行到return语句时,函数即告结束,如果后面还有代码,则后面的代码不被执行。依靠流程控制,函数体里可以有多个return语句。当然,对于不需要返回结果的函数,可以不写return
语句,或者写不带结果的return语句。这些后面我们都将有例了演解。return 返回的结果,类型必须和前面“返回类型”一致。</P>
<P>一个最简单的例子,也比一堆说明文字来得直观,下面我写一个函数,用于实现两个整数,返回相加的和。这当然是一个愚不可及的函数,两数相加直接用+就得,写什么函数啊?</P>
<P> </P>
<P>//愚不可及的函数:实现两数相加</P>
<P>//参数:a:加数1,b:加数2;</P>
<P>//返回:相加的和</P>
<P>int AddTwoNum(int a, int b)</P>
<P>{</P>
<P> return a + b;</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -