`
yeshaoting
  • 浏览: 666706 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

[不同编译器]函数参数求值顺序分析(附前置与后置++执行效率)

阅读更多

[不同编译器]函数参数求值顺序分析(附前置与后置++执行效率)


函数参数的求值顺序

 

函数参数的求值顺序跟不同语言编译器的处理方式有关,有些语言编译器从左向右处理,而有时从右往左处理.
这种编译器求值顺序的不同会相应地产生不同的输出结果.

测试程序:
向测试方法method(int a,int b)中传入类似于++x,x+y,x++的实参
.
e.g. method(++x,x+y),method(x+y,++x),...
根据输出结果的不同推出参数求值顺序.


. C语言编译环境

---------------------------------------前绪分析---------------------------------------

 

前置++程序:

 

// 前置++程序
// author: jarg
// http://jarg.iteye.com/

#include "stdio.h"

void main()
{
	int x = 2;
	printf("%d",++x);
	printf("%d",x);
}

 

C语言程序反汇编后的指令:

10:       int x = 2;
00401028   mov         dword ptr [ebp-4],2
11:       printf("%d",++x);
0040102F   mov         eax,dword ptr [ebp-4]
00401032   add         eax,1
00401035   mov         dword ptr [ebp-4],eax
00401038   mov         ecx,dword ptr [ebp-4]
0040103B   push        ecx
0040103C   push        offset string "%d" (00422fa4)
00401041   call        printf (00401090)
00401046   add         esp,8
12:       printf("%d",x);
00401049   mov         edx,dword ptr [ebp-4]
0040104C   push        edx
0040104D   push        offset string "%d" (00422fa4)
00401052   call        printf (00401090)
00401057   add         esp,8
13:   }

 

汇编指令解释:
第十条语句: int x = 2;对应汇编信息是mov dword ptr [ebp-4],2(dword ptr [ebp-4]是变量x的存储单元,语句是将值2放到变量x的存储单元中
).
第十一条语句(总共8条指令
):
0040102F~00401038:
变量x存储单元中的数值存入ax寄存器,然后ax寄存器中数值加1,再将ax寄存器中的数值存入变量x的存储单元,最后将变量x的存储单元中的数值存入cx寄存器中(总共4条指令
)
0040103B:
cx寄存器中的数值压入栈,作为函数的第二个实参值

0040103C:
将字符串"%d"压入栈,作为函数第一个实参值
00401041:
调用printf函数,执行函数过程

 

 

后置++程序:

// 后置++程序
// author: jarg
// http://jarg.iteye.com/

#include "stdio.h"

void main()
{
	int x = 2;
	printf("%d",x++);
	printf("%d",x);
}

 

 

 

 

 

C语言程序反汇编后的指令:

10:       int x = 2;
00401028   mov         dword ptr [ebp-4],2
11:       printf("%d",x++);
0040102F   mov         eax,dword ptr [ebp-4]
00401032   mov         dword ptr [ebp-8],eax
00401035   mov         ecx,dword ptr [ebp-8]
00401038   push        ecx
00401039   push        offset string "%d" (00422fa4)
0040103E   mov         edx,dword ptr [ebp-4]
00401041   add         edx,1
00401044   mov         dword ptr [ebp-4],edx
00401047   call        printf (00401090)
0040104C   add         esp,8
12:       printf("%d",x);
0040104F   mov         eax,dword ptr [ebp-4]
00401052   push        eax
00401053   push        offset string "%d" (00422fa4)
00401058   call        printf (00401090)
0040105D   add         esp,8
13:   } 

 

汇编指令解释:
第十条语句: int x = 2;对应汇编信息是mov dword ptr [ebp-4],2(dword ptr [ebp-4]是变量x的存储单元,语句是将值2放到变量x的存储单元中
).
第十一条语句(总共10条指令
):
0040102F~00401035:
变量x存储单元中的数值存入ax寄存器,再将ax寄存器中的数值存入变量x的存储单元的下一个存储单元,最后将变量x的存储单元的下一个存储单元中的数值存入cx寄存器中(总共3条指令
)
00401038:
cx寄存器中的数值压入栈,作为函数的第二个实参值

0040103C:
将字符串"%d"压入栈,作为函数第一个实参值
0040103E~00401044:
将变量x的存储单元中的数值存入dx寄存器,再将dx寄存器中的数值加1,最后最dx寄存器中的数值存入变量x的存储单元中
00401047:
调用printf函数,执行函数过程

 

结论(C语言编译环境下):
前置++与后置++程序不同就在于一个是++x,另一个是
x++;
这一区别造成了执行过程相差2条指令
.
由此可见,++x的执行效率高于x++.另外,前置++先执行x=x+1,然后将x值压入栈,做为函数实参值,调用函数;而后置++先将x值压入栈,做为函数实参值,然后执行x=x+1,再调用函数.

二个程序的printf函数的都是先处理第二个实参,压入栈;然后处理第一个实参,压入栈.
由此可见,C语言编译环境下函数求值顺序是从右向左
.
栈是一个先入后出的数据结构,最后一个实参先入栈,则会最后一个出栈,这样在函数从左向右顺序依次读取形参的时候,做出栈操作给对应的形参赋值.

 

---------------------------------------前绪分析---------------------------------------

 

 

 

 

 

C语言测试程序:

// 函数参数的求值顺序
// author: jarg
// http://jarg.iteye.com/
 
#include "stdio.h"

void main()
{
	int x = 2;
	printf("%d\t%d\t%d",x,++x,x++);
	printf("\t%d\n",x);
}

 

由前绪分析的结论已经得出: C语言编译环境下函数求值顺序是从右向左
初始化时x = 2,求值顺序是从右向左,则输出为3 3 2 4

输出结果:
3       3       2 4

 

 

. Java语言编译环境

 

Java语言测试程序:

// 函数参数的求值顺序
// author: jarg
// http://jarg.iteye.com/

public class Test
{
	public static void main(String[] args)
	{
		int x = 2;
		System.out.print("" + (x) + "\t" + (++x) + "\t" + (x++));
		System.out.print("\t" + x);
	}
}

 

初始化时x = 2,假设:
 
假设求值顺序是从左向右,则输出为
2 3 3 4
 
假设求值顺序是从右向左,则输出为3 3 2 4

 

输出结果:
2 3 3 4

 

结论(Java语言编译环境下):
由此可知,Java编译环境对函数求值顺序是按照函数参数声明顺序(符合我们正常思维逻辑)的从左向右
.
解释
:
虚拟机为每一个调用的Java(非本地)方法建立一个新的栈帧.栈帧包括:为方法的局部变量所预留的空间,该方法的操作数栈,以及特定虚拟机实现需要的其他所有的信息.局部变量和操作数栈大小在编译时计算出来,并设置到class文件中去,然后虚拟机就能够了解到方法的栈帧需要多少内存.当虚拟机调用一个方法的时候,它为该方法创建恰当大小的栈帆,再将新的栈帧压入Java
.
值得一提的Java编译器将Java方法的参数严格按照它们的声明顺序放到"局部变量数组"
.
处理方法时,虚拟机从所调用帧内的操作数栈中弹出实参值.虚拟机把对应的值存入局部变量数组参数对应位置,这种存入可以随机存入
.
C语言需要将后面参数得先入栈(先入后出结构),然后需要参数值的时候出栈供方法使用
.
这种不同导致编译器求值顺序的差异.

 

C语言编译环境下前置后置++执行过程类似,Java编译环境函数从左向右顺序求值情况下,++x在执行完x=x+1操作后才做传值操作,这就导致后面的x++中的x值变成3;表达式的输出结果也是3,不难看出x++是先做传值操作再完成的x=x+1操作,这一情况体现在下一条语句:System.out.print("\t" + x);,x输出的是4.
但是由于本人能力不够,不知道如何查看Java程序编译后类似于C语言汇编后的指令代码.因此,对于Java语言中二者执行效率孰高孰低不敢妄自定夺.姑且类推猜测前置++效率高于后置++.

 

 

本人才疏学浅,汇编描述以及Java编译环境结论解释的地方有不准确的地方,望海涵.

 

 

分享到:
评论

相关推荐

    Python课程设计 课设 手写数字识别卷积神经网络源码+文档说明.zip

    高分设计源码,详情请查看资源内容中使用说明 高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明高分设计源码,详情请查看资源内容中使用说明

    SpringBoot2.0快速开发框架权限.rar

    SpringBoot2.0快速开发框架权限.rarSpringBoot2.0快速开发框架权限.rarSpringBoot2.0快速开发框架权限.rar

    大语言模型的微调和推理baichuan7B, chatglm2-6B, Qwen-7B-chat源码.zip

    详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;

    基于Qt与STM32平台开发的汽车车机系统上位机

    基于Qt开发的汽车车机系统上位机 & 常见类型汽车传感器信号模拟发生器 任务和要求: 任务: 根据发动机测控系统信号需求,设计一套发动机信号模拟器人机交互系统,能够根据需要向下位机输出控制信号,使其输出发动机测控系统需要的传感器模拟信号,给发动机测控系统的开发提供方便。 要求: 1.设计应包含上位机与下位机的交互程序及人机交互界面的设计,与下位机设计相结合,使其能够实现全部类型发动机传感器信号的模拟输出及显示。 2.设计中需要采用模块化开发程序。 3.所设计的人机交互界面简洁合理。 4.应考虑所设计系统的实用性。 具体工作内容: 1.根据设计目标,查阅相关设计标准和设计方法资料,对发动机信号模拟器设计中的关键工程原理和工程方法进行提炼,并围绕关键问题进行国内外设计现状调研,开展分析、评价与总结,确定主要研究内容,制定设计技术路线,制定设计计划(周进度),撰写开题报告,并进行开题答辩,开题报告参考文献应不少于15篇(其中外文文献不少于 4 篇,近五年文献不少于三分之一)。 2.根据设计要求和技术指标,进行满足功能原理需求的多方案拟定,考虑安全、 标准等多因素进行技术性与经济性评价

    实验-三、数据库安全性(目的、要求和模板).doc

    实验-三、数据库安全性(目的、要求和模板).doc

    毕设绝技 - 4天玩乐完成商城系统完整资料day02

    文件为第二天视频教程 在毕业设计的挑战中,有时我们需要以极短的时间完成一个相对复杂的项目,比如一个商城系统。虽然时间紧迫,但只要我们合理规划、高效执行,完全有可能在4天内完成一个基础且功能完备的商城系统。 商城系统,也被称为网上商城系统或Online Mall system,是一种功能完善的网上销售系统。该系统主要包括产品发布、在线订购、在线支付、在线客服等功能模块,旨在为企业或个人提供一个在线销售平台,实现商品的展示、交易和客户服务。 商城系统具有多种核心功能,如商品管理、订单管理、用户管理和营销管理。商品管理功能支持商品的添加、编辑、删除、分类和搜索,满足商家对商品信息的全面管理需求。订单管理功能则涵盖订单的生成、支付、发货、退款和评价等环节,确保交易流程的顺畅进行。用户管理功能包括用户的注册、登录、个人信息管理和收货地址管理等,提升用户体验。而营销管理功能则通过促销活动的设置、优惠券的发放和积分兑换等手段,帮助商家提升销售业绩。 商城系统的特点主要体现在功能性、易用性和安全性上。商城系统注重功能性的开发,每个功能都有其发挥作用的地方,满足商家的实际需求。

    忻州师范学院-论文答辩PPT模板我给母校送模板作品.pptx

    PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。

    小型餐饮管理系统-数据库设计报告.doc

    小型餐饮管理系统-数据库设计报告.doc

    毕业设计+Python+基于OpenCV的交通路口红绿灯控制系统设计+Sqlite +PyCharm 1.zip.zip

    本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!! 本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!! 本资源中的源码都是经过本地编译过可运行的,下载后按照文档配置好环境就可以运行。资源项目的难度比较适中,内容都是经过助教老师审定过的,应该能够满足学习、使用需求,如果有需要的话可以放心下载使用。有任何问题也可以随时私信博主,博主会第一时间给您解答!!

    西南交通大学-毕业答辩PPT模板我给母校送模板作品.pptx

    PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。

    2024年中国中空纤维膜行业研究报告.docx

    2024年中国中空纤维膜行业研究报告

    四川师范大学-PPT模板我给母校送模板作品.pptx

    PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。

    实验三、数据库安全性实验报告.doc

    实验三、数据库安全性实验报告.doc

    西北农林科技大学-PPT模板我给母校送模板作品.pptx

    PPT模板,答辩PPT模板,毕业答辩,学术汇报,母校模板,我给母校送模板作品,周会汇报,开题答辩,教育主题模板下载。PPT素材下载。

    java电子相册源码.rar

    java电子相册源码.rarjava电子相册源码.rarjava电子相册源码.rarjava电子相册源码.rar

    玉米脱粒机设计及其总装配图(论文、dwg图).rar

    玉米脱粒机设计及其总装配图(论文、dwg图)

    studyopencv2

    studyopencv2

    2024-2030全球与中国牛肉卷饼市场现状及未来发展趋势.docx

    2024-2030全球与中国牛肉卷饼市场现状及未来发展趋势

    在KITTI车辆数据集,采用随机多尺度变化增强车辆训练集样本数量,采用k-means聚类获取最优先验候选框大小

    在KITTI车辆数据集,采用随机多尺度变化增强车辆训练集样本数量,采用k-means聚类获取最优先验候选框大小,引入到YOLOv3模型中,提升模型的车辆检测精度和鲁棒性。.zip

    基于Vue+SSM高校疫情信息管理系统源码.zip

    详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;详情请查看资源内容中使用说明;

Global site tag (gtag.js) - Google Analytics