天天看點

C語言函數不定參數實作方式

函數如何實作不定參數:由于在C語言中沒有函數重載,解決不定數目函數參數問題變得比較麻煩,即使采用C++,如果參數個數不能确定,也很難采用函數重載。對這種情況,提出了指針參數來解決問題。

(1)va_list

定義了一個指針arg_ptr, 用于訓示可選的參數.

(2)va_start(arg_ptr, argN)

使參數清單指針arg_ptr指向函數參數清單中的第一個可選參數,argN是位于第一個可選參數之前的固定參數, 或者說最後一個固定參數.如有一va

函數的聲明是void va_test(char a, char b, char c, ...), 則它的固定參數依次是a,b,c, 最後一個固定參數argN為c, 是以就是va_start

(arg_ptr, c).

(3)va_arg(arg_ptr, type)

傳回參數清單中指針arg_ptr所指的參數, 傳回類型為type. 并使指針arg_ptr指向參數清單中下一個參數.傳回的是可選參數, 不包括固定參數.

(4)va_end(arg_ptr)

清空參數清單, 并置參數指針arg_ptr無效.

(注:va在這裡是variable-argument(可變參數)的意思.   這些宏定義在stdarg.h中,是以用到可變參數的程式應該包含這個頭檔案)

以下以幾個栗子來說明情況:

例1:

1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <stdarg.h>
 4 
 5 int print(const char *format, ...)
 6 {
 7     va_list args;
 8     const char *args1;
 9     va_start(args, format);
10     args1 = va_arg(args,const char *);
11     va_end(args);
12     printf("format=%s args1=%s", format, args1);
13 }
14 int main()
15 {
16     print("11111", "22222");
17 }      

運作結果:

1 /*
2 format=11111 args1=22222
3 Process returned 24 (0x18)   execution time : 0.542 s
4 Press any key to continue.
5 */      

例2:

1 例2:
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <stdarg.h>
 5 
 6 int print(const char *format, ...)
 7 {
 8     va_list args;
 9     const char *args1;
10     va_start(args, format);
11     args1 = va_arg(args,const char *);
12     va_end(args);
13     printf("format=%s args1=%s", format, args1);
14 }
15 
16 int main()
17 {
18     print("11111", "22222", "333333");
19 }      
1 /*
2 format=11111 args1=22222
3 Process returned 24 (0x18)   execution time : 0.542 s
4 Press any key to continue.
5 */      

我們從上面可以看見這樣在函數中加入三個參數是沒有問題的;

例3:

1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <stdarg.h>
 4 
 5 int print(const char *format, ...)
 6 {
 7     va_list args;
 8     const char *args1;
 9     va_start(args, format);
10     args1 = va_arg(args, const char *);
11     args2 = va_arg(args, const char *);
12     va_end(args);
13     printf("format=%s args1=%s", format, args1, args2);
14 }
15 
16 
17 int main()
18 {
19 
20     print("11111", "23333");
21 }      
1 /*
2 format=11111 args1=23333
3 Process returned 24 (0x18)   execution time : 0.153 s
4 Press any key to continue.
5 
6 */      

注意是上面并沒有三個參數,但是程式還是可以運作起來的! 

從上面三個例子可以看出我們傳入的參數都是一個類型的參數;

例4:

 不同類型的函數參數:

1 int print(const char *format, ...)
 2 {
 3     va_list args;
 4     int args1;
 5     va_start(args, format);
 6     args1 = va_arg(args, int);
 7     va_end(args);
 8     printf("format=%s args1=%d", format, args1);
 9 }
10 
11 
12 int main()
13 {
14 
15     print("11111", 123);
16 }      
1 /*
2 format=11111 args1=123
3 Process returned 22 (0x16)   execution time : 0.007 s
4 Press any key to continue.
5 */      

但是注意不能使用:

總之,va_arg(ap,type)中的type絕對不能為以下類型:

——char、signed char、unsigned char

——short、unsigned short

——signed short、short int、signed short int、unsigned short int

——float

繼續閱讀