电脑桌面
添加小米粒文库到电脑桌面
安装后可以在桌面快捷访问

C语言中可变参数的用法VIP免费

C语言中可变参数的用法_第1页
1/6
C语言中可变参数的用法_第2页
2/6
C语言中可变参数的用法_第3页
3/6
C語言中可變参數的用法——va_list、va_start、va_arg、va_end参數定義C語言可變参簡介我們在C語言編程中會遇到一些参數個數可變的函數,例如printf()這個函數,它的定義是這样的:intprintfC語言可變参簡介我們在C語言編程中會遇到一些参數個數可變的函數,例如printf()這個函數,它的定義是這样的:intprintf(constchar*format,...);它除了有一個参數format固定以外,後面跟的参數的個數和類型是可變的,例如我們可以有以下不同的調用方法:printf("%d",i);printf("%s",s);printf("thenumberis%d,stringis:%s",i,s);寫一個簡單的可變参數的C函數下面我們來探討如何寫一個簡單的可變参數的C函數.寫可變参數的C函數要在程序中用到以下這些宏:voidva_start(va_listarg_ptr,prev_param);typeva_arg(va_listarg_ptr,type);voidva_end(va_listarg_ptr);va在這裏是variable-argument(可變参數)的意思.這些宏定義在stdarg.h中,所以用到可變参數的程序應該包含這個頭文件.下面我們寫一個簡單的可變参數的函數,改函數至少有一個整數参數,第二個参數也是整數,是可選的.函數只是打印這兩個参數的值.voidsimple_va_fun(inti,...){va_listarg_ptr;intj=0;va_start(arg_ptr,i);j=va_arg(arg_ptr,int);va_end(arg_ptr);printf("%d%d\n",i,j);return;}我們可以在我們的頭文件中這样聲明我們的函數:externvoidsimple_va_fun(inti,...);我們在程序中可以這样調用:simple_va_fun(100);simple_va_fun(100,200);從這個函數的實現可以看到,我們使用可變参數應該有以下步驟:1)首先在函數裏定義一個va_list型的變量,這裏是arg_ptr,這個變量是指向参數的指針.2)然後用va_start宏初始化變量arg_ptr,這個宏的第二個参數是第一個可變参數的前一個参數,是一個固定的参數.3)然後用va_arg返回可變的参數,並賦值给整數j.va_arg的第二個参數是你要返回的参數的類型,這裏是int型.4)最後用va_end宏結束可變参數的獲取.然後你就可以在函數裏使用第二個参數了.如果函數有多個可變参數的,依次調用va_arg獲取各個参數.如果我們用下面三種方法調用的話,都是合法的,但結果卻不一样:1)simple_va_fun(100);結果是:100-123456789(會變的值)2)simple_va_fun(100,200);結果是:1002003)simple_va_fun(100,200,300);結果是:100200我們看到第一種調用有錯誤,第二種調用正確,第三種調用盡管結果正確,但和我們函數最初的設計有沖突.下面我們探討出現這些結果的原因和可變参數在編譯器中是如何處理的。可變参數在編譯器中的處理我們知道va_start,va_arg,va_end是在stdarg.h中被定義成宏的,由於1)硬件平台的不同2)編譯器的不同,所以定義的宏也有所不同,下面以VC++中stdarg.h裏x86平台的宏定義摘錄如下(’\’號表示折行):typedefchar*va_list;#define_INTSIZEOF(n)\((sizeof(n)+sizeof(int)-1)&~(sizeof(int)-1))#defineva_start(ap,v)(ap=(va_list)&v+_INTSIZEOF(v))#defineva_arg(ap,t)\(*(t*)((ap+=_INTSIZEOF(t))-_INTSIZEOF(t)))#defineva_end(ap)(ap=(va_list)0)定義_INTSIZEOF(n)主要是为了某些需要內存的對齊的系統.C語言的函數是從右向左壓入堆棧的,圖(1)是函數的参數在堆棧中的分布位置.我們看到va_list被定義成char*,有一些平台或操作系統定義为void*.再看va_start的定義,定義为&v+_INTSIZEOF(v),而&v是固定参數在堆棧的地址,所以我們運行va_start(ap,v)以後,ap指向第一個可變参數在堆棧的地址,如圖:高地址|-----------------------------||函數返回地址||-----------------------------||.......||-----------------------------||第n個参數(第一個可變参數)||-----------------------------|<--va_start後ap指向|第n-1個参數(最後一個固定参數)|低地址|-----------------------------|<--&v圖(1)然後,我們用va_arg()取得類型t的可變参數值,以上例为int型为例,我們看一下va_arg取int型的返回值:j=(*(int*)((ap+=_INTSIZEOF(int))-_INTSIZEOF(int)));首先ap+=sizeof(int),已經指向下一個参數的地址了.然後返回ap-sizeof(int)的int*指針,這正是第一個可變参數在堆棧裏的地址(圖2).然後用*取得這個地址的內容(参數值)賦给j.高地址|-...

1、当您付费下载文档后,您只拥有了使用权限,并不意味着购买了版权,文档只能用于自身使用,不得用于其他商业用途(如 [转卖]进行直接盈利或[编辑后售卖]进行间接盈利)。
2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。
3、如文档内容存在违规,或者侵犯商业秘密、侵犯著作权等,请点击“违规举报”。

碎片内容

C语言中可变参数的用法

确认删除?
VIP
微信客服
  • 扫码咨询
会员Q群
  • 会员专属群点击这里加入QQ群
客服邮箱
回到顶部