在for循环中声明变量的优点和缺点?

时间:2016-10-14 17:56:55

标签: java variables for-loop

在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

在考试中,这是我的方式的罚分。我试图通过告诉他说服他:

  • 我没有看到代码按照他的方式完成。
  • 它不是那么重要的变量,所以让它本地化是有意义的。
  • 可能是在for循环中你可能需要使用类型长变量。

他的答案是:"如果这里有很少的循环,你不需要反复声明同一个变量" ...很难与讲师争论那么特别的你是一个来自foreng国家的一年级学生。但是int并没有占用太多内存,而且java有一个垃圾收集器来清理内存..

所以请帮助我说服他或我,并提出一个很好的论据。

3 个答案:

答案 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上的值。)

然而,在大多数情况下...除了一些非常低级别的处理收益(这是有争议的)之外没有其他实际好处。我假设你的教授要么是一名低端程序员,他已经从事这项业务多年,受过良好教育,或者有很高开销的应用程序。