from:http://blog.chinaunix.net/uid-21273878-id-1828735.html
|
首先分析一下_bnd(X, bnd)。
在使用过程中,_bnd(X, bnd)括号内的bnd是一个固定值:_ADNBND或者_AUPBND。这个值在这里都是3。
对于X,我们看看下面的例子:
char c;
_bnd(c, bnd) = ((sizeof(c)) + (3)) & (~(3)) = 4&0xFFFFFFFC = 4
int t;
_bnd(t, bnd) = ((sizeof(t)) + (3)) & (~(3)) = 7&0xFFFFFFFC = 4
double d;
_bnd(d, bnd) = ((sizeof(d)) + (3)) & (~(3)) = b&0xFFFFFFFC = 8
char str[15];
_bnd(str, bnd) = ((sizeof(str)) + (3)) & (~(3)) = 0x12&0xFFFFFFFC = 16
_bnd(X, bnd)给出了以4字节对齐 的变量X 的大小。
下面给出一个 具体 列子:
|
首先分析一下va_start(argptr, num):
(void) ((argptr) = ((char *)&num + 4)) 即
argptr = (char *)(0xbff69ce0 ) + 4 = (char *)( 0xbff69ce4 )
即 argptr 指向了下一个参数的地址。
再来解析 va_arg(argptr, double):
第一次for循环:
(* (double*) ((argptr += 8) - 8)) = (*(double *)( 0xbff69ce4 )) 即
取出了第一个用于计算的参数的数值。
注意:此时argptr的值是:argptr = argptr + 8 = 0xbff69cec , 即
指向了下一个参数的地址 。
第二次for循环:
(* (double*) ((argptr += 8) - 8)) = (*(double *)( 0xbff69cec ))即
取出了第二个用于计算的参数的值。
和第一次取数值一样,此时的argptr的值也变了,为: 0xbff69cf4。
对,如果有第三个参数,这就是第三个参数的地址。
明白了可变参数的这些取值方法,我们就可以自由使用了。