zoukankan      html  css  js  c++  java
  • C语言函数的变参实用与分析

    实现变参传递的关键是:

    传入参数在内存中是连续分布的。

    #define va_list void*
    #define va_arg(arg, type)     *(type*)arg; arg = (char*)arg + sizeof(type);
    #define va_start(arg, start)  arg = (va_list)(((char*)&(start)) + sizeof(start))
    #define va_end(arg)  arg = (void*)0

    这四个宏其实是c语言定义好的在stdarg.h中。
    通过va_start(arg, start)传入第一个参数以确定后面参数的地址。
    va_arg(arg, type)取出arg的值,并将地址指向下一个
    #include <stdio.h>
    
    #define va_list void*
    #define va_arg(arg, type)     *(type*)arg; arg = (char*)arg + sizeof(type);
    #define va_start(arg, start)  arg = (va_list)(((char*)&(start)) + sizeof(start))
    #define va_end(arg)  arg = (void*)0
    int sum(int nr, ...)
    {
        int i = 0;
        int result = 0;
        va_list arg = NULL;///不定类型指针
        va_start(arg, nr);//让指针指向第二个参数地址
    
        for(i = 0; i < nr; i++)
        {
            result += va_arg(arg, int);
        }
        va_end(arg);
        return result;
    }
    
    int main(int argc, char* argv[])
    {
        printf("%d
    ", sum(4, 100,100,100,100));
        printf("%d
    ", sum(3, 200, 200, 200));
    
        return 0;
    }
    #include <stdio.h>  
    #include <stdlib.h>  
    #include <stdarg.h>  
     /*
     
     #define va_list void*
    #define va_arg(arg, type)     *(type*)arg; arg = (char*)arg + sizeof(type);
    #define va_start(arg, start)  arg = (va_list)(((char*)&(start)) + sizeof(start))
    
    这些在stdarg.h中定义过
     */
    void printf_diy(char *fmt,...) {  
            va_list arg;  //定义一个不定类型指针
            char c;  
      
            va_start(arg, fmt);  //arg指向下一个参数
      
            do {  
                    c = *fmt;  
                    if(c != '%'){  
                            putchar(c); //输出  
                    }  
                    else {  
                            fmt++;  
                            switch(*fmt) {  
                            case 'd':  
                                    printf("%d", *((int*)arg));  
                                    break;  
                            case 'x':  
                                    printf("%#x", *((int*)arg));  
                                    break;  
                            case 'f':  
                                    printf("%f", *((float*)arg));  
                            default:  
                                    break;  
                            }  
      
                            va_arg(arg,int);  
                    }  
      
                    ++fmt;  
      
            } while (*fmt != '');  
      
            va_end(arg);  
            return;  
    }  
      
    int main(int argc, char **argv) {  
            int i = 1234;  
            int j = 5678;  
            float f = 13.9;  
      
            printf_diy("i = %d
    ", i);  
            printf_diy("j = %d
    ", j);  
            printf_diy("f = %f
    ", f);  
            return 0;  
    }  
  • 相关阅读:
    【css】所有的a标签设置为新窗口打开【原创】
    TP 3.1版本不支持 CONTROLLER_NAME
    关于TP 特殊页面伪静态规则的编写 研究实现
    larave PHP框架
    [转]git和github
    [转]mysql语句大全
    camera.swf?  提示  图片上传中请稍候,没任何报错
    mysql大小写敏感(默认为1,不敏感)
    数据cube的schema与sql的对应的关系
    MDX的实例讲解(排名前15的小例子)
  • 原文地址:https://www.cnblogs.com/PengfeiSong/p/6274853.html
Copyright © 2011-2022 走看看