zoukankan      html  css  js  c++  java
  • 可变参数函数(一)

    一个函数可以接受不定数的参数个数,这就是可变参数函数,比较常见的比如printf(),scanf();

    printf(const char* format,…);
    printf(“%d”,i);
    printf(“%s”,s);
    printf(“the number is %d,stirng is :%s”,i,s);

    变量参数函数的简单实现:

    #include<stdio.h>
    #include<stdarg.h>
    
    int simple(int num,...)
    {
        int i,result = 0;
        va_list vl;
        va_start(vl,num);
        printf("num:%d, vl:%d
    ",num,*vl);
        for(i = 0; i < num - 1 ; i++)
        {
            result = va_arg(vl,int);
            printf("in for result:%d ,*vl:%d
    ",result,*vl);
        }
        va_end(vl);
        return result;
    }
    
    int main()
    {
        int sum = simple(5,1,2,3,4,5);
        if(0 == sum)
        {
            printf("simple failed
    ");
        }
        else
        {
            printf("simple success! sum = %d
    ",sum);    
        }
        return 0;
    }

    结果如下:

    exbot@ubuntu:~/wangqinghe/DeBug/20190702$ ./VA

    num:5, vl:1020625376

    in for result:1 ,*vl:1020625376

    in for result:2 ,*vl:1020625376

    in for result:3 ,*vl:1020625376

    in for result:4 ,*vl:1020625376

    simple success! sum = 4

    sum.c
    #include<stdio.h>
    #include<stdlib.h>
    #include<stdarg.h>
    
    double add(int n,...)
    {
        //printf("add...
    ");
        int i = 0;
        double sum = 0;
        va_list argptr;  
        va_start(argptr,n);  //初始化argptr
        for(i = 0 ; i < n; i++) ////对每个可选参数,读取类型为int的参数
        {
            sum += va_arg(argptr,int);        //累加到sum中
        }
        va_end(argptr);    
        printf("add_sum = %f
    ",sum);
        return sum;
    }
    
    int main(int argc,char **argv)
    {
        double sum = 0;
        int *p = malloc(argc * sizeof(int));
        int i;
        for(i = 1; i < argc; i++)        
        {        
            p[i] = atoi(argv[i]);    
            printf("p[%d] = %d
    ",i,p[i]);
        }
    
        sum = add(argc,p[1]);
        printf("sum = %f
    ",sum);
        sum = add(argc,p[1],p[2]);
        printf("sum = %f
    ",sum);
        sum = add(argc,p[1],p[2],p[3]);
        printf("sum = %f
    ",sum);        
    
        free(p);
        return 0;
    }

    输出结果;

    exbot@ubuntu:~/wangqinghe/DeBug/20190702$ ./sum 10 20 30

    p[1] = 10

    p[2] = 20

    p[3] = 30

    add_sum = 239745405.000000

    sum = 239745405.000000

    add_sum = 56.000000

    sum = 56.000000

    add_sum = 69.000000

    sum = 69.000000

    相关函数介绍:

    可变函数列表的实现由几个宏组成的,在文件#include<stdarg.h>中。

    va_list 定义某个变量,内核的定义如下:

    typedef char *va_list;  //字符指针类型

    va_start(ap,type) 开始获取可变参数列表中第一个参数(…里面的第一个),也就是跳过第一个参数。(所以以上的第一个输出是个随机值)。

    #ifndef __sparc__
    #define va_start(AP, LASTARG)                         
     (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))//ap指向下一个参数,lastarg不变
    #else
    #define va_start(AP, LASTARG)                         
     (__builtin_saveregs (),                        
      AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) //跳过下第一个参数,指向第二个参数内存地址
    #endif
    
    //对type向上取整 取int的整 4,然后乘上int整型4的倍数
    #define __va_rounded_size(TYPE)  
      (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))

    Va_arg(args,int)循环获取可变参数列表中的参数,args指向下一个参数地址,返回的是当前参数地址。

    //  first=va_arg(args,int)
    #define va_arg(AP, TYPE)                        //ap指向下一个类型的参数
     (AP += __va_rounded_size (TYPE),                    //返回ap - sizeof(type)参数,即前一个参数
      *((TYPE *) (AP - __va_rounded_size (TYPE))))
    
    //对type向上取整 取int的整 4,然后乘上int整型4的倍数
    #define __va_rounded_size(TYPE)  
      (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))

    最后一个va_end(ap)结束标志,在程序中只是作为一个可变参数列表的结束标识,在stdarg.h中仅仅定义了一下,没有实现代码部分。

  • 相关阅读:
    整理用js实现tab标签页
    整理悬浮在列表中a元素时改变a元素上下边框颜色的问题。
    整理Javascript基础数据和引用数据复制值的问题
    这一周的学习整理
    关于变量作用域的一点整理
    Javascript 知识遗漏点梳理。
    安卓自定义TextView实现自动滚动
    解决 IntelliJ IDEA Tomcat 控制台中文输出乱码问题
    Tomcat 控制台UTF-8乱码问题
    java 实现hex文件转换bin保存至内存中
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11119490.html
Copyright © 2011-2022 走看看