可变参数,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

浙公网安备 33010602011771号