c/c++多参数的问题
?C/C++語言有一個不同于其它語言的特性,即其支持可變參數,典型的函數如printf、scanf等可以接受數量不定的參數。如:
| printf ( "I love you" );? printf ( "%d", a ); printf ( "%d,%d", a, b ); |
第一、二、三個printf分別接受1、2、3個參數,讓我們看看printf函數的原型:
| int printf ( const char *format, ... ); |
從函數原型可以看出,其除了接收一個固定的參數format以外,后面的參數用"…"表示。在C/C++語言中,"…"表示可以接受不定數量的參數,理論上來講,可以是0或0以上的n個參數。
本文將對C/C++可變參數表的使用方法及C/C++支持可變參數表的深層機理進行探索。?
可變參數表的用法
1、相關宏
標準C/C++包含頭文件stdarg.h,該頭文件中定義了如下三個宏:
| void va_start ( va_list arg_ptr, prev_param ); /* ANSI version */ type va_arg ( va_list arg_ptr, type );? void va_end ( va_list arg_ptr ); |
在這些宏中,va就是variable argument(可變參數)的意思;arg_ptr是指向可變參數表的指針;prev_param則指可變參數表的前一個固定參數;type為可變參數的類型。va_list也是一個宏,其定義為typedef char * va_list,實質上是一char型指針。char型指針的特點是++、--操作對其作用的結果是增1和減1(因為sizeof(char)為1),與之不同的是int等其它類型指針的++、--操作對其作用的結果是增sizeof(type)或減sizeof(type),而且sizeof(type)大于1。
通過va_start宏我們可以取得可變參數表的首指針,這個宏的定義為:
| #define va_start ( ap, v ) ( ap = (va_list)&v + _INTSIZEOF(v) ) |
顯而易見,其含義為將最后那個固定參數的地址加上可變參數對其的偏移后賦值給ap,這樣ap就是可變參數表的首地址。其中的_INTSIZEOF宏定義為:
| #define _INTSIZEOF(n) ((sizeof ( n ) + sizeof ( int ) - 1 ) & ~( sizeof( int ) - 1 ) ) |
va_arg宏的意思則指取出當前arg_ptr所指的可變參數并將ap指針指向下一可變參數,其原型為:
| #define va_arg(list, mode) ((mode *)(list =\ (char *) ((((int)list + (__builtin_alignof(mode)<=4?3:7)) &\ (__builtin_alignof(mode)<=4?-4:-8))+sizeof(mode))))[-1] |
對這個宏的具體含義我們將在后面深入討論。
而va_end宏被用來結束可變參數的獲取,其定義為:
| #define va_end ( list ) |
可以看出,va_end ( list )實際上被定義為空,沒有任何真實對應的代碼,用于代碼對稱,與va_start對應;另外,它還可能發揮代碼的"自注釋"作用。所謂代碼的"自注釋",指的是代碼能自己注釋自己。
下面我們以具體的例子來說明以上三個宏的使用方法。
2、一個簡單的例子
| #include <stdarg.h> /* 函數名:max * 功能:返回n個整數中的最大值 * 參數:num:整數的個數 ...:num個輸入的整數 * 返回值:求得的最大整數 */ int max ( int num, ... ) { int m = -0x7FFFFFFF; /* 32系統中最小的整數 */ va_list ap; va_start ( ap, num ); for ( int i= 0; i< num; i++ ) { int t = va_arg (ap, int); if ( t > m ) { m = t; } } va_end (ap); return m; }? /* 主函數調用max */ int main ( int argc, char* argv[] ) {? int n = max ( 5, 5, 6 ,3 ,8 ,5); /* 求5個整數中的最大值 */ cout << n; return 0; } |
函數max中首先定義了可變參數表指針ap,而后通過va_start ( ap, num )取得了參數表首地址(賦給了ap),其后的for循環則用來遍歷可變參數表。這種遍歷方式與我們在數據結構教材中經常看到的遍歷方式是類似的。
函數max看起來簡潔明了,但是實際上printf的實現卻遠比這復雜。max函數之所以看起來簡單,是因為:
(1) max函數可變參數表的長度是已知的,通過num參數傳入;
(2) max函數可變參數表中參數的類型是已知的,都為int型。
而printf函數則沒有這么幸運。首先,printf函數可變參數的個數不能輕易的得到,而可變參數的類型也不是固定的,需由格式字符串進行識別(由%f、%d、%s等確定),因此則涉及到可變參數表的更復雜應用。
?
轉載于:https://blog.51cto.com/qingfeilove/1015068
總結
以上是生活随笔為你收集整理的c/c++多参数的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 频繁梦到亲人是怎么回事
- 下一篇: C++程序设计(第2版)课后习题答案--