一, 函数的多个的参数的使用
#include <stdarg.h>
void va_start(va_list ap, last);
type va_arg(va_list ap, type);
void va_end(va_list ap);
void va_copy(va_list dest, va_list src);
- va_list 类型的 在C语言中是 typedef char* va_list;类型
- va_start(), 是把第一个参数连接链表 , 和字符对齐
- va_avg(), 连接多个参数成链表结构
- va_end(), 销毁链表结构体
函数的api实现
va_list argptr;
--------------------------------
va_start(argptr, fmt);
--------------------------------
#define __crt_va_start(ap, x) __crt_va_start_a(ap, x)
--------------------------------
#define __crt_va_start_a(ap, v) \
((void)(ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v)))
--------------------------------
#ifdef __cplusplus
#define _ADDRESSOF(v) (&const_cast<char&>(reinterpret_cast<const volatile char&>(v)))
#else
#define _ADDRESSOF(v) (&(v))
#endif
--------------------------------
#define _INTSIZEOF(n) \
((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
~按位取反
&相同为1,不同为0
1 我们知道对于IX86,sizeof(int)一定是4的整数倍,所以~(sizeof(int) - 1) )的值一定是
右面[sizeof(n)-1]/2位为0,整个这个宏也就是保证了右面[sizeof(n)-1]/2位为0,其余位置
为1,所以_INTSIZEOF(n)的值只有可能是4,8,16,……等等,实际上是实现了字节对齐。
2 #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
的目的在于把sizeof(n)的结果变成至少是sizeof(int)的整倍数,这个一般用来在结构中实现按int的倍数对齐。
如果sizeof(int)是4,那么,当sizeof(n)的结果在1~4之间是,_INTSIZEOF(n)的结果会是4;当sizeof(n)的结果在5~8时,
_INTSIZEOF(n)的结果会是8;当sizeof(n)的结果在9~12时,_INTSIZEOF(n)的结果会是12;……总之,会是sizeof(int)的倍数。
理论基础:
对于两个正整数 x, n 总存在整数 q, r 使得
x = nq + r, 其中 0<= r
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
struct point {
double x, y;
};
struct point barycentre(int n, ...)
{
int i;
struct point t;
struct point sum = { 0 };
va_list listPointer;
va_start(listPointer, n);
for (i = 0; i<n; i++) {
t = va_arg(listPointer, struct point);
sum.x += t.x;
sum.y += t.y;
}
sum.x /= n;
sum.y /= n;
va_end(listPointer);
return sum;
}
int omain()
{
struct point a, b, c, bc;
a.x = rand() % 1000 / 100.0;
a.y = rand() % 1000 / 100.0;
b.x = rand() % 1000 / 100.0;
b.y = rand() % 1000 / 100.0;
c.x = rand() % 1000 / 100.0;
c.y = rand() % 1000 / 100.0;
bc = barycentre(3, a, b, c);
printf("The barycentre of the 3 points is (%f,%f).\n", bc.x, bc.y);
system("pause");
return 0;
}
使用例子
#define bufsize 80
char buffer[bufsize];
int vspf(char *fmt, ...)
{
va_list argptr;
int cnt;
va_start(argptr, fmt);
cnt = vsnprintf(buffer, bufsize, fmt, argptr);
va_end(argptr);
return(cnt);
}
int main(void)
{
int inumber = 30;
float fnumber = 90.0;
char string[4] = "abc";
vspf("%d %f %s", inumber, fnumber, string);
printf("%s\n", buffer);
system("pause");
return 0;
}