va_start() va_end()函数应用
生活随笔
收集整理的這篇文章主要介紹了
va_start() va_end()函数应用
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1:當(dāng)無法列出傳遞函數(shù)的所有實(shí)參的類型和數(shù)目時(shí),可用省略號(hào)指定參數(shù)表void foo(...);
void foo(parm_list,...);
2:函數(shù)參數(shù)的傳遞原理
函數(shù)參數(shù)是以數(shù)據(jù)結(jié)構(gòu):棧的形式存取,從右至左入棧.eg:
?1?#include?<iostream>??
?2?void?fun(int?a,?)?
?3?{?
?4?int?*temp?=?&a;?
?5?temp++;?
?6?for?(int?i?=?0;?i?<?a;?++i)?
?7?{?
?8?cout?<<?*temp?<<?endl;?
?9?temp++;?
10?}?
11?}?
12?
13?int?main()?
14?{?
15?int?a?=?1;?
16?int?b?=?2;?
17?int?c?=?3;?
18?int?d?=?4;?
19?fun(4,?a,?b,?c,?d);?
20?system("pause");?
21?return?0;?
22?}?
Output::?
1?
2?
3?
4
3:獲取省略號(hào)指定的參數(shù)
在函數(shù)體中聲明一個(gè)va_list,然后用va_start函數(shù)來獲取參數(shù)列表中的參數(shù),使用完畢后調(diào)用va_end()結(jié)束。像這段代碼:?
1?void?TestFun(char*?pszDest,?int?DestLen,?const?char*?pszFormat,?)?
2?{?
3?va_list?args;?
4?va_start(args,?pszFormat);?
5?_vsnprintf(pszDest,?DestLen,?pszFormat,?args);?
6?va_end(args);?
7?}
8?
4.va_start使argp指向第一個(gè)可選參數(shù)。va_arg返回參數(shù)列表中的當(dāng)前參數(shù)并使argp指向參數(shù)列表中的下一個(gè)參數(shù)。va_end把a(bǔ)rgp指針清為NULL。函數(shù)體內(nèi)可以多次遍歷這些參數(shù),但是都必須以va_start開始,并以va_end結(jié)尾。
1).演示如何使用參數(shù)個(gè)數(shù)可變的函數(shù),采用ANSI標(biāo)準(zhǔn)形式?
?1?#include?〈stdio.h〉?
?2? #include?〈string.h〉?
?3? #include?〈stdarg.h〉?
?4? /*函數(shù)原型聲明,至少需要一個(gè)確定的參數(shù),注意括號(hào)內(nèi)的省略號(hào)*/?
?5? int?demo(?char,??);?
?6? void?main(?void?)?
?7? {?
?8? ?demo("DEMO",?"This",?"is",?"a",?"demo!",?"");?
?9? }?
10? /*ANSI標(biāo)準(zhǔn)形式的聲明方式,括號(hào)內(nèi)的省略號(hào)表示可選參數(shù)*/?
11? int?demo(?char?�msg,??)?
12? {?
13???/*定義保存函數(shù)參數(shù)的結(jié)構(gòu)*/
14? ?va_list?argp;?
15? ?int?argno?=?0;??
16? ?char?para;?
17?
18? ?/*argp指向傳入的第一個(gè)可選參數(shù),msg是最后一個(gè)確定的參數(shù)*/?
19? ?va_start(?argp,?msg?);?
20? ?while?(1)?
21???{?
22? ?para?=?va_arg(?argp,?char);?
23? ?if?(?strcmp(?para,?"")?==?0?)?
24???break;?
25? ?printf("Parameter?#%d?is:?%s\n",?argno,?para);?
26? ?argno++;?
27? ?}?
28? ?va_end(?argp?);?
29? ?/*將argp置為NULL*/
30? return?0;?
31? }?
2)//示例代碼1:可變參數(shù)函數(shù)的使用
?1?#include?"stdio.h"
?2?#include?"stdarg.h"
?3?void?simple_va_fun(int?start,?)?
?4?{?
?5???va_list?arg_ptr;?
?6???int?nArgValue?=start;
?7???int?nArgCout=0;?//可變參數(shù)的數(shù)目
?8???va_start(arg_ptr,start);?//以固定參數(shù)的地址為起點(diǎn)確定變參的內(nèi)存起始地址。
?9???do
10???{
11???++nArgCout;
12???printf("the?%d?th?arg:?%d\n",nArgCout,nArgValue);?//輸出各參數(shù)的值
13???nArgValue?=?va_arg(arg_ptr,int);?//得到下一個(gè)可變參數(shù)的值
14???}?while(nArgValue?!=?-1);??
15???return;?
16?}
17?int?main(int?argc,?char*?argv[])
18?{
19???simple_va_fun(100,-1);?
20???simple_va_fun(100,200,-1);?
21???return?0;
22?}
3)//示例代碼2:擴(kuò)展——自己實(shí)現(xiàn)簡單的可變參數(shù)的函數(shù)。
下面是一個(gè)簡單的printf函數(shù)的實(shí)現(xiàn),參考了<The C Programming Language>中的例子
?1?#include?"stdio.h"
?2?#include?"stdlib.h"
?3?void?myprintf(char*?fmt,?)?//一個(gè)簡單的類似于printf的實(shí)現(xiàn),//參數(shù)必須都是int?類型
?4?{?
?5???char*?pArg=NULL;?//等價(jià)于原來的va_list?
?6???char?c;
?7????
?8???pArg?=?(char*)?&fmt;?//注意不要寫成p?=?fmt?!!因?yàn)檫@里要對(duì)//參數(shù)取址,而不是取值
?9???pArg?+=?sizeof(fmt);?//等價(jià)于原來的va_start??
10??
11???do
12???{
13???c?=*fmt;
14???if?(c?!=?'%')
15???{
16???putchar(c);?//照原樣輸出字符
17???}
18???else
19???{
20???//按格式字符輸出數(shù)據(jù)
21???switch(*++fmt)?
22???{
23???case'd':
24???printf("%d",*((int*)pArg));??
25???break;
26???case'x':
27???printf("%#x",*((int*)pArg));
28???break;
29???default:
30???break;
31???}?
32???pArg?+=?sizeof(int);?//等價(jià)于原來的va_arg
33???}
34???++fmt;
35???}while?(*fmt?!=?'\0');?
36???pArg?=?NULL;?//等價(jià)于va_end
37???return;?
38?}
39?int?main(int?argc,?char*?argv[])
40?{
41???int?i?=?1234;
42???int?j?=?5678;
43????
44???myprintf("the?first?test:i=%d\n",i,j);?
45???myprintf("the?secend?test:i=%d;?%x;j=%d;\n",i,0xabcd,j);?
46???system("pause");
47???return?0;
48?}
void foo(parm_list,...);
2:函數(shù)參數(shù)的傳遞原理
函數(shù)參數(shù)是以數(shù)據(jù)結(jié)構(gòu):棧的形式存取,從右至左入棧.eg:
?1?#include?<iostream>??
?2?void?fun(int?a,?)?
?3?{?
?4?int?*temp?=?&a;?
?5?temp++;?
?6?for?(int?i?=?0;?i?<?a;?++i)?
?7?{?
?8?cout?<<?*temp?<<?endl;?
?9?temp++;?
10?}?
11?}?
12?
13?int?main()?
14?{?
15?int?a?=?1;?
16?int?b?=?2;?
17?int?c?=?3;?
18?int?d?=?4;?
19?fun(4,?a,?b,?c,?d);?
20?system("pause");?
21?return?0;?
22?}?
Output::?
1?
2?
3?
4
3:獲取省略號(hào)指定的參數(shù)
在函數(shù)體中聲明一個(gè)va_list,然后用va_start函數(shù)來獲取參數(shù)列表中的參數(shù),使用完畢后調(diào)用va_end()結(jié)束。像這段代碼:?
1?void?TestFun(char*?pszDest,?int?DestLen,?const?char*?pszFormat,?)?
2?{?
3?va_list?args;?
4?va_start(args,?pszFormat);?
5?_vsnprintf(pszDest,?DestLen,?pszFormat,?args);?
6?va_end(args);?
7?}
8?
4.va_start使argp指向第一個(gè)可選參數(shù)。va_arg返回參數(shù)列表中的當(dāng)前參數(shù)并使argp指向參數(shù)列表中的下一個(gè)參數(shù)。va_end把a(bǔ)rgp指針清為NULL。函數(shù)體內(nèi)可以多次遍歷這些參數(shù),但是都必須以va_start開始,并以va_end結(jié)尾。
1).演示如何使用參數(shù)個(gè)數(shù)可變的函數(shù),采用ANSI標(biāo)準(zhǔn)形式?
?1?#include?〈stdio.h〉?
?2? #include?〈string.h〉?
?3? #include?〈stdarg.h〉?
?4? /*函數(shù)原型聲明,至少需要一個(gè)確定的參數(shù),注意括號(hào)內(nèi)的省略號(hào)*/?
?5? int?demo(?char,??);?
?6? void?main(?void?)?
?7? {?
?8? ?demo("DEMO",?"This",?"is",?"a",?"demo!",?"");?
?9? }?
10? /*ANSI標(biāo)準(zhǔn)形式的聲明方式,括號(hào)內(nèi)的省略號(hào)表示可選參數(shù)*/?
11? int?demo(?char?�msg,??)?
12? {?
13???/*定義保存函數(shù)參數(shù)的結(jié)構(gòu)*/
14? ?va_list?argp;?
15? ?int?argno?=?0;??
16? ?char?para;?
17?
18? ?/*argp指向傳入的第一個(gè)可選參數(shù),msg是最后一個(gè)確定的參數(shù)*/?
19? ?va_start(?argp,?msg?);?
20? ?while?(1)?
21???{?
22? ?para?=?va_arg(?argp,?char);?
23? ?if?(?strcmp(?para,?"")?==?0?)?
24???break;?
25? ?printf("Parameter?#%d?is:?%s\n",?argno,?para);?
26? ?argno++;?
27? ?}?
28? ?va_end(?argp?);?
29? ?/*將argp置為NULL*/
30? return?0;?
31? }?
2)//示例代碼1:可變參數(shù)函數(shù)的使用
?1?#include?"stdio.h"
?2?#include?"stdarg.h"
?3?void?simple_va_fun(int?start,?)?
?4?{?
?5???va_list?arg_ptr;?
?6???int?nArgValue?=start;
?7???int?nArgCout=0;?//可變參數(shù)的數(shù)目
?8???va_start(arg_ptr,start);?//以固定參數(shù)的地址為起點(diǎn)確定變參的內(nèi)存起始地址。
?9???do
10???{
11???++nArgCout;
12???printf("the?%d?th?arg:?%d\n",nArgCout,nArgValue);?//輸出各參數(shù)的值
13???nArgValue?=?va_arg(arg_ptr,int);?//得到下一個(gè)可變參數(shù)的值
14???}?while(nArgValue?!=?-1);??
15???return;?
16?}
17?int?main(int?argc,?char*?argv[])
18?{
19???simple_va_fun(100,-1);?
20???simple_va_fun(100,200,-1);?
21???return?0;
22?}
3)//示例代碼2:擴(kuò)展——自己實(shí)現(xiàn)簡單的可變參數(shù)的函數(shù)。
下面是一個(gè)簡單的printf函數(shù)的實(shí)現(xiàn),參考了<The C Programming Language>中的例子
?1?#include?"stdio.h"
?2?#include?"stdlib.h"
?3?void?myprintf(char*?fmt,?)?//一個(gè)簡單的類似于printf的實(shí)現(xiàn),//參數(shù)必須都是int?類型
?4?{?
?5???char*?pArg=NULL;?//等價(jià)于原來的va_list?
?6???char?c;
?7????
?8???pArg?=?(char*)?&fmt;?//注意不要寫成p?=?fmt?!!因?yàn)檫@里要對(duì)//參數(shù)取址,而不是取值
?9???pArg?+=?sizeof(fmt);?//等價(jià)于原來的va_start??
10??
11???do
12???{
13???c?=*fmt;
14???if?(c?!=?'%')
15???{
16???putchar(c);?//照原樣輸出字符
17???}
18???else
19???{
20???//按格式字符輸出數(shù)據(jù)
21???switch(*++fmt)?
22???{
23???case'd':
24???printf("%d",*((int*)pArg));??
25???break;
26???case'x':
27???printf("%#x",*((int*)pArg));
28???break;
29???default:
30???break;
31???}?
32???pArg?+=?sizeof(int);?//等價(jià)于原來的va_arg
33???}
34???++fmt;
35???}while?(*fmt?!=?'\0');?
36???pArg?=?NULL;?//等價(jià)于va_end
37???return;?
38?}
39?int?main(int?argc,?char*?argv[])
40?{
41???int?i?=?1234;
42???int?j?=?5678;
43????
44???myprintf("the?first?test:i=%d\n",i,j);?
45???myprintf("the?secend?test:i=%d;?%x;j=%d;\n",i,0xabcd,j);?
46???system("pause");
47???return?0;
48?}
轉(zhuǎn)載于:https://www.cnblogs.com/phonefans/archive/2008/12/24/1361635.html
總結(jié)
以上是生活随笔為你收集整理的va_start() va_end()函数应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 斗罗大陆魂师对决夏日派对门票怎么获得?
- 下一篇: 关于ASP.NET Web 部件连接的引