當前位置:偏方大全网 - 偏方秘方 - C語言的使用...

C語言的使用...

c語言可變參數技術

摘要

C語言中有壹個長度不確定的參數,比如“…”,主要用在參數個數不確定的函數中,printf函數就是我們想到的最簡單的例子。

原型:

int printf( const char *format [,argument]...);

使用案例:

printf("享受每壹天!\ \ n ");

printf("值是%d!\\n ",值);

這個可變參數可以說是C語言的壹個難點,這裏會由幾個問題引發壹些分析。

註意:在C++中,有壹個函數重載可以用來區分不同函數參數的調用,但是仍然不能表示任意數量的函數參數。

問:printf的實現

請問printf函數怎麽實現,裏面的可變參數怎麽處理?答案和分析:

頭文件

typedef char * va _ list

# define va _ start(list)list =(char *)& amp;列表

#定義va_end(列表)

#define va_arg(list,mode)\\

((mode *)(list+= sizeof(mode)))[-1]

自己實現printf:

# include & ltstdarg.h & gt

int printf(char*格式,…)

{

va _ list ap

va_start(ap,格式);

int n = vprintf(format,AP);

va _ end(AP);

返回n;

}

問題:運行時確定的參數。

有沒有什麽方法可以寫出壹個函數,它的參數可以在運行時確定?

答案和分析:

目前還沒有“正常”的解決方法,但是有壹個獨壹無二的偏方,因為有壹個函數在這方面給我們做了壹個榜樣,就是main(),它的原型是:

int main(int argc,char * argv[]);

該函數的參數是argc和argv。

往深裏想,“參數形式只能在運行時確定”,也就是說從聲明中看不到被接受的參數,也就是參數根本沒有固定的形式。常見的方式是妳可以決定

意思是空虛

*類型參數,用它指向實際的參數區,然後根據需要在函數中任意解釋它們的含義。這是argv在主函數中的意義,而argc是用來表現現實的。

參數的個數,這為我們使用提供了進壹步的方便,當然這個參數不是必須的。

雖然參數沒有固定的形式,但我們必須分析函數中參數的含義。所以自然會有壹個要求,就是調用者和被調用者要在參數區內容的格式、大小、有效性等方面達成壹致,否則不同意就慘了。

問題:可變長度參數的傳輸

有時,需要編寫壹個函數,並將其變長參數直接傳遞給另壹個函數。這個要求能實現嗎?

答案和分析:

目前妳沒有辦法直接做到這壹點,但是我們可以繞道。首先我們將被調用函數的參數定義為va_list類型,同時在調用函數中將變長參數列表轉換為va_list,這樣就可以傳遞變長參數了。請看以下內容:

void subfunc (char *fmt,va_list argp)

{

...

arg = va_arg (fmt,argp);/*從argp中逐個取出需要的參數*/

...

}

void mainfunc (char *fmt,...)

{

va _ list argp

va_start (argp,fmt);/*將變長參數轉換為va_list */

subfunc (fmt,argp);/*將va_list傳遞給子函數*/

va _ end(argp);

...

}

問題:變長參數的類型是函數指針。

我想用va_arg從變長參數中提取類型為函數指針的參數,但結果總是不正確。為什麽?

答案和分析:

這和va_arg的實現有關。va_arg的簡單演示版本實現如下:

#define va_arg(argp,type) \\

(*(type *)(((argp)+= sizeof(type))-sizeof(type)))

其中argp的類型是char *。

如果妳想用va_arg從變量參數列表中提取函數指針類型的參數,例如

Int (*),那麽va_arg(argp,int (*))擴展為:

(*(int(*)()*)(((argp)+= sizeof(int(*))-sizeof(int(*))))

顯然,(int (*)() *)是沒有意義的。

解決這個問題的方法是用typedef將函數指針定義為獨立的數據類型,例如:

typedef int(* func ptr)();

此時,調用va_arg(argp,funcptr)將擴展為:

(*(funcptr *)(((argp)+= sizeof(funcptr))-sizeof(funcptr)))

這樣就可以通過編譯檢查了。

問題:獲取可變長度參數

有這樣壹個帶有可變長度參數的函數,其中使用了以下代碼來獲取float類型的參數:

va_arg (argp,float);

這樣做可以嗎?

答案和分析:

妳不能。在可變長度參數中,應用了“加寬”原則。即float類型擴展為double;char,

Short擴展為int。因此,如果要去變長參數float,需要使用va_arg(argp,

雙倍).對於char和short類型,使用va_arg(argp,int)。

問題:定義可變長度參數的限制

為什麽我的編譯器不允許我定義以下函數,也就是變長參數,但是沒有固定參數?

int f(...)

{

...

}

答案和分析:

妳不能。這是ANSI C所要求的,您必須定義至少壹個固定參數。

這個參數將被傳遞給va_start(),然後va_arg()和va_end()將被用來確定實際調用過程中所有變長參數的類型和值。

  • 上一篇:在農村地區建造房屋的風水公式
  • 下一篇:什麽是盆腔炎?
  • copyright 2024偏方大全网