(C语言)函数栈帧&可变参数列表&命令行参数

一 函数栈帧

1.认识相关寄存器

eax:通用寄存器,保存临时数据,常用于返回值。

ebx:通用寄存器,保存临时数据。

ebp:栈底寄存器。

esp: 栈顶寄存器。

eip: 指令寄存器,保存当前指令的下一条指令的地址。

2.认识相关汇编命令

mov: 数据转移指令

push: 数据入栈,同时esp栈顶寄存器也要发生改变。

pop:数据弹出至指定位置,同时esp栈顶寄存器也要发生改变。

sub:减法命令。

add: 加法命令。

call:函数调用,①压入返回地址。②转入目标函数。

jump:通过修改eip,转入目标函数,进行调用。

ret:恢复返回地址,压入eip,类似pop eip 命令。

3.函数栈帧总结

1.临时变量的形成是在函数正式被调用之前就形成了的。

2.形参实例化的顺序是从右向左的。

3.函数调用完毕,栈帧结构被释放。

4.临时变量具有临时性的本质:栈帧具有临时性。

5.调用函数是有成本的,成本体现在时间和空间上,本质是形成与释放栈帧有成本。

6.函数调用,因拷贝所形成的临时变量,变量和变量之间的位置关系是有规律的。

二 可变参数列表

1.注意事项

可变参数必须从头到尾逐个访问。如果你在访问了几个可变参数之后想半途终止,这是可以的,但是,如果你想一开始就访问参数列表中间的参数,那是不行的。参数列表中至少有一个命名参数。如果连一个命名参数都没有,就无法使用 va_start 。这些宏是无法直接判断实际存在参数的数量。
这些宏无法判断每个参数的是类型。如果在 va_arg 中指定了错误的类型,那么其后果是不可预测的

2.原理

先看看这几个宏的含义:
1. 可变参数列表对应的函数,最终调用也是函数调用,也要形成栈帧
2. 栈帧形成前,临时变量是要先入栈的,根据之前所学,参数之间位置关系是固定的
3. 通过上面汇编的学习,发现了短整型在可变参数部分,会默认进行整形提升,那么函数内部在提取该数据的时候,就要考虑提升之后的值,如果不加考虑,获取数据可能会报错或者结果不正确。
#include<stdio.h>
#include<stdarg.h>

//查找最大数据。
int FindMaxDate(int num, ...)
{
	va_list arg;    //定义可以访问可变参数部分的变量,其实是一个char*类型
	va_start(arg,num);   //使arg指向可变参数部分
	int max = va_arg(arg, int);  //根据类型,获取可变参数列表中的第一个数据
	for (int i = 0; i < num - 1; i++)//获取并比较其他的
	{
		int curr = va_arg(arg, int);
		if (max < curr)
		{
			max = curr;
		}
	}
	va_end(arg);//arg使用完毕,收尾工作。本质就是讲arg指向NULL
	return max;
}


int main()
{
	int max = FindMaxDate(5,1,2,5,4,9);
	printf("%d\n", max);
	return 0;
}

三  命令行参数

1.main函数也是可以带参数的。

#include <stdio.h> 
int main(int argc, char* argv[], char* envp[]) 
{ 
    int i = 0; 
     for(i=0; i<argc; i++) 
    {
        printf("%s\n", argv[i]); 
     }
    return 0; 
}

argc: 是个整型变量,表示命令行参数的个数(含第一个参数)。

argv :是个字符指针的数组,每个元素是一个字符指针,指向一个字符串。这些字符串就是命令行中的每一个参数(字符串)。

envp :是字符指针的数组,数组的每一个原元素是一个指向一个环境变量(字符串)的字符指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhang丶&|!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值