程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++函數的可變參數詳談

C++函數的可變參數詳談

編輯:關於C++

可變參數的英文表示為:variable argument.

它在函數的定義時,用三個點號'.'表示,用逗號與其它參數分隔.

可變參數的特點:不像固定參數那樣一一對應,也不像固定參數有固定的參數類型和參數名稱;可變參數中個數不

定可是傳入的是一個參數也可以是多個;可變參數中的每個參數的類型可以不同,也可以相同;可變參數的每個參數並沒有

實際的名稱與之相對應.

由此可見,可變參數的形式非常自由而富有彈生.因些,它給那些天才程序員有更大地想象和發揮空間.

然而,更多地自由,同樣也加大操作上的難度.

以下就對可變參數的幾個方面作一定的介紹.

1)可變參數的存儲形式.

大家都知道,一般函數的形參屬於局部變量.而局部變量就是存儲在內存的棧區(所謂的棧區:由編譯器自動分配釋放,

存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。).可變參數也是存儲在內存棧區.

在對函數的形參存儲的時侯,編譯器是從函數的形參的右邊到左邊逐一地壓棧,

這樣保證了棧頂是函數的形參的第一個參數(從左到右數).而80x86平台下的內存分配順序是從高地址內存到低地址內存.

因此,函數的形參在內存的存儲形式如下圖(以fun(int var1,int var2,...,int var3,int var4)為例):

棧區:

|棧頂       低地址

|第一個固定參數var1

|可變參數前的第一個固定參數var2

|可變參數的第一個參數

|...

|可變參數的最後一個參數

|函數的倒數第二個固定參數var3

|函數的最後一個固定參數var4

|...

|函數的返回地址

|...

|棧底  高地址

2)使用可變參數所用到頭文件和相關宏說明

在此,以TC2.0編譯器為參考對象來說明.

可變參數的相關定義在TC2.0的名為"STDARG.H"的頭文件中.

此文件為:

/* stdarg.h
Definitions for ACCESSing parameters in functions that accept
a variable number of arguments.
Copyright (c) Borland International 1987,1988
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#if !defined(__STDARG)
#define __STDARG
typedef void *va_list;
#define va_start(ap, parmN) (ap = ...)
#define va_arg(ap, type) (*((type *)(ap))++)
#define va_end(ap)
#define _va_ptr  (...)
#endif

以上為"STDARG.H"的內容.

該文件定義了使用可變參數所用到的數據類型:typedef void *va_list;

va_start(ap,parmN)起到初始化,使用得ap指向可變參數的第一個參數.ap的類型為va_list,

parmN為可變參數的前面一個固定參數.

va_arg(ap,type)獲得當前ap所指向的參數,並使ap指向可變參數的下一個參數,type為需要獲得的參數的類型.

va_end(ap) 結束可變參數獲取.

3)可變參數的使用實例

實例目的:用可變參數來實現個數不定的字符串的傳遞,並顯示傳遞過來的字符串.

#include<stdio.h>
#include<conio.h>
#include<stdarg.h>
void tVarArg(int num,...);/*num為可變參數的個數*/
int main(void)
{
clrscr();
tVarArg(5,"Hello! ","My ","name ","is ","neverTheSame.n");
tVarArg(8,"This ","is ","an ","example ","about ","variable-argument ","in ","funtion");
getch();
return 0;
}
void tVarArg(int num,...)
{
va_list argp; /*定義一個指向可變參數的變量*/
va_start(argp,num); /*初始化,使用argp指向可變參數的第一個參數*/
while(--num>=0)
 printf("%s",(va_arg(argp,char*)));/*va_arg(argp,char*)獲得argp所指向的參數,
  並使用argp指向下一個參數,char*使用所獲得的參數的類型轉換為char*型.*/
va_end(argp); /*結束可變參數獲取*/
return ;
}

4)可變參數的使用需要注意的問題

1.每個函數的可變參數至多有一個.

2.va_start(ap,parmN)中parmN為可變參數前的一個固定參數.

3.可變參數的個數不確定,完全由程序約定.

4.可變參數的類型不確定,完全由va_arg(ap,type)中的type指定,然後就把參數的類型強制轉換.

而printf()中不是實現了識別參數嗎?那是因為函數

printf()是從固定參數format字符串來分析出參數的類型,再調用va_arg

的來獲取可變參數的.也就是說,你想實現智能識別可變參數的話是要通

過在自己的程序裡作判斷來實現的.

5.編譯器對可變參數的函數的原型檢查不夠嚴格,對編程人員要求很高.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved