C語言可變參數實現

來源:互聯網
上載者:User

第一:什麼是可變參數
int printf(const char* format, ...);
看到printf的定義大家就知道了,只有一個固定的const char*參數,後面的都是不定長的參數列表了。

第二:自己寫一個可變參數函數
1.參數形參方式,跟printf類似,第一個為固定參數,後面的用...代替;
2.包含stdarg.h標頭檔,因為需要用到幾個裡面定義的宏;
void va_start(va_list arg_ptr, prev_param);
type va_arg(va_list arg_ptr, type);
void va_end(va_list arg_ptr);
va是variable argument可變參數的意思。
3.函數裡面定義一個va_list類型的變數,它是儲存參數地址的指標,因為得到參數的地址之後,再結合參數的類型,才能得到參數的值。
4.用va_start宏初始化3中定義的va_list類型變數,
5.用va_arg宏獲得下一個參數的值
6.設定結束條件。
例子程式:
1#include<stdio.h>
2#include<stdarg.h> //required by variable argument list
3
4void simple_va_function(int start, ){
5 va_list arg_ptr;
6 int nArgValue = start;
7 int nArgCount = 0; //count of arguments
8 va_start(arg_ptr, start); //to obtain beginning address of variable arguments base on the given arguemnt
9 do{
10 nArgCount++;
11 printf("The %d argument is %d.\n", nArgCount, nArgValue);
12 nArgValue = va_arg(arg_ptr, int);
13 }while(nArgValue != -1);
14 va_end(arg_ptr);
15 return;
16}
17
18int main(){
19 simple_va_function(1, 2, 3, 4, -1); //need to set a flag to specify the end of argument list
20 return 0;
21}

第三:可變參數的編譯器實現原理,這幾個宏的實現。
首先列出stdarg.h裡面的宏定義(注意這個宏定義與硬體平台和編譯器有關,這裡是VC6的宏定義):
typedef char * va_list;
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 )
其中va_list被定為一般指標,有些機器使用void*,有些使用char*,反正都可以啦。
_INTSZEOF(n)是考慮了記憶體對齊後的變數佔用空間,自己考慮一下,代進去小於4位元組的類型進去算一下,就知道在這個平台上(32位機),記憶體對齊到4個位元組。
va_start就是求得第一個可變參數的地址
va_arg是求的下一個可變參數的地址存的值
va_end只是簡單地將指標置零

第四:小結
1.標準C庫的中的三個宏的作用只是用來確定可變參數列表中每個參數的記憶體位址,編譯器是不知道參數的實際數目的。
2.在實際應用的代碼中,程式員必須自己考慮確定參數數目的辦法
1)在固定參數設定標誌,例如printf的實現,有多少個%號則表明後面多少個參數
2)多設定一個可變參數標識參數列表結束
3.實現可變參數的要點就是想辦法取得每個參數的地址,取得地址的辦法由以下幾個因素決定:
①函數棧的生長方向
②參數的入棧順序
③CPU的對齊
④記憶體位址的表達方式,用void*表示一般地址還是char*
結合原始碼,我們可以看出va_list的實現是由④決定的,_INTSIZEOF(n)的引入則是由③決定的,他和①②又一起決定了va_start的實現,最後va_end的存在則是良好編程風格的體現,將不再使用的指標設為NULL,這樣可以防止以後的誤操作。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.