关于变量在for循环内外定义的思考
在c#或java里面,我们通常会这样写for循环:
for(int i = ;i<;i++)
{
Console.WriteLine(i);
}
前一阵子,我突发奇想,如果按照下面这样写,会不会比上面的运行效率高一些:
int i = 0;
for(; i<10 ;i++)
{
Console.WriteLine(i);
}
因为我觉得最上面的那种方式,每次循环都会声明一个变量,说不定会影响效率,于是百度了一下,发现其他人也有这个疑惑,特意百度了一些资料,在此做个综合。
首先是在内层循环中定义变量到底会不会存在重复分配的问题,这涉及到编译器的优化,不过主流编译器(如vs和gcc)这一块优化都比较好,不会反复分配变量。函数的定义是编译器的事情,运行的时候不存在什么定义,更没有什么开销。
除非是类对象或者结构体对象, 在for循环里面与外面, 开销可能会不一样.基本数据类型, 那是一样的, 编译器肯定会优化这个东西。
一般来说, 在进入函数时, 所有的栈变量都分配好空间了. 所以那个for变量写在哪里都是一样的. 具体你可以看一下反汇编代码, 全部就展现在你眼前了,我查看过C#的IL代码,发现两种写法的IL代码是一样的,说明没有区别。
栈中的空间在编译这个代码的时候大小就确定下来了,运行这个方法时空间就已经分配好了,不要想当然的以为声明一次就要分配一次空间,那是c语言,java可以重用这些超出作用域的空间。只要用javap查看方法字节码,看看使用的局部变量表的大小和使用方式即知java这种基于虚拟机的语言,是跟单纯的C不同,C语言的原则是相信程序员能做好一切,因此它不会帮你做多少事情,需要考虑代码优化,内存占用等。
不过,自己在编程的时候要注意不要让上一次的结果影响到下一次循环,比如上一次 a = 3, 当下一次循环在给a赋值的时候出了错误,而你捕获了错误,却没修正a的值,程序继续执行,那么这时候a=3还成立,可能就会有问题了,如果是每次都重新定义,那就不存在这样的问题。
最后总结:
- 对于使用int等基本数据类型作为循环变量,只要你用的优化方面足够给力的主流的编译器,完全不需要关心在循环外还是循环内定义循环变量。
- 如果循环变量本身是复杂的对象,建议在循环外定义好,并且在
for循环的赋值语句、判断语句中,都要避免重复创建对象。
关于变量在for循环内外定义的思考的更多相关文章
- 关于Java语言for循环内外变量定义的问题
今天看书时,看到一个代码,一个在循环外面没有用的变量,后即有了我的问题,在后面: 我的问题: 变量循环内定义,例如:while(true){String splitStr = null;}这“些”个s ...
- 【Javascript】: for循环中定义的变量在for循环体外也有效
for循环中定义的变量在for循环体外也有效 <script> (function(){ var a = 111; for(var i=0;i<5;i++){ var carl = ...
- C++在循环内和循环外定义变量的差异
原文:http://blog.csdn.net/cashey1991/article/details/45127561 最后总结: 对于使用int等基本数据类型作为循环变量,只要你用的优化方面足够给力 ...
- oracle存储过程、声明变量、for循环|转|
oracle存储过程.声明变量.for循环 1.创建存储过程 create or replace procedure test(var_name_1 in type,var_name_2 out ty ...
- SQLserver中的常量与变量、判断循环语句
数据库中的变量与常量 数据库中定义变量 [起临时存储数据的作用] ---数据库中定义变量(运行时要从头到尾进行运行,从定义变量开始到赋值) --前面必须加 declare --定义变量 : de ...
- oracle存储过程、声明变量、for循环(转)
oracle存储过程.声明变量.for循环 1.创建存储过程 create or replace procedure test(var_name_1 in type,var_name_2 out ty ...
- [转]oracle存储过程、声明变量、for循环
oracle存储过程.声明变量.for循环 1.创建存储过程 create or replace procedure test(var_name_1 in type,var_name_2 out ty ...
- oracle存储过程、声明变量、for循环
oracle存储过程.声明变量.for循环 1.创建存储过程 create or replace procedure test(var_name_1 in type,var_name_2 out t ...
- IOS 成员变量,全局变量,局部变量定义,static与extern的区别
IOS 成员变量,全局变量,局部变量定义,static与extern的区别 1,先说定义 1)成员变量定义:生存与该类的生命周期,变量存活周期跟你定义的该类实体对象一样:作用域是整个实体对象:可以在h ...
随机推荐
- mysql系统表加trigger和对特定的库禁用 DDL 语句
给 mysql 系统表加上 trigger 1 Reply 默认情况下,mysql 是不能给系统表,例如 mysql.user 加上触发器的.会提示 ERROR 1465 (HY000): Trigg ...
- 理解Python元类(转)
add by zhj:先收藏了,有时间看,图倒是不少,可以配合stackover flow上那篇文章一起看 原文:http://blog.ionelmc.ro/2015/02/09/understan ...
- Python使用UUID库生成唯一ID(转)
原文:http://www.cnblogs.com/dkblog/archive/2011/10/10/2205200.html 资料: Python官方Doc:<20.15. uuid — U ...
- Type Encoding
[Type Encodings] The compiler encodes the return and argument types for each method in a character s ...
- 了解 JavaScript 中的内置对象
所有编程语言都具有内部(或内置的)对象来创建 语言的基本功能.内部对象是 您编写自定义代码所用语言的基础, 该代码基于您的想象实现自定义功能.JavaScript 有许多 将其定义为语言的内部对象.本 ...
- mac电脑Coding显示/隐藏文件
苹果Mac OS X操作系统下,隐藏文件是否显示有很多种设置方法,最简单的要算在Mac终端输入命令.显示/隐藏Mac隐藏文件命令如下(注意其中的空格并且区分大小写): 显示Mac隐藏文件的命令:def ...
- 使用MSSQL,连接oracle,对oracle数据进行操作
EXEC sp_addlinkedserver--创建链接服务器.链接服务器让用户可以对 OLE DB 数据源进行分布式异类查询. @server = 'Mktg',--要创建的链接服务器的名称.s ...
- C#用串口接收事件接不全数据的处理
问题描述:都知道用事件dataReceive来处理串口非常的方便,但当一次的数据过长时,就会出现截断数据的情况.比如说发一个指 令,返回一个30个字节的数据,但上位机则分两次来接收者30个数据. 解决 ...
- 给js function的参数设置默认值
C# 中 function func(a,b=1){//具体方法} js 中 function func(a,b){ a= arguments[0] || 10; b= arguments[1] || ...
- HTML5中script的async属性异步加载JS
HTML5中script的async属性异步加载JS HTML4.01为script标签定义了5个属性: charset 可选.指定src引入代码的字符集,大多数浏览器忽略该值.defer 可 ...