va start和va end的使用

2021-06-18 16:09:18 字數 1249 閱讀 2475

1、由於在c語言中沒有函式過載,解決不定數目函式引數問題變得比較麻煩;即使採用c++,如果引數個數不能確定,也很難採用函式過載.

對這種情況,有些人採用指標引數來解決問題.下面就c語言中處理不定引數數目的問題進行討論.

2、下面是 裡面重要的幾個巨集定義如下:

typedef char* va_list;

void va_start ( va_list ap, prev_param ); /* ansi version */

type va_arg ( va_list ap, type ); 

void va_end ( va_list ap ); 

va_list 是乙個字元指標,可以理解為指向當前引數的乙個指標,取參必須通過這個指標進行。

3、函式引數是以棧的形式訪問,從右至左入棧。

舉個例子如下:void func(int x, float y, char z);

呼叫函式的時候,實參 char z 先進棧,然後是 float y,最後是 int x,因此在記憶體中變數的存放次序是 x->y->z,因此,從理論上說,我們只要探測到任意乙個變數的位址,並且知道其他變數的型別,通過指標移位運算,則總可以找到其他的輸入變數。

4、例項

#include#includevoid arg_test(int i, ...)

int main(int argc,char *argv)

5、讀取可變引數的過程其實就是堆疊中,使用指標,遍歷堆疊段中的引數列表,從低位址到高位址乙個乙個地把引數內容讀出來的過程.

6、雖然可以通過在堆疊中遍歷引數列表來讀出所有的可變引數,但是由於不知道可變引數有多少個,什麼時候應該結束遍歷,如果在堆疊中遍歷太多,那麼很可能讀取一些無效的資料.

解決辦法:a.可以在第乙個起始引數中指定引數個數,那麼就可以在迴圈還中讀取所有的可變引數;

b.定義乙個結束標記,在呼叫函式的時候,在最後乙個引數中傳遞這個標記,這樣在遍歷可變引數的時候,可以根據這個標記結束可變引數的遍歷;

7、典型應用:printf的實現

#include /* minprintf: minimal printf with variable argument list */

void minprintf(char *fmt, ...)

switch (*++p)

}va_end(ap); /* clean up when done */

}

va start和va end使用詳解

本文主要介紹va start和va end的使用及原理。在以前的一篇帖子format messagebox 詳解 中曾使用到va start和va end這兩個巨集,但對它們也只是泛泛的了解。介紹這兩個巨集之前先看一下c中傳遞函式的引數時的用法和原理 1.在c中,當我們無法列出傳遞函式的所有實參的型...

va start和va end使用詳解

介紹這兩個巨集之前先看一下c中傳遞函式的引數時的用法和原理 1.在c中,當我們無法列出傳遞函式的所有實參的型別和數目時,可以用省略號指定參數列 void foo void foo parm list,這種方式和我們以前認識的不大一樣,但我們要記住這是c中一種傳參的形式,在後面我們就會用到它。2.函式...

va start和va end使用詳解

本文主要介紹va start和va end的使用及原理。在以前的一篇帖子format messagebox 詳解 中曾使用到va start和va end這兩個巨集,但對它們也只是泛泛的了解。介紹這兩個巨集之前先看一下c中傳遞函式的引數時的用法和原理 1.在c中,當我們無法列出傳遞函式的所有實參的型...