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

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

#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 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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值