?? 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 + -