在Java中,for循环末尾加上额外的分号概念有问题。

3

我正在编写一个将元素插入到链表末尾的代码。然而,在for循环结尾处没有使用分号,导致无法正确更新列表。这个分号有什么意义,它是如何影响我的代码的?

public void insertAtEnd() throws IOException {
        LinkedList node=new LinkedList();
        System.out.println("Enter an element");
        int value=Integer.parseInt(br.readLine());
        node.setData(value);
        LinkedList p,q;
        for(p=head; (q=p.getNext())!=null; p=q); 
            p.setNext(node);
    }

1
将for循环的主体放在花括号内是一个好习惯。如果您在循环内执行其他操作,花括号的存在将确保代码在循环内部而不是外部执行。 - Mark Chorley
那个循环的目的是什么? - Murat Karagöz
1
请注意,最后一行的额外缩进非常具有误导性!它暗示该行应在每次迭代中执行,而实际上它只应在循环完成后执行。如果您删除分号,则节点将成为第二个元素,第三个元素,第四个元素等等。 - Oebele
3
即使函数体应该为空,这样做也是一个很好的习惯。漏掉分号比漏掉一对大括号要容易得多。编写这种语句的情况很少,像errorprone这样的工具完全禁止它。 - Andy Turner
所有这些都应该进行改进,以便通过注释来解释循环,提高可读性。 - ControlAltDel
显示剩余2条评论
5个回答

7
分号表示在循环结束之前,下面的语句不会被执行。在你的情况下,循环将p带到列表的末尾(最后一个元素),然后下一个语句将其下一个值分配给新元素。

2
目前代码的构造方式是:for(p=head; (q=p.getNext())!=null; p=q);for循环体为空。通过p.getNext()p=q赋值来更新变量pq,然后单次执行p.setNext(node);编辑:至于为什么这段代码带有分号就能正常工作,那是因为你正在遍历列表中的变量p和q。虽然带有空循环体的for循环也可以,但传统上我们会使用while循环。 p.setNode(node);的缩进方式让它看起来与for循环相关,但实际上不是这样的,其目的是通过迭代遍历寻找链表的末尾。
(注:在我回答问题时其他人也提出了类似的观点)

1
不完全正确-它更改了p的值,这对代码的正确运行是必要的。 - Oebele
@Oebele,你是正确的,我想说的是for循环没有主体,因此p.setNext()没有被调用。 - KevinO
好的,现在它是正确的。点赞了,只是为了让它出现在不正确的答案上方。 - Oebele

1
它需要被移除,因为它导致循环中没有任何操作。循环将在执行完下一个单一的代码块后结束,可以是一个语句或一个 { } 代码块。在这种情况下,你只有一个语句 ;,所以它会被"执行"但不会有任何操作,然后在循环结束后调用p.setNext(node);
public void insertAtEnd() throws IOException {
        LinkedList node=new LinkedList();
        System.out.println("Enter an element");
        int value=Integer.parseInt(br.readLine());
        node.setData(value);
        LinkedList p,q;
        for(p=head; (q=p.getNext())!=null; p=q)
            p.setNext(node);
    }

2
我认为你的假设是错误的。循环的目的是找到最后一个元素,并将“node”作为其下一个元素添加。如果您删除分号,“node”将成为第二个元素、第三个元素、第四个元素等。 - Oebele

1
分号本质上是通过你的缩进来转换你想要做的事情:
for(p=head; (q=p.getNext())!=null; p=q)
{
    p.setNext(node);
}

into the following:

for(p=head; (q=p.getNext())!=null; p=q)
{
}
p.setNext(node);

所以在加上分号后,你的循环每次都不执行任何操作。然后,在它完成执行之后,你只运行了一次p.setNext(node);

通常情况下,你可以通过像我在这两个代码段中所做的那样明确地编写花括号来避免这个问题。现在不清楚你正在尝试完成哪个代码段。


不对。你的第一个片段将对象“node”设置为第二个、第三个、第四个等元素,导致异常,我忘记了确切是哪一个异常,我想是OutOfMemoryException? - Oebele
@Oebele 我只是在回答 OP 的实际问题:解释分号如何影响代码。我并不完全理解他现在的意图。你认为我的编辑现在更清晰了吗? - NoseKnowsAll
1
虽然这个代码看起来不错,但我怀疑他是自己写的,因为他似乎不理解这段代码。需要注意的是,在第二个片段中声称循环没有任何作用也是误导性的,因为p的值被改变了。 - Oebele

0

for语句提供了一种紧凑的方式来遍历一系列值。程序员通常称之为“for循环”,因为它会重复循环,直到满足特定条件。for语句的一般形式可以表示如下:

for (initialization; termination; increment) {
    //statement(s)
}

使用此版本的for语句时,请记住以下几点:

  1. 初始化表达式初始化循环;它在循环开始时执行一次
  2. 当终止表达式评估为false时,循环终止。
  3. 增量表达式在每次迭代循环后被调用;这个表达式可以完全接受递增或递减一个值。

在您的情况下,循环将p带到列表的末尾(最后一个元素),然后下一个语句将其下一个值分配给新元素


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接