在for循环中声明变量有哪些优点和缺点? 我想改变我的讲师思想,或改变我的思想: 讲师强迫我使用:
// Declare variables
int i;
...
for(i = 0; boolen expesion; update) // Note i not declared here
我喜欢这样做:
for(int i = 0; boolean expesion; update) // Note i is declared here
在考试中,这是我的方式的罚分。我试图通过告诉他说服他:
他的答案是:"如果这里有很少的循环,你不需要反复声明同一个变量" ...很难与讲师争论那么特别的你是一个来自foreng国家的一年级学生。但是int并没有占用太多内存,而且java有一个垃圾收集器来清理内存..
所以请帮助我说服他或我,并提出一个很好的论据。
答案 0 :(得分:5)
他的答案是:“如果这里有很少的循环,你不需要 反复声明相同的变量“......这很难说 讲师特别是你是一名学生的第一年学生 国家。但是int并没有占用那么多内存加上java有垃圾 收藏家清理记忆..
这是关于学习在学术界编写软件的丑陋真相。除非你的部门负责人不仅比大多数讲师更好,而且在为学生辩护时自信,你只会降低你的成绩,这种情况很有可能。当我在大学时,一位教授因使用“先进技术”而对学生进行评分而闻名。我指的是他讲课前的章节。即使他们能够以绝对的精确度完全表达他们正在做的事情,也证明他们不仅仅是复制和粘贴。
事实是你的教授对大多数常见的循环都是错误的。除非您的代码需要在循环之后引用索引变量,否则最好让变量在范围更改时被删除。对于大多数实际的循环,他的方式不仅没有必要。它甚至不可能,因为今天许多“for”循环实际上是 - 像这样的每个循环
for (String s : someArray) {
System.out.println(s);
}
或(Groovy)
someArray.each { element ->
println element
}
更新:我认为另一件事是教授的论点是错误的,除非绝对必要,否则让国家暴露是一种不好的形式。作为一般规则,对于任何语言来说,这都是一个糟糕的想法,尤其是对于垃圾收集语言。由于变量是int
而不是Integer
(堆栈上的原语与堆上的对象,对于初学者来说读取它),在这种情况下它不太重要。但是,在处理对象时,应该编写一个代码,以使GC对于“此范围已退出,让我们清理其中的所有内容”这一点非常简单。
随着时间的推移,如果您习惯保持不必要的状态,则存在引入内存泄漏的风险。您的习惯可能会使GC更难以完成其工作以及长时间运行的任务,这可能会导致内存需求增加和不稳定。你不需要以任何方式去功能语言纯粹主义者,但你需要借用它的精神,它将国家视为必要的邪恶,而不是来自天堂的祝福。
答案 1 :(得分:3)
他是对的,你不需要重复声明相同的变量,但是:
优良作法是将变量的范围限制在使用它们的位置。
单独声明变量实际上需要一行源代码,所以它本身并没有减少代码。
在每个for
循环中声明变量将不使用更多空间。
生成的字节代码相同。
因此,如果您不需要变量在之外的for
循环,则应始终在for
循环的范围内声明变量。有助于防止意外将变量重用于其他目的。
我们来看下面的代码:
static void test1() {
int i;
for (i = 0; i < 10; i++)
;
for (i = 0; i < 10; i++)
;
}
static void test2() {
for (int i = 0; i < 10; i++)
;
for (int i = 0; i < 10; i++)
;
}
如您所见,单独声明i
需要多行代码。
字节码是这样的:
static void test1(); static void test2();
Code: Code:
0: iconst_0 0: iconst_0
1: istore_0 1: istore_0
2: goto 8 2: goto 8
5: iinc 0, 1 5: iinc 0, 1
8: iload_0 8: iload_0
9: bipush 10 9: bipush 10
11: if_icmplt 5 11: if_icmplt 5
14: iconst_0 14: iconst_0
15: istore_0 15: istore_0
16: goto 22 16: goto 22
19: iinc 0, 1 19: iinc 0, 1
22: iload_0 22: iload_0
23: bipush 10 23: bipush 10
25: if_icmplt 19 25: if_icmplt 19
28: return 28: return
如您所见,它们完全相同,因此它们在堆栈上使用相同数量的空间作为局部变量。
答案 2 :(得分:0)
评论说得对“不要和他争辩。请他做,并在考试后做你想做的事。”
然而,你的教授确实指出何时这可能是有效的,应该这样做,我假设你遗漏了。例如,通过将索引变量保留在for循环范围之外,您可以稍后引用它。 (当从未知来源传入数组时,这对于确定数组的大小非常有用,例如拉出数据库)。同样,每次运行循环时都不需要设置新变量(可论证)一些值(通过将i设置为零,但这取决于语言,但在汇编设置中我可以看到一些寻址和push / pop / ext ...... CPU上的值。)
然而,在大多数情况下...除了一些非常低级别的处理收益(这是有争议的)之外没有其他实际好处。我假设你的教授要么是一名低端程序员,他已经从事这项业务多年,受过良好教育,或者有很高开销的应用程序。