如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理

本篇文章給大家分享的是有關(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è)贑中的源碼

如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理

如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理

如上你可以在頭文件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ù)。

如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理

如上,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ù)函數(shù)的實(shí)現(xiàn)原理

它先加上參數(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.

如何解析可變參數(shù)函數(shù)的實(shí)現(xiàn)原理
如上明先可以看到

這個(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)

網(wǎng)站優(yōu)化排名