当前位置:网站首页>可变长参数
可变长参数
2022-07-06 08:38:00 【飞天_】
目录
#include <stdio.h>
#include <stdarg.h>
void MultiArg(int prev_param, ...)
{
va_list arg_ptr;
//va_start将arg_ptr设置为传递到此函数的参数列表中的第一个可选参数。参数arg_ptr必须拥有va_list类型
//在首次使用va_arg前必须使用va_start
//va_arg从arg_ptr指定的位置中检索type的值,并增加arg_ptr以通过使用type的大小来确定下一个参数的开始位置
//来指向列表中的下一个参数
//prev_param是固定参数在内存中的地址,在调用va_start后,arg_ptr指向第一个可变参数。这个宏的作用就是在prev_param的内存地址上增加prev_param所占的内存大小,这样就得到了第一个可变参数的地址。
va_start(arg_ptr, prev_param);
for (int i = 0; i < prev_param; i++)
{
int value = va_arg(arg_ptr, int);
printf("第%d个可选参数=%d\n", i, value);
}
//检索所有参数后,重置va_end指向的指针NULL,在函数返回前必须在使用了va_start或va_copy初始化的各个参数列表上调用va_end
va_end(arg_ptr);
}
//最后一个参数需要是-1
void MulitArg_2(int prev_param,...)
{
va_list var_ptr;
va_start(var_ptr, prev_param);
int value = 0;
int i = 0;
//依次取出堆栈中的可选参数
while ((value = va_arg(var_ptr, int)) != -1)
{
printf("第%d个可选参数=%d\n", i++, value);
}
va_end(var_ptr);
}
int main()
{
MultiArg(5, 1, 2, 3, 4, 5);
MulitArg_2(0, 1, 2, 3, 4, 5, -1);
getchar();
return 0;
}
为什么可以实现可变长参数?
由栈结构和函数调用惯例决定的
程序的内存布局
现代的应用程序都运行在内存空间里,如果是32的操作系统,有32根地址线,最大可用地址空间为4G,2的32次方。大多数操作系统都会将4GB的内存空间中的一部分挪用给内核使用,应用程序无法直接访问这一段内存,这一部分内存地址称为内核空间。
Windows默认高地址的2GB作为内核空间
Linux默认高地址的1GB作为内核空间
剩下的3GB或2GB称为用户空间。
用户空间一般默认分类如下:
栈:最高地址处,通常用数兆字节
堆:栈下面,一般有几十数百兆容量
可执行文件映像:存储可执行文件在内存中的映像
保留区:内存中禁止访问的区域,在大多数操作系统中极小的地址是不被允许访问的,例如常见的NULL地址
Linux下一个进程里典型的内存布局:
栈
栈最重要的两个寄存器:ebp、esp。
ebp在栈中是固定不变的,始终指向栈底。(ebp寄存器又称为帧指针)
esp是一直变换的始终指向栈顶。
esp增大,栈空间减小,esp减小,栈空间增大。
用于保存一个函数调用所需要的维护信息的栈称为堆栈帧也叫活动记录。
堆栈帧一般包括:
1、函数的返回地址和参数
2、临时变量(非静态局部变量以及编译器自动生成的临时变量)
3、上下文(函数调用前后需要保持不变的寄存器)
一个常见的帧指针/活动记录如下所示:
函数调用惯例
函数的调用方和被调用方需要有一个明确的约定,参数是怎么传递的,函数名字是怎么修饰的,只有提前约定好了,才能保持正确的调用,这种约定就称为函数调用惯例。
变长参数的实现正是得益于C语言默认的cdecl调动惯例的自右向左压栈传递方式
调用可变长参数函数栈结构为:
MulitArg_2(0, 1, 2, 3, 4, 5, -1);
边栏推荐
- LDAP application (4) Jenkins access
- Summary of MySQL index failure scenarios
- Precise query of tree tree
- 【刷题】牛客网面试必刷TOP101
- The network model established by torch is displayed by torch viz
- The harm of game unpacking and the importance of resource encryption
- egg. JS project deployment online server
- C language double pointer -- classic question type
- Process of obtaining the electronic version of academic qualifications of xuexin.com
- 优秀的软件测试人员,都具备这些能力
猜你喜欢
[secretly kill little partner pytorch20 days -day01- example of structured data modeling process]
延迟初始化和密封类
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
leetcode刷题 (5.28) 哈希表
Hungry for 4 years + Ali for 2 years: some conclusions and Thoughts on the road of research and development
Beijing invitation media
Sort according to a number in a string in a column of CSV file
Generator parameters incoming parameters
Fairguard game reinforcement: under the upsurge of game going to sea, game security is facing new challenges
Problems in loading and saving pytorch trained models
随机推荐
同一局域网的手机和电脑相互访问,IIS设置
egg. JS project deployment online server
JS native implementation shuttle box
Research Report on Market Research and investment strategy of microcrystalline graphite materials in China (2022 Edition)
优秀的软件测试人员,都具备这些能力
堆排序详解
Chrome浏览器的crash问题
电脑清理,删除的系统文件
marathon-envs项目环境配置(强化学习模仿参考动作)
China dihydrolaurenol market forecast and investment strategy report (2022 Edition)
Leetcode question brushing (5.28) hash table
logback1.3. X configuration details and Practice
Hungry for 4 years + Ali for 2 years: some conclusions and Thoughts on the road of research and development
Mobile phones and computers on the same LAN access each other, IIS settings
Sort according to a number in a string in a column of CSV file
Purpose of computer F1-F12
MySQL learning record 10getting started with JDBC
移位运算符
[brush questions] top101 must be brushed in the interview of niuke.com
Browser thread