函数的多个参数va_list, va_start, va_avg, va_end的使用

来源:互联网 发布:福禄克网络官网 编辑:程序博客网 时间:2024/04/29 04:57

一, 函数的多个的参数的使用

#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);
  1. va_list 类型的 在C语言中是 typedef char* va_list;类型
  2. va_start(), 是把第一个参数连接链表 , 和字符对齐
  3. va_avg(), 连接多个参数成链表结构
  4. 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 80char 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;}
原创粉丝点击