关于变量在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 5.5 服务器变量详解一(转)
add by zhj:在MySQL5.6中对一些参数有增删改,详见http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html ...
- oracel 导入导出
一.导出模式(三种模式)及命令格式 1. 全库模式 exp 用户名/密码@网络服务名 full=y file=路径\文件名.dmp log=路径\文件名.log 2. 用户模式(一般情况下采用此模式) ...
- C++11空指针
[C++11空指针] 早在 1972 年,C语言诞生的初期,常数 0 带有常数及空指针的双重身分. C 使用 preprocessor macro NULL 表示空指针, 让 NULL 及 0 分别代 ...
- Python的高级Git库 Gittle
Gittle是一个高级纯python git 库.构建在dulwich之上,提供了大部分的低层机制 Gittle是一个高级纯python git 库.构建在dulwich之上,提供了大部分的低层机制. ...
- 利用HTML5开发Android(7)---HTML5本地存储之Database Storage
在上一篇<HTML5本地存储之Web Storage篇>中,简单介绍了如何利用localStorage实现本地存储:实际上,除了sessionStorage和localStorage外,H ...
- 《Spring3.0就这么简单》第1章快速入门
问题 [如何将jsp中传递到HttpServletRequest的参数,自动装配到Java对象中] [成功] public void setUsernAme(String username) < ...
- Spring AOP 实现原理
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- 利用花生壳和IIS发布网页过程
老早利用做过类似的事情,但最近又忘了怎么弄的了,还是自己给自己总结下,省得以后到处找了. [动态域名绑定] 如果具有公网IP地址,申请一个免费的花生壳动态域名,再下一个花生壳客户,使用已经申请好的动态 ...
- 转载:js和as间的交互
转载一: 提及AS3与外部脚本的交互,笔者认为可以总结成两种.一是AS3调用外部函数,二是外部脚本调用AS3函数.无外乎就 这两种.在调用函数的同时,我们还可以向函数传递一些参数.这就达到了传递数据的 ...
- java中导入常量
import关键字除了导入包之外,还可以导入静态成员,这时JDK5.0以上版本提供的新功能.导入静态成员可以是程序员编程更为方便. 使用import导入静态成员的语法为: import static ...