可变参数函数
来源:互联网 发布:js回调函数原理 编辑:程序博客网 时间:2024/06/06 04:41
C程序例子:为了了解可变参数函数汇中,参数读取的具体步骤,在add函数中本别用三个变量a,b,c来读取对应的参数。但在应用中,可用for循环,循环num次读取参数。
#include<stdio.h>#include<stdlib.h>#include<stdarg.h>//包含了va_list等宏,用于处理可变参数的函数//typedef char* valist; char指针类型int add(int num,...)//int num 告诉编译器函数有多少个参数,...代表参数可变{ int result = 0; int a,b,c; va_list argp;//typedef char * va_list; 创建一个指针 va_start(argp,num);//开始读取num个参数,读取结束后在把地址放在argp中 a = va_arg(argp,int);//va_arg()读取参数 b = va_arg(argp,int); c = va_arg(argp,int); va_end(argp); return a+b+c;}void main(){ int x = 3; int r; r = add(3,1,3,3);// printf("%d\n",r); getchar();}
可变参数分析:
- 首先要包含stdarg.h的头文件,因为里面包含处理可变参数函数的宏
- 可变参数函数的定义中至少定义一个参数,…代表可变参数。这个参数用于告诉编译器该函数还要传递的参数的个数,而且该参数在堆栈中的地址可用于定位其他参数的位置(因为上一个博客中已经得出这些参数是按顺序压入栈中的,而且存储单元是紧挨着的)。
可变参数函数读取实参的步骤:
1). va_list argp;//typedef char * va_list; 创建一个指针;PS:va = variable argument,创建的 指针共va_start和va_end使用
2).va_start(argp,num);//开始读取参数,argp指向除num外的最左边的参数
a =va_arg(argp,int);//按整数类型,从对应的堆栈中读取参数,argp+=4,argp指向b;
b = va_arg(argp,int);//按整数类型,从对应的堆栈中读取参数,argp+=4,argp指向c;
c =va_arg(argp,int);//按整数类型,从对应的堆栈中读取参数,argp+=4,;
va_end(argp);//结束读取,argp = 0;以下为对应反汇编程序及相应的注释
r = add(3,1,3,3);//004010CF push 3 //地址:0018FEEC004010D1 push 3 //地址:0018FEE8004010D3 push 1 //地址:0018FEE4004010D5 push 3 //地址:0018FEE0004010D7 call @ILT+0(_add) (00401005)//函数返回地址0018FEDC@ILT+0(_add):00401005 jmp add (00401020)int add(int num,...) //int num 告诉编译器函数有多少个参数,...代表参数可变8: {00401020 push ebp //地址:0018FED800401021 mov ebp,esp //此时ebp = 0018FED800401023 sub esp,54h00401026 push ebx00401027 push esi00401028 push edi00401029 lea edi,[ebp-54h]0040102C mov ecx,15h00401031 mov eax,0CCCCCCCCh00401036 rep stos dword ptr [edi]9: int result = 0.0;00401038 mov dword ptr [ebp-4],010: int a,b,c;11: va_list argp; //typedef char * va_list; 创建一个指针12:13: va_start(argp,num); //开始读取num个参数,读取结束后在把地址放在argp中0040103F lea eax,[ebp+0Ch] //0018FEE4 1的地址00401042 mov dword ptr [ebp-14h],eax //把1的地址即出num外的左边的第一个参数的地址赋值给argp14: a = va_arg(argp,int);00401045 mov ecx,dword ptr [ebp-14h]00401048 add ecx,4 //0018FEE8 2的地址,总是按int类型指向下一个单元0040104B mov dword ptr [ebp-14h],ecx0040104E mov edx,dword ptr [ebp-14h]00401051 mov eax,dword ptr [edx-4] 00401054 mov dword ptr [ebp-8],eax //读取0018FEE4 即1的值15: b = va_arg(argp,int);00401057 mov ecx,dword ptr [ebp-14h]0040105A add ecx,4 //0018FEEC 3的地址,总是按int类型指向下一个单元0040105D mov dword ptr [ebp-14h],ecx00401060 mov edx,dword ptr [ebp-14h]00401063 mov eax,dword ptr [edx-4]00401066 mov dword ptr [ebp-0Ch],eax //读取0018FEE8 即1的值16: c = va_arg(argp,int);00401069 mov ecx,dword ptr [ebp-14h]0040106C add ecx,4 //0018FEF0 ,总是按int类型指向下一个单元0040106F mov dword ptr [ebp-14h],ecx00401072 mov edx,dword ptr [ebp-14h]00401075 mov eax,dword ptr [edx-4]00401078 mov dword ptr [ebp-10h],eax17: va_end(argp);0040107B mov dword ptr [ebp-14h],0 //结束参数读取,对argp重新赋值18: return a+b+c;00401082 mov eax,dword ptr [ebp-8]00401085 add eax,dword ptr [ebp-0Ch]00401088 add eax,dword ptr [ebp-10h]19:20: }
0 0
- 可变参数 函数(可变参数列表--1)
- 可变参数函数 可变参数宏
- 可变参数函数
- 可变参数函数实现
- 可变参数函数
- 可变参数函数实现
- c可变函数参数
- 可变参数函数
- 可变参数函数
- 可变参数函数
- printf函数可变参数
- C可变参数函数
- 可变参数函数
- 可变参数函数使用
- 可变参数函数
- 可变参数函数
- 【转帖】可变参数函数
- 函数可变参数
- uvalive(NIM博弈)
- Android TextView 支持BBCode的显示
- WebStorm 注册码
- NYOJ 865 解题报告
- 《混合存储综述》 总结
- 可变参数函数
- DownloadManager实现文件下载
- c++ string 类的 ”数值转换“ 操作
- webStorm注册码
- Context源码解析
- 天声人語 20150726
- Hidden String
- Audio PCM
- 摘枇杷