C語言可變引數函式探秘

2021-05-27 09:35:28 字數 1388 閱讀 6780

c語言的可變引數函式看起來是不很酷,必須printf之類的,初學時,一頭霧水,不禁感覺到宇宙的浩瀚和自己的渺小啊,但是等你知道其中原理之後,也就淡定了:)

下面首先看乙個程式:

#include "stdarg.h"

#include double addmanynum(int n, ...)

va_end(arglist);

return sum;

}int main()

這就是乙個典型的可變引數函式

va_start

va_arg

va_end

跟進之後發現其定義如下:

#define va_start _crt_va_start

#define va_arg _crt_va_arg

#define va_end _crt_va_end

再跟進他們的巨集定義:

#define _intsizeof(n)   ( (sizeof(n) + sizeof(int) - 1) &~(sizeof(int) - 1) )

#define _crt_va_start(ap,v)  ( ap = (va_list)_addressof(v) + _intsizeof(v))

#define _crt_va_arg(ap,t)    ( *(t *)((ap += _intsizeof(t)) -_intsizeof(t)) )

#define _crt_va_end(ap)      ( ap = (va_list)0 )

分別解釋一下:

#define _intsizeof(n)   ( (sizeof(n) + sizeof(int) - 1) &~(sizeof(int) - 1) )

這個主要是位元組對齊,這裡是使用int占用位元組數對齊,所以32位平台的話應該是4位元組

#define _crt_va_start(ap,v)  ( ap = (va_list)_addressof(v) + _intsizeof(v))

這個函式主要是將ap的指標偏移到第乙個引數位置,在上面的函式中就是n後面的底乙個數

#define _crt_va_arg(ap,t)    ( *(t *)((ap += _intsizeof(t)) -_intsizeof(t)) )

這個就是根據t引數的大小,取下引數t的值;

上面函式的引數我都預設設定成double,所以處理起來簡單了不少,像printf這種支援變引數型別的函式的話,其內部會先對格式字串進行處理,然後得出每個引數的型別,再去取相應的引數值。

#define _crt_va_end(ap)      ( ap = (va_list)0 )

將引數列表指標置零

看到這裡以前不會的同學是不是淡定了很多呢,呵呵

C語言函式可變引數

翻apue的時候,看到了一組可變引數的巨集就是va list 類似 void print arg int count,1 va list變數 ifdef m alpha typedef struct va list else typedef char va list 這個 endif 2 intsi...

C語言可變引數函式

今天在c和指標書中第一次接觸到這個函式,以前有碰到過這樣可變引數的問題,但無從下手。原來c語言還是有這樣的功能,感覺c真是無所不能。c函式要在程式中用到以下這些巨集 void va start va list arg ptr,prev param type va arg va list arg pt...

C語言 可變引數函式

可變引數函式,即引數個數可變的函式。返回值 函式名 固定引數m個,可變引數n個 其中,m 1,n 0,即 至少需要乙個固定引數,否則你怎麼定位到引數呢?固定引數的宣告與普通函式引數相同 可選引數由於數目不定 0個或以上 宣告時用 表示 用作引數佔位符 固定引數和可選引數共同構成可變引數函式的引數列表...