本篇文章給大家分享的是有關(guān)如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
成都創(chuàng)新互聯(lián)專注于網(wǎng)站建設(shè)|成都網(wǎng)站維護(hù)|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計(jì)與制作經(jīng)驗(yàn),為許多企業(yè)提供了網(wǎng)站定制設(shè)計(jì)服務(wù),案例作品覆蓋發(fā)電機(jī)維修等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身定制品質(zhì)網(wǎng)站。
學(xué)習(xí)C的語言的時(shí)候,肯定接觸到標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)輸入函數(shù)。
這個(gè)函數(shù)給人的感覺很強(qiáng)大,因?yàn)樗芰眍?,就是這個(gè)函數(shù)的參數(shù)是可變的。
下面是一個(gè)自己編寫的可變參數(shù)的函數(shù),它的功能是求和。如下
#include <stdio.h>
#include <stdarg.h>
int sum(int data,...)
{
int i=data,s=0;
va_list vl;
va_start(vl,data);
while(i!=-1)
{
s+=i;
i=va_arg(vl,int);
}
va_end(vl);
return s;
}
int main()
{
int s=sum(1,2,3,4,5,-1);
printf("sum = %d\n",s);
return 0;
}
程序如上,注意以下幾點(diǎn)就可以編寫可變參數(shù)的函數(shù)了。
1.聲明
int sum(int data,...)
它的末尾是以...結(jié)束的,表示是可變參數(shù)函數(shù)。
2.正確使用
va_list
va_start,va_arg,va_end
如上,就可以編寫可變參數(shù)函數(shù)了。
不過大多數(shù)初級(jí)學(xué)者可能對(duì)
va_list
va_start,va_arg,va_end
望而卻步,認(rèn)為他們很神秘。
其實(shí)他們也是很基礎(chǔ)的C知識(shí),只是被包裝了。
C中包裝的方法,有 typedef,#define
例如你把int包裝成ID
typedef int ID;
其實(shí)
va_list
va_start,va_arg,va_end
他們也是包裝得到的。
va_list 就是一個(gè)指針類型。
va_start,va_arg,va_end,就是3個(gè)宏。
下面給出它們?cè)贑中的源碼
如上你可以在頭文件stdarg.h中查到,本文是針對(duì)VC6.0來說的,高版本的編譯器,在vadefs.h,它的定義是
類似的。
不過本文關(guān)鍵是說實(shí)現(xiàn)的原理:
首先在你調(diào)用一個(gè)可變參數(shù)函數(shù)時(shí),例如
上面的
int s=sum(1,2,3,4,5,-1);
這個(gè)函數(shù),編譯器會(huì)在內(nèi)存中分配空間存儲(chǔ)這些參數(shù)。
根據(jù)編譯器中從右至左的順序把參數(shù)壓棧。
這里的棧就是常說的存儲(chǔ)局部變量和函數(shù)參數(shù)的內(nèi)存空間。
這塊內(nèi)存空間是連續(xù)的。
因此我們只要能找到這塊內(nèi)存空間的首地址就可以了。然后每讀一個(gè)參數(shù),就加上這個(gè)參數(shù)在內(nèi)存空間中占
的大小,就是下一個(gè)參數(shù)的內(nèi)存地址,就這樣依次就可以得到每一個(gè)參數(shù)。
下面說下每個(gè)標(biāo)識(shí)的含義
1,va_list 就是一個(gè)char* 指針,用來記錄這個(gè)參數(shù)列表在內(nèi)存中地址。
2,va_start()
例如:va_start(vl,data);這個(gè)宏是得到參數(shù)列表中第2個(gè)參數(shù)內(nèi)存地址。
至于為什么不是第一個(gè),這和寫編譯器的程序員有關(guān),因?yàn)樗暮甓x,就是說明這個(gè)vl,注(vl就是va_list)
指向的就是第2個(gè)參數(shù)。
如上,v就是第一個(gè)參數(shù),ap就是va_list的變量,例如上面的
va_start(vl,data);
很明顯它先得到第一個(gè)參數(shù)內(nèi)存地址,然后又加上這個(gè)參數(shù)的內(nèi)存大小,就是下個(gè)參數(shù)的內(nèi)存地址。
注:因?yàn)榈谝粋€(gè)參數(shù),參數(shù)列表中已經(jīng)給出,所以它得到的是第2個(gè)參數(shù)的內(nèi)存地址。
3,va_arg
這個(gè)宏的意思,就是取得當(dāng)前vl所指的參數(shù),并且vl加上這個(gè)參數(shù)大小,指向下一個(gè)參數(shù)。
它的定義,明顯說明了這個(gè)問題。
它先加上參數(shù)類型t的大小,然后,在減去,參數(shù)類型t的大小,然后作強(qiáng)制類型轉(zhuǎn)換(t*),所以t一定要是類
型,不是變量。然后取*得到改地址指向的內(nèi)存中的數(shù)據(jù)。
例如實(shí)例中的
i=va_arg(vl,int);
第一次調(diào)用的時(shí)候,它得到就是參數(shù)列表中第二個(gè)參數(shù)的值。
下面依次調(diào)用就可以得到第三個(gè),第四個(gè)參數(shù)的值。。。
4,va_end
這個(gè)宏,就比較簡(jiǎn)單了。
就是把指針值歸0.讓它指向NULL。
也就是一個(gè)指針不用了,就會(huì)把它賦值為NULL.
如上明先可以看到
這個(gè)宏就是一個(gè)賦值語句。
ap=(char*)0;//va_list 就是cha*的別名。
其實(shí)只要把4個(gè)標(biāo)識(shí)
va_list
va_start,va_arg,va_end
的意思記住了,就可以編寫可變參數(shù)的函數(shù)。
使用的主要注意
va_start(ap,v)
v是第一個(gè)參數(shù)。
va_arg(ap,t)
t是你要取得的參數(shù)類型。
va_end(ap)
就是把指針ap賦值為0,使他不指向內(nèi)存的變量。
ap
就是
va_list的一個(gè)變量。也就是一個(gè)
char *類型的變量。
到此,我想你應(yīng)該對(duì)可變參數(shù)函數(shù)的實(shí)現(xiàn)原理有了一定的了解,起碼應(yīng)該有了形象的了解吧。
coder:huifeng00
以上就是如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
當(dāng)前文章:如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理
網(wǎng)站路徑:http://muchs.cn/article4/pipdoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、定制網(wǎng)站、靜態(tài)網(wǎng)站、品牌網(wǎng)站建設(shè)、網(wǎng)站制作、營銷型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)