可变参数,va_list; va_start ; va_end ;vsprintf 理解(转)

 

1 int printf(const char* fmt, ...)
 2 {
char outbuf[10240];
3 va_list args; 4 int i; 5 //1.将变参转化为字符串 6 va_start(args,fmt); 7 vsprintf((char *)outbuf, fmt, args); 8 va_end(); 9 //2. 打印字符串到串口 10 for(i=0;i< strlen((char *)outbuf); i++) 11 { 12 putc(outbuf[i]); 13 } 14 return i; 15 }

 

其中va_list( VA_LIST 是在C语言中解决变参问题的一组宏):va_list表示可变参数列表类型,实际上就是一个char指针fmt

然后是va_start:va_start用于获取函数参数列表中可变参数的首指针(获取函数可变参数列表) 

         1、输出参数args(类型为va_list): 用于保存函数参数列表中可变参数的首指针(即,可变参数列表)

         2、输入参数fmt: args指向fmt后面的参数,为第一个参数的前一个参数,是一个固定参数

vsprintf((char *)outbuf, fmt, args):送格式化输出到串中 ,函数说明:vsprintf()会根据参数fmt 字符串来转换并格式化数据, 然后将结果复制到参数char(*)outbuf 的字符串数组, 直到出现字符串结束('\0')为止.

va_end():va_end用于结束对可变参数的处理。

对于这段代码的理解:
 printf函数首先定义了一个char指针fmt,然后后面紧跟的是printf的变参,那么变参转换就开始了,下一个函数va_start定义了一个指向变参的首指针args,紧接着利用vsprintf函数,按照fmt格式以及通过args指针,将变参一个个按照规定好的格式转换数据,结果复制到char(*)outbuf这个数组中,最后结束可变参数处理。

这里我对于fmt这个指针的理解是,定义了一个指针类型,转换结果就是按照这个指针的类型转换的,这里转换的结果就是将变参转换成char字符型

 

https://www.cnblogs.com/smy87/p/9274705.html

 

#include <stdio.h>
#include <stdarg.h>

int myPrintf(int n, ...)
{
    int max = 0;
    int tmp = 0;
    /*
        #define va_start __crt_va_start
        #define va_arg   __crt_va_arg
        #define va_end   __crt_va_end
        #define va_copy(destination, source) ((destination) = (source))

        // 实现内存对齐
        #define _INTSIZEOF(n)          ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1)) 

        // 实现 ap 指向第一个可变参数
        #define __crt_va_start_a(ap, v) ((void)(ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v)))

        // 取出一个可变参数的值,指向下一个可变参数
        #define __crt_va_arg(ap, t)     (*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
        #define __crt_va_end(ap)        ((void)(ap = (va_list)0))
    */
    va_list args;   // typedef char* va_list;
    va_start(args, n);  // 实现args指向第一个可变参数
    if (n > 0) {
        do {
            tmp = va_arg(args, int);
            if (tmp > max)
                max = tmp;
            n--;
        } while (n > 0);
    }

    va_end(args);
    return max;
}

int main()
{
    int temp;
    temp = myPrintf(4,30,10,16);
    printf("max = %d\n",temp);
    printf("hello world\n");
    system("pause");
}

 

text:00411810 sub_411810      proc near               ; CODE XREF: sub_4112AD↑j
.text:00411810
.text:00411810 var_CC          = byte ptr -0CCh
.text:00411810 var_8           = dword ptr -8
.text:00411810
.text:00411810                 push    ebp
.text:00411811                 mov     ebp, esp
.text:00411813                 sub     esp, 0CCh
.text:00411819                 push    ebx
.text:0041181A                 push    esi
.text:0041181B                 push    edi
.text:0041181C                 lea     edi, [ebp+var_CC]
.text:00411822                 mov     ecx, 33h
.text:00411827                 mov     eax, 0CCCCCCCCh
.text:0041182C                 rep stosd
.text:0041182E                 mov     ecx, offset unk_41C003
.text:00411833                 call    sub_411212
.text:00411838                 push    16
.text:0041183A                 push    10
.text:0041183C                 push    30
.text:0041183E                 push    4
.text:00411840                 call    sub_411302
.text:00411845                 add     esp, 10h
.text:00411848                 mov     [ebp+var_8], eax
.text:0041184B                 mov     eax, [ebp+var_8]
.text:0041184E                 push    eax
.text:0041184F                 push    offset aMaxD    ; "max = %d\n"
.text:00411854                 call    sub_411046
.text:00411859                 add     esp, 8
.text:0041185C                 push    offset aHelloWorld ; "hello world\n"
.text:00411861                 call    sub_411046
.text:00411866                 add     esp, 4
.text:00411869                 push    offset Command  ; "pause"
.text:0041186E                 call    j_system_0
.text:00411873                 add     esp, 4
.text:00411876                 xor     eax, eax
.text:00411878                 pop     edi
.text:00411879                 pop     esi
.text:0041187A                 pop     ebx
.text:0041187B                 add     esp, 0CCh
.text:00411881                 cmp     ebp, esp
.text:00411883                 call    sub_41121C
.text:00411888                 mov     esp, ebp
.text:0041188A                 pop     ebp
.text:0041188B                 retn
.text:0041188B sub_411810      endp

 

posted @ 2019-07-04 16:27  狂奔~  阅读(1793)  评论(0)    收藏  举报