va_start() va_end()函数应用
生活随笔
收集整理的這篇文章主要介紹了
va_start() va_end()函数应用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1:當無法列出傳遞函數的所有實參的類型和數目時,可用省略號指定參數表void foo(...);
void foo(parm_list,...);
2:函數參數的傳遞原理
函數參數是以數據結構:棧的形式存取,從右至左入棧.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:獲取省略號指定的參數
在函數體中聲明一個va_list,然后用va_start函數來獲取參數列表中的參數,使用完畢后調用va_end()結束。像這段代碼:?
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指向第一個可選參數。va_arg返回參數列表中的當前參數并使argp指向參數列表中的下一個參數。va_end把argp指針清為NULL。函數體內可以多次遍歷這些參數,但是都必須以va_start開始,并以va_end結尾。
1).演示如何使用參數個數可變的函數,采用ANSI標準形式?
?1?#include?〈stdio.h〉?
?2? #include?〈string.h〉?
?3? #include?〈stdarg.h〉?
?4? /*函數原型聲明,至少需要一個確定的參數,注意括號內的省略號*/?
?5? int?demo(?char,??);?
?6? void?main(?void?)?
?7? {?
?8? ?demo("DEMO",?"This",?"is",?"a",?"demo!",?"");?
?9? }?
10? /*ANSI標準形式的聲明方式,括號內的省略號表示可選參數*/?
11? int?demo(?char?�msg,??)?
12? {?
13???/*定義保存函數參數的結構*/
14? ?va_list?argp;?
15? ?int?argno?=?0;??
16? ?char?para;?
17?
18? ?/*argp指向傳入的第一個可選參數,msg是最后一個確定的參數*/?
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:可變參數函數的使用
?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;?//可變參數的數目
?8???va_start(arg_ptr,start);?//以固定參數的地址為起點確定變參的內存起始地址。
?9???do
10???{
11???++nArgCout;
12???printf("the?%d?th?arg:?%d\n",nArgCout,nArgValue);?//輸出各參數的值
13???nArgValue?=?va_arg(arg_ptr,int);?//得到下一個可變參數的值
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:擴展——自己實現簡單的可變參數的函數。
下面是一個簡單的printf函數的實現,參考了<The C Programming Language>中的例子
?1?#include?"stdio.h"
?2?#include?"stdlib.h"
?3?void?myprintf(char*?fmt,?)?//一個簡單的類似于printf的實現,//參數必須都是int?類型
?4?{?
?5???char*?pArg=NULL;?//等價于原來的va_list?
?6???char?c;
?7????
?8???pArg?=?(char*)?&fmt;?//注意不要寫成p?=?fmt?!!因為這里要對//參數取址,而不是取值
?9???pArg?+=?sizeof(fmt);?//等價于原來的va_start??
10??
11???do
12???{
13???c?=*fmt;
14???if?(c?!=?'%')
15???{
16???putchar(c);?//照原樣輸出字符
17???}
18???else
19???{
20???//按格式字符輸出數據
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);?//等價于原來的va_arg
33???}
34???++fmt;
35???}while?(*fmt?!=?'\0');?
36???pArg?=?NULL;?//等價于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:函數參數的傳遞原理
函數參數是以數據結構:棧的形式存取,從右至左入棧.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:獲取省略號指定的參數
在函數體中聲明一個va_list,然后用va_start函數來獲取參數列表中的參數,使用完畢后調用va_end()結束。像這段代碼:?
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指向第一個可選參數。va_arg返回參數列表中的當前參數并使argp指向參數列表中的下一個參數。va_end把argp指針清為NULL。函數體內可以多次遍歷這些參數,但是都必須以va_start開始,并以va_end結尾。
1).演示如何使用參數個數可變的函數,采用ANSI標準形式?
?1?#include?〈stdio.h〉?
?2? #include?〈string.h〉?
?3? #include?〈stdarg.h〉?
?4? /*函數原型聲明,至少需要一個確定的參數,注意括號內的省略號*/?
?5? int?demo(?char,??);?
?6? void?main(?void?)?
?7? {?
?8? ?demo("DEMO",?"This",?"is",?"a",?"demo!",?"");?
?9? }?
10? /*ANSI標準形式的聲明方式,括號內的省略號表示可選參數*/?
11? int?demo(?char?�msg,??)?
12? {?
13???/*定義保存函數參數的結構*/
14? ?va_list?argp;?
15? ?int?argno?=?0;??
16? ?char?para;?
17?
18? ?/*argp指向傳入的第一個可選參數,msg是最后一個確定的參數*/?
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:可變參數函數的使用
?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;?//可變參數的數目
?8???va_start(arg_ptr,start);?//以固定參數的地址為起點確定變參的內存起始地址。
?9???do
10???{
11???++nArgCout;
12???printf("the?%d?th?arg:?%d\n",nArgCout,nArgValue);?//輸出各參數的值
13???nArgValue?=?va_arg(arg_ptr,int);?//得到下一個可變參數的值
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:擴展——自己實現簡單的可變參數的函數。
下面是一個簡單的printf函數的實現,參考了<The C Programming Language>中的例子
?1?#include?"stdio.h"
?2?#include?"stdlib.h"
?3?void?myprintf(char*?fmt,?)?//一個簡單的類似于printf的實現,//參數必須都是int?類型
?4?{?
?5???char*?pArg=NULL;?//等價于原來的va_list?
?6???char?c;
?7????
?8???pArg?=?(char*)?&fmt;?//注意不要寫成p?=?fmt?!!因為這里要對//參數取址,而不是取值
?9???pArg?+=?sizeof(fmt);?//等價于原來的va_start??
10??
11???do
12???{
13???c?=*fmt;
14???if?(c?!=?'%')
15???{
16???putchar(c);?//照原樣輸出字符
17???}
18???else
19???{
20???//按格式字符輸出數據
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);?//等價于原來的va_arg
33???}
34???++fmt;
35???}while?(*fmt?!=?'\0');?
36???pArg?=?NULL;?//等價于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?}
轉載于:https://www.cnblogs.com/phonefans/archive/2008/12/24/1361635.html
總結
以上是生活随笔為你收集整理的va_start() va_end()函数应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 斗罗大陆魂师对决夏日派对门票怎么获得?
- 下一篇: 求一个微信网名情侣网名