zoukankan      html  css  js  c++  java
  • 理解可变参数的原理

    今天在学习中,发现了函数的参数还可以是三个点的,让我有点奇怪。所以就去在网上查了一下,这个知识点称为“可变参数”。以下就是我对于可变参数的理解:

    知识储备:

    首先我们先了解一个知识点:在《STL源码剖析》这本书中,空间配置器那一章节中二级空间配置,需要每此申请空间个数为8的整数倍。以下就是其实现的方式。image

     下来,我们来看可变参数是如何实现的?

    首先,我们来看一端代码:

    #include<stdio.h>
    //#include<stdarg.h>
    
    typedef char* va_list;
    #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
    
    #define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
    #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
    #define va_end(ap)      ( ap = (va_list)0 )
    
    int Avg(int n, ...) //可变参数的理解
    {
        int i;
        int sum = 0;
        va_list v1;
        va_start(v1, n);  //(v1 = (va_list)&n + _INTSIZEOF(n))
        for (i = 0; i < n; i++)
        {
            //(*(int *)((v1 += _INTSIZEOF(int)) - _INTSIZEOF(int)))
            sum += va_arg(v1, int);
        }
        va_end(v1);  //v1 = (va_list)0;
        return sum / n;
    }
    
    int main()
    {
        int avg = 0;
        avg = Avg(3, 10, 20, 30);
        printf("%d", avg);
        return 0;
    }

    实现原理:

    image

    实现说明:

    ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

    此步骤含义同上面的知识储备

    (v1 = (va_list)&n + _INTSIZEOF(n))   

    此步骤含义是将创建好的指针v1指向可变参数列表的第一个数据。

    (*(int *)((v1 += _INTSIZEOF(int)) - _INTSIZEOF(int)))

    此步骤含义是将创建好的指针向后移动,再减去sizeof(char)*4的偏移量,通过强转(int*)来取得参数的第一个值,循环移动,直至取至最后一个参数。

    v1 = (va_list)0;

    此步骤含义是将创建的指针v1赋值NULL(0);

     

  • 相关阅读:
    【分享】使用Vivado,vck190 BIST 测试,遇到错误“IDCODE/SW CHECK: FAILED”,可以忽略。
    公司预算制定/财务信息化/管理层执行
    税款输入不正确 j2
    发票凭证仍然包含信息
    会计暂估
    委托加工\受托加工凭证处理\会计处理
    记录unknown filesystem type ntfs
    c#多进程通讯,今天,它来了
    多线程通信,IPC,进程通信
    go语言跨平台编译
  • 原文地址:https://www.cnblogs.com/single-dont/p/11253451.html
Copyright © 2011-2022 走看看