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\n", sum(4, 100,100,100,100));
    printf("%d\n", 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 != '\0');  
  
        va_end(arg);  
        return;  
}  
  
int main(int argc, char **argv) {  
        int i = 1234;  
        int j = 5678;  
        float f = 13.9;  
  
        printf_diy("i = %d\n", i);  
        printf_diy("j = %d\n", j);  
        printf_diy("f = %f\n", f);  
        return 0;  
}  

 

posted @ 2017-01-11 19:12  SongPF  阅读(396)  评论(0编辑  收藏  举报