📄 c44.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>可变参数的函数 </title>
<script language="javascript">
var prePage="http://www.nec.sjtu.edu.cn/support/Course/C/c/c4/c/c4/c43.htm";
var nextPage="c/c4/c45.htm";
</script>
<link rel="stylesheet" href="../cstyle.css" type="text/css">
</head>
<body background="../img/mainback.jpg" bgproperties="fixed">
<h2 align="center"><a name="_top"></a><font face="楷体_GB2312">4.4 可变参数的函数</font></h2>
<div align="center"><center>
<table border="0" width="100%" cellspacing="0" cellpadding="0">
<tr>
<td width="33%" align="center"><a href="c44.htm#c441.html#c441">引言</a></td>
<td width="33%" align="center"><a href="c44.htm#c442.html#c442">头文件<stdarg.h></a></td>
<td width="34%" align="center"><a href="c44.htm#c443.html#c443">一个例子</a></td>
</tr>
</table>
</center></div>
<hr>
<h3><a name="c441"></a>1.引言</h3>
<blockquote>
<font FACE="宋体" SIZE="3"><p ALIGN="JUSTIFY">C
语言支持函数的参数的个数和类型都是可变的, 这和其它语言不同.
它为程序员带来了很大的灵活性。</p>
<p ALIGN="JUSTIFY"><font color="#FF0000">注意</font>: 本课有点难度,
因此初学者可跳过本课。</p>
<p ALIGN="JUSTIFY">最显然的例子是格式化的输出函数: printf()
和格式化的输入函数: scanf()。(详细内容见 8.3 标准文件的格式化输入/输出)</p>
<p ALIGN="JUSTIFY">我们来看一个关于 printf()
的例子。它是有关可变参数的函数的最易理解的例子。</p>
<table border="6" width="85%" bgcolor="#CCFFFF" bordercolor="#FF9933" cellspacing="0"
cellpadding="0">
<tr>
<th width="46%" bgcolor="#FF9933"><p align="center">语句</th>
<th width="32%" bgcolor="#FF9933"><p align="center">输出</th>
<th width="22%" bgcolor="#FF9933"><p align="center">解释</th>
</tr>
<tr>
<td width="46%">main()<br>
{<br>
char c = 'a';<br>
static char str[] = "how now";<br>
int i = 1234;<br>
float x = -123.45;</td>
<td width="32%"> </td>
<td width="22%"> </td>
</tr>
<tr>
<td width="46%"> printf("%d\n",i);</td>
<td width="32%"><p align="center">1234</td>
<td width="22%">两个参数, 类型分别是串, int。</td>
</tr>
<tr>
<td width="46%"> printf("%.2f %d\n",x,i);</td>
<td width="32%"><p align="center">-123.45 1234</td>
<td width="22%">三个参数, 类型分别是串, float 和 int。</td>
</tr>
<tr>
<td width="46%"> printf("%.2f %d %c\n",<br>
x,i,c);</td>
<td width="32%"><p align="center">-123.45 1234 a</td>
<td width="22%">四个参数, 类型分别是串, float, int 和 char。</td>
</tr>
<tr>
<td width="46%"> printf("%.2f %d %c %s\n",<br>
x,i,c,str);</td>
<td width="32%"><p align="center">-123.45 1234 a how now</td>
<td width="22%">五个参数, 类型分别是串, float, int , char 和 string。</td>
</tr>
<tr>
<td width="46%">}</td>
<td width="32%"> </td>
<td width="22%"> </td>
</tr>
</table>
<p ALIGN="JUSTIFY"><br>
如何定义和说明可变参数的函数呢?</p>
<p ALIGN="JUSTIFY">在以前的 C 编译系统中,
你不能指定函数所期望的参数类型, 但是 ANSI C
鼓励你使用原型去那样做。为了支持如 printf() 那样的函数,
原型的语法包括一个特别的终止符, 即省略号...。</p>
<p ALIGN="JUSTIFY">因为一个 C
编译系统可能被要求做不寻常的事以处理一些个数变化的参数, 所以
ANSI C 要求这样的函数的说明和定义 都要包括省略号终止符。</p>
<p ALIGN="JUSTIFY">例如, printf() 可说明成 int printf(char *format, ...);</p>
<p ALIGN="JUSTIFY">作为扩展的情况,
函数可以被说明或定义为没有固定的参数, 如下所示:<br>
<font SIZE="3">int f(...);</font></p>
</font><p align="right"><a href="c44.htm#_top.html#_top">返回页首</a></p>
</blockquote>
<hr>
<h3><a name="c442"></a>2.头文件<stdarg.h></h3>
<blockquote>
<font FACE="宋体" SIZE="3"><p ALIGN="JUSTIFY">按照 ANSI C 标准中的规范说明,
以 <stdarg.h> 为界面的库包含着几个函数的宏,
它们提供了一种可移植的方法来控制可变参数表。<font color="#FF0000">注意</font>:
不是任何 C 编译器都支持头文件 <stdarg.h>, 仅仅那些遵照 ANSI C
标准的才支持这个文件。</p>
<p ALIGN="JUSTIFY">头文件 <stdarg.h> 说明了一个类型并定义了三个宏,
用来处理被调函数参数个数和类型未知的参数表。</p>
<p ALIGN="JUSTIFY">类型和宏列在下面:(<font color="#FF0000">请把鼠标移动到下面的语句上看解释</font>)</p>
<p ALIGN="JUSTIFY"><br>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=3,0,0,0" ID="c441"
WIDTH="505" HEIGHT="200">
<param name="movie" value="../movie/c441.swf">
<param name="quality" value="autohigh">
<param name="bgcolor" value="#FFFFCC"><embed SRC="../movie/c441.swf" swLiveConnect="FALSE" WIDTH="505" HEIGHT="200"
QUALITY="autohigh" BGCOLOR="#FFFFCC" TYPE="application/x-shockwave-flash"
PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">
</object>
<!-- EndAftershock c441.swf --> </p>
<p ALIGN="right"></font><a href="c44.htm#_top.html#_top">返回页首</a></p>
</blockquote>
<hr>
<h3><a name="c443"></a>3.一个例子</h3>
<blockquote>
<font FACE="宋体" SIZE="3"><p ALIGN="JUSTIFY">假定我们想写一个错误处理函数,
称作为 errmsg(), 返回值是 void, 它的唯一固定的参数是一个 int,
此整数指定错误信息的细节。此参数后面可以是一个文件名,
或一个行号, 或两者兼而有之, 这些参数都类似 printf() 的格式,
最后的参数指出出错信息的正文。</p>
<p ALIGN="JUSTIFY">这样, 此函数的说明(在适当的头文件中)将是:<br>
void errmsg(int code, ...);</p>
<p ALIGN="JUSTIFY">我们来看这个函数的定义:(<font color="#FF0000">请把鼠标移动到下面的语句上看解释</font>)<br>
</p>
<p>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=3,0,0,0" ID="c442"
WIDTH="505" HEIGHT="415">
<param name="movie" value="../movie/c442.swf">
<param name="quality" value="autohigh">
<param name="bgcolor" value="#FFFFCC"><embed SRC="../movie/c442.swf" swLiveConnect="FALSE" WIDTH="505" HEIGHT="415"
QUALITY="autohigh" BGCOLOR="#FFFFCC" TYPE="application/x-shockwave-flash"
PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">
</object>
</p>
<!-- EndAftershock c442.swf -->
<p ALIGN="JUSTIFY">假设宏 FILENAME, LINENUMBER, 和 WARNING 的定义与 errmsg()
的说明包含在同一个头文件中。</p>
<p ALIGN="JUSTIFY">我们看一下 errmsg() 的执行的结果。<br>
errmsg(FILENAME|WARNING, "make", "Can't open: %s\n",
"Makefile" );<br>
<font color="#FF0000">错误输出:</font> make: warning: Can't open:
Makefile</p>
<p ALIGN="JUSTIFY">请再看一下其它的调用。<br>
errmsg(FILENAME|LINENUMBER, "make", 9 , "Syntax error: %s\n"
,"stop!" );<br>
<font FACE="宋体" SIZE="3" color="#FF0000">错误输出:</font> make:
9: Syntax error: stop!</p>
</font>
</blockquote>
<p align="right"><a href="c44.htm#_top.html#_top">返回页首</a></p>
<p align="center"><a href="http://www.nec.sjtu.edu.cn/support/Course/C/c/c4/c45.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 + -