📄 c42.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>函数调用</title>
<script language="javascript">
var prePage="c/c4/c41.htm";
var nextPage="c/c4/c43.htm";
</script>
<link rel="stylesheet" href="../cstyle.css" type="text/css">
<bgsound src="../voice/c42.au" loop="1">
</head>
<body background="../img/mainback.jpg" bgproperties="fixed">
<h2 align="center"><font face="楷体_GB2312"><a name="_top"></a>4.2 函数调用</font></h2>
<div align="center"><center>
<table border="0" width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="33%" align="center"><a href="c42.htm#c421.html#c421">调用一个函数</a></td>
<td width="33%" align="center"><a href="c42.htm#c422.html#c422">嵌套调用函数</a></td>
<td width="34%" align="center"><a href="c42.htm#c423.html#c423">函数原型</a></td>
</tr>
</table>
</center></div>
<hr>
<h3><a name="c421"></a>1.调用一个函数</h3>
<blockquote>
<font SIZE="2"><p></font><img src="../img/c421.gif" alt="c421.jpg (2871 bytes)"
align="right" WIDTH="206" HEIGHT="60">当调用一个带形式参数的函数时,
我们用到实际参数。实际参数是在调用时赋给相应的形式参数的特殊的值。</p>
<p> </p>
<p>例子1: </p>
<p><font size="3"><font color="#000080">try(int i)</font>
<font color="#FF0000"><strong><em><----i:形式参数<br>
</em></strong></font><font color="#000080">{<br>
.......<br>
}<br>
main()<br>
{<br>
int number=1;</font> <font color="#FF0000"><strong><em>
<----这是实际参数 number 的值,即被传给形式参数 base 的值,它为1。</em></strong></font><br>
<font color="#000080">try(number); </font>
<font color="#FF0000"><strong><em><----- number:实际参数</em></strong></font><br>
<font color="#000080">}</font></font></p>
<p><img src="../img/c422.gif" alt="c422.jpg (2661 bytes)" align="right" WIDTH="202"
HEIGHT="68">实际参数可以是一个常量, 变量,
或甚至可以是一个表达式。</p>
<p> </p>
<p> </p>
<font face="宋体" size="3"><p ALIGN="JUSTIFY">例子2: </p>
<p ALIGN="JUSTIFY"><font color="#000080">try(int base)<br>
{<br>
base=base+5;<br>
}</font></font></p>
<p ALIGN="JUSTIFY"><font face="宋体" size="3"><font color="#000080">main()<br>
{<br>
int number=1;<br>
try(number);<br>
}</font></p>
<p ALIGN="JUSTIFY">上例中实在参数 number 和形式参数<font size="3"> base </font>占有不同的内存位置。</p>
<p ALIGN="JUSTIFY"> </p>
<p ALIGN="JUSTIFY">例子3: </p>
<p ALIGN="JUSTIFY"><font color="#000080">main()<br>
{<br>
float duff(int); /* 在调用的函数中说明 */<br>
int n;<br>
float q;<br>
...<br>
q=duff(n);<br>
...<br>
}</font></font></p>
<p ALIGN="JUSTIFY"><font face="宋体" size="3"><font color="#000080">float duff(int k)
/* 在函数定义中说明 */<br>
{<br>
float tor;<br>
...<br>
return(tor); /* 返回一个 float 值 */<br>
}</font></p>
<p ALIGN="JUSTIFY">在调用函数中,
被调用的函数的说明可以只包括圆括号和参数的类型以区别它是一个函数。</p>
</font><p ALIGN="right"><a href="c42.htm#_top.html#_top">返回页首</a></p>
</blockquote>
<hr>
<h3>2.<font size="3">嵌套调用函数</font></h3>
<blockquote>
<font face="宋体" size="3"><p ALIGN="JUSTIFY">一个 C
语言程序中的每一个函数与其它函数处于同等的地位。每一个可以调用
其它任何其它函数, 也可以被其它任何 函数调用。也就是说:
我们可以嵌套地调用函数<font size="3">, </font>但不能嵌套地定义函数。</p>
<p ALIGN="JUSTIFY">这使得 C 语言函数与 Pascal 过程有点儿不同, 因为<font
size="3"> Pascal </font>过程可以嵌套定义在其它过程中。</p>
<p ALIGN="JUSTIFY">例子1: <img src="../img/c423.gif" alt="c423.gif (63308 bytes)"
align="right" WIDTH="330" HEIGHT="90"></p>
<p ALIGN="JUSTIFY"></font><font face="宋体" color="#000080">echo()<br>
{<br>
......<br>
}</font></p>
<p ALIGN="JUSTIFY"><font face="宋体" color="#000080">recall()<br>
{<br>
...<br>
init();<br>
.......<br>
}</font></p>
<p ALIGN="JUSTIFY"><font face="宋体" color="#000080">main()<br>
{<br>
echo();<br>
recall();<br>
}</font><font face="宋体" size="3"></p>
</font><font size="3"><p><font color="#FF00FF">结论</font>: C </font><font face="宋体"
size="3">语言中允许嵌套地调用函数</font><font size="3">!</font></p>
<font face="宋体" size="3"><p ALIGN="JUSTIFY">例子2:</p>
<p ALIGN="JUSTIFY"><font color="#000080">main()<br>
{<br>
int i;<br>
...<br>
echo() </font><font color="#FF0000"><strong><em><-----错误!</em></strong></font><font
color="#000080"><br>
{<br>
..... <br>
}<br>
...<br>
echo();<br>
...<br>
}</font></p>
<p ALIGN="JUSTIFY"><font color="#FF00FF">结论</font>: C
语言中不允许嵌套地定义函数!你必须分别定义函数</font><font size="3">!</p>
</font><font FACE="宋体" SIZE="3"><p ALIGN="JUSTIFY">main() 函数是很特殊的吗?
是的, 是有一点特殊。在一个由几个函数组成的程序中, 总是从 main()
函数中的第一句开始执行<font size="3">!</font></p>
</font><p ALIGN="right"><a href="c42.htm#_top.html#_top">返回页首</a></p>
</blockquote>
<hr>
<h3>3.函数原型</h3>
<blockquote>
<font FACE="宋体" SIZE="3"><p ALIGN="JUSTIFY">一个函数其返回值若不是 int
的话, 就必须在使用之前加以说明。ANSI 标 准 C 更进了一步,
即允许你同时还能说明参数的个数和类型,
但老的标准在函数说明中不包括形式参数的类型。</p>
<p ALIGN="JUSTIFY">例如:</p>
<p ALIGN="JUSTIFY">ANSI C 标准的函数说明:</p>
<p ALIGN="JUSTIFY"><font color="#000080">main()<br>
{<br>
</font><font color="#800000"><blink>float func(int,float);</blink></font><font
color="#000080"><br>
...<br>
z=func(x,y);<br>
...<br>
}</font></p>
<p ALIGN="JUSTIFY">老的说明格式为:</p>
<p ALIGN="JUSTIFY"><font color="#000080">main()<br>
{<br>
</font><font color="#800000">float func();</font><font color="#000080"><br>
...<br>
z=func(x,y);<br>
...<br>
}</font></font></p>
<p ALIGN="JUSTIFY"><font FACE="宋体" SIZE="3">由 4.1 章节函数的定义可知,
定义函数的文法也作了改变<font size="3">, </font>这样说明和定义就可以匹配。这种扩充的定义和说明称为函数原型。用这种方法,
你能做有效的类似于 Pascal
语言的类型检查。当函数实参的类型与参数定义中的类型不一致时,
一个强类型语言的编译器会发出出错信息。</p>
<p ALIGN="JUSTIFY">我们将用一个返回值为其参数的立方的函数来说明函数原型。ANSI
C 标准的函数定义:</p>
<p ALIGN="JUSTIFY"></font><font face="宋体" color="#000080">double cube( double x )<br>
{<br>
return x*x*x;<br>
}</font><font FACE="宋体" SIZE="3"></p>
<p>参数</font><font size="3"> x </font><font FACE="宋体" SIZE="3">的类型</font><font
size="3">double </font><font FACE="宋体" SIZE="3">是紧跟在第一个左括号后说明的。</font></p>
<font FACE="宋体" SIZE="3"><p ALIGN="JUSTIFY">老的定义格式为:<br>
</font><font face="宋体" color="#000080">double cube( x )<br>
double x;<br>
{<br>
return x*x*x;<br>
}</font><font FACE="宋体" SIZE="3"></p>
<p ALIGN="JUSTIFY">有些编译器允许老的函数定义是为了对现有的 C
代码实现向上兼容。不过, 还是要强烈要求读者采用较新的函数原型<font
size="3">, </font>因为它具备了增强的类型检查的功能。</p>
<p ALIGN="JUSTIFY">下面的例子展示了一个短小但完整的 C 程序,
它采用了函数原型的定义和说明。</p>
<p ALIGN="JUSTIFY"></font><font face="宋体" color="#000080">#include <stdio.h><br>
main()<br>
{<br>
double cube (double); </font><font face="宋体"
color="#FF0000"><strong><em><--- 函数原型说明也可以写成这样:double
cube(double x);</em></strong></font><font face="宋体" color="#000080"><br>
printf("The cube of 2 is %.0f", cube(2.0));<br>
}</font></p>
<p ALIGN="JUSTIFY"><font face="宋体" color="#000080">double cube(double x)
</font><font face="宋体" color="#FF0000"><strong><em><---
函数原型定义</em></strong></font><font face="宋体" color="#000080"><br>
{<br>
return x*x*x;<br>
}</font><font FACE="宋体" SIZE="3"></p>
<p ALIGN="JUSTIFY">老的说明中没有参数类型的检查,
因此它的可靠性要差些。新的 ANSI
标准的函数原型说明能使编译器对参数类型进行检查。</p>
<p ALIGN="JUSTIFY">假使将第一次调用 cube() 函数变为:<br>
</font><font face="宋体" color="#000080">#include <stdio.h><br>
main()<br>
{<br>
double cube (double);<br>
printf("The cube of 2 is %.0f", cube(2.0,7.0) );
</font><font face="宋体" color="#FF0000"><strong><em><---
参数不匹配</em></strong></font><font face="宋体" color="#000080"><br>
}</font></p>
<p ALIGN="JUSTIFY"><font face="宋体" color="#000080">double cube(double x)<br>
{<br>
return x*x*x;<br>
}</font><font FACE="宋体" SIZE="3"></p>
<p ALIGN="JUSTIFY">如果用老的函数说明方式,
这个错误就不会被发觉。采用了新的函数原型的说明,
编译器会在执行时出错, 指示函数参数不匹配。</p>
<p ALIGN="JUSTIFY">在编译时发现错误当然比在运行时发现错误要更合人心意。一般来讲<font
size="3">, </font>一个错误发现得越早<font size="3">, </font>那么修改它的代价就越小。</p>
<p ALIGN="JUSTIFY">让我们看另外一个例子。</p>
<p ALIGN="JUSTIFY"></font><font face="宋体" color="#000080">float func(int,float);
</font><font face="宋体" color="#FF0000"><strong><em><---
函数原型说明</em></strong></font><font face="宋体" color="#000080"> <br>
main()<br>
{<br>
int x,y;<br>
x=10;<br>
y=10;<br>
func(x,y);
</font><font face="宋体" color="#FF0000"><strong><em><--- 类型不匹配</em></strong></font><font
face="宋体" color="#000080"> <br>
}</font></p>
<p ALIGN="JUSTIFY"><font face="宋体" color="#000080">float func(int x, float y)
</font><font face="宋体" color="#FF0000"><strong><em><---
函数原型定义</em></strong></font><font face="宋体" color="#000080"><br>
{<br>
printf("%f\n",y/(float)x);<br>
}</font><font FACE="宋体" SIZE="3"></p>
<p ALIGN="JUSTIFY">现在, 让我们来看一看一些函数原型说明的例子. </p>
<p ALIGN="JUSTIFY">例 1 </font><font face="宋体" color="#000080">void
srand(unsigned int seed);</font><font FACE="宋体" SIZE="3"><br>
解释: 函数 srand 无返回值; 它仅有一个 unsigned int 类形的参数。</p>
<p ALIGN="JUSTIFY">例 2 </font><font face="宋体" color="#000080">int rand(void);</font><font
FACE="宋体" SIZE="3"><br>
解释: 函数rand 返回一个 int; 它没有参数。如果函数没有参数,
那么原型说明中就可以将参数表用关键字 void 来代替。</p>
<p ALIGN="JUSTIFY">例 3 </font><font face="宋体" color="#000080">int strcmp(const
char *, const char *)</font><font FACE="宋体" SIZE="3"><br>
解释: 函数 strcmp 返回一个 整数; 它有两个参数, 都为 strcmp
不能改变的字符串指针。</p>
<p ALIGN="JUSTIFY">例 4 <font color="#000080">int fprintf(FILE *stream, const char
* format, ...)</font>;<br>
解释: 函数 fprintf 返回一个整数; FIlE 是在 stdio.h 中说明的类型名;
format 是一个限定为字符常量的指针; 注意<font size="3">: </font>省略号<font
size="3">(...) </font>表示参数数目未知。 详见<a href="http://www.nec.sjtu.edu.cn/support/Course/C/c/c4/c44.htm">4.4章节</a>
可变参数的函数</p>
</font><p align="right"><a href="c42.htm#_top.html#_top">返回页首</a></p>
</blockquote>
<p align="center"><a href="http://www.nec.sjtu.edu.cn/support/Course/C/c/c4/c43.htm"><img src="../img/next.gif" width="145" height="30"
alt="next.gif (3633 bytes)" border="0"></a></p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -