可变参数函数(二)
函數(shù)樣例:
#include<stdio.h> #include<stdlib.h> #include<stdarg.h>double add(int n,...) {int i = 0;double sum = 0;va_list argptr;va_start(argptr,n);for(i = 0 ; i < n; i++){double d = va_arg(argptr,double);printf("%d argument is %.3f\n",i,d); //獲取第i個(gè)double型的可變參數(shù)sum += va_arg(argptr,double); }va_end(argptr); return sum; }int main(int argc,char **argv) {double sum = 0;float *p = malloc(argc * sizeof(float));int i;for(i = 1; i < argc; i++) { p[i] = atof(argv[i]); //printf("p[%d] = %.3f\n",i,p[i]); }sum = add(1,p[1]); printf("sum = %.3f\n",sum);sum = add(2,p[1],p[2]); printf("sum = %.3f\n",sum);sum = add(3,p[1],p[2],p[3]); printf("sum = %.3f\n",sum);free(p);return 0; }運(yùn)行結(jié)果:
exbot@ubuntu:~/wangqinghe/DeBug/20190702$ gcc sum.c -o sum
exbot@ubuntu:~/wangqinghe/DeBug/20190702$ ./sum 10 20 30
0 argument is 10.000
sum = 0.000
0 argument is 10.000
1 argument is 0.000
sum = 20.000
0 argument is 10.000
1 argument is 30.000
2 argument is 0.000
sum = 20.000
?
測(cè)試:double d =? va_arg(argptr,double);是否只提取可變參數(shù)列表中double類型的數(shù)據(jù)
#include<stdio.h> #include<stdlib.h> #include<stdarg.h>double add(int n,...) {int i = 0;double sum = 0;va_list argptr;va_start(argptr,n);for(i = 0 ; i < n; i++){double d = va_arg(argptr,double);printf("%d argument is %.3f\n",i,d);sum += va_arg(argptr,double); }va_end(argptr); return sum; }int main(int argc,char **argv) {double sum = 0;float *p = malloc(argc * sizeof(float));int i;for(i = 1; i < argc; i++) { if(0 == i % 2) {p[i] = atof(argv[i]);printf("float : p[%d] = %.3f\n",i,p[i]); }}sum = add(1,p[1]); printf("sum = %.3f\n",sum);sum = add(2,p[1],p[2]); printf("sum = %.3f\n",sum);sum = add(3,p[1],p[2],p[3]); printf("sum = %.3f\n",sum);free(p);return 0; }運(yùn)行結(jié)果:
exbot@ubuntu:~/wangqinghe/DeBug/20190702$ ./sum 10 20 30 40 50 60 70
float : p[2] = 20.000
float : p[4] = 40.000
float : p[6] = 60.000
0 argument is 0.000
sum = 0.000
0 argument is 0.000
1 argument is 0.000
sum = 20.000
0 argument is 0.000
1 argument is 0.000
2 argument is 0.000
sum = 20.000
結(jié)論:可變參數(shù)的輸入類型要和使用的一致。(暫定)。
函數(shù)介紹:
va_list
這是一個(gè)適用于 va_start()、va_arg() 和 va_end() 這三個(gè)宏存儲(chǔ)信息的類型。
一般情況下va_list所定義變量為字符指針,即typedef char *va_list
該類型的變量用于存儲(chǔ)參數(shù)的地址。因?yàn)榈玫絽?shù)的地址之后,再結(jié)合參數(shù)的類型,才能得到參數(shù)的值。
?
va_start
宏原型是:
void va_start(va_list ap, last_arg)參數(shù):
ap是一個(gè) va_list 類型的對(duì)象,它用來存儲(chǔ)通過 va_arg 獲取額外參數(shù)時(shí)所必需的信息。
last_arg是最后一個(gè)傳遞給函數(shù)的已知的固定參數(shù)。?
該宏與 va_arg 和 va_end 宏是一起使用的,且必須在使用 va_arg 和 va_end 之前被調(diào)用。
?
va_arg
宏原型是:
type va_arg(va_list ap, type)其作用是從ap開始取一個(gè)type型的值返回,并且自動(dòng)將ap指向下一個(gè)參數(shù)。所以如果參數(shù)類型寫錯(cuò)了,例如將char*寫成char了,本來要取4個(gè)字節(jié),結(jié)果只取了一個(gè)字節(jié),ap本來要向后面移動(dòng)4個(gè)字節(jié),結(jié)果只移動(dòng)了一個(gè)字節(jié),后面的數(shù)據(jù)就全錯(cuò)了。
參數(shù):
ap是一個(gè) va_list 類型的對(duì)象,存儲(chǔ)了有關(guān)額外參數(shù)和檢索狀態(tài)的信息。該對(duì)象應(yīng)在第一次調(diào)用 va_arg 之前通過調(diào)用 va_start 進(jìn)行初始化。
type這是一個(gè)類型名稱。該類型名稱是作為擴(kuò)展自該宏的表達(dá)式的類型來使用的。?
返回值:該宏返回下一個(gè)額外的參數(shù),是一個(gè)類型為 type 的表達(dá)式。
?
注意:
va_arg宏的第2個(gè)參數(shù)不能被指定為char、short或者float類型。
因?yàn)閏har和short類型的參數(shù)會(huì)被轉(zhuǎn)換為int類型,而float類型的參數(shù)會(huì)被轉(zhuǎn)換為double類型。如果錯(cuò)誤的指定了,將會(huì)在程序中引起麻煩。
例如,這樣寫肯定是不對(duì)的:
c = va_arg(ap,char);因?yàn)槲覀儫o法傳遞一個(gè)char類型參數(shù),如果傳遞了,它將會(huì)被自動(dòng)轉(zhuǎn)化為int類型。上面的式子應(yīng)該寫成:
c = va_arg(ap,int);va_end
宏原型為:
void va_end(va_list ap)參數(shù):
ap是之前由同一函數(shù)中的 va_start 初始化的 va_list 對(duì)象。?
其作用是作用是將ap設(shè)置為NULL,如果在從函數(shù)返回之前沒有調(diào)用 va_end,則結(jié)果為未定義。
?
總結(jié)
使用可變長(zhǎng)參數(shù)的步驟:
?
1.聲明va_list變量;
2.使用va_start指定可變長(zhǎng)參數(shù)的位置;
3.使用va_arg來獲取參數(shù)值;
4.可選,使用va_end將va_list清零。
?
參考原文:https://blog.csdn.net/hmxz2nn/article/details/80445770
?
轉(zhuǎn)載于:https://www.cnblogs.com/wanghao-boke/p/11121054.html
總結(jié)