`nums[i++]=i;` 在Java和C中表现不同吗?

huangapple go评论84阅读模式
英文:

nums[i++]=i; performs differently in java and C?

问题

private void delete(int[] nums, int i, int size) {
    while (i < size - 1) {
        //nums[i ++] = nums[i + 1];
        nums[i] = nums[i + 1];
        i++;
        System.out.println("i: " + i);
    }
    return;
}

我发现,如果用注释部分替换语句

nums[i] = nums[i + 1];
i++;

在 Java 中会抛出数组越界异常,但在 C 语言中表现良好。

英文:
private void delete(int[] nums, int i, int size) {
    while (i &lt; size - 1) {
       //nums[i ++] = nums[i + 1];

       nums[i] = nums[i + 1];
       i++;
       
       System.out.println(&quot;i: &quot;+i);

    }
    return;
}

I found that if replace the statement

nums[i] = nums[i + 1];
i++; 

with the comment part

nums[i ++] = nums[i + 1];

It throws OutOfIndex in java but performs well in C.

答案1

得分: 2

> 它在Java中抛出OutOfIndex异常,但在C中表现良好。

C并不是Java。C标准并没有规定在执行禁止操作时会发生什么。它只是描述了任何约束违规或违反"应当"规定的情况为"行为未定义"或未定义的行为

C编译器不会检测此类未定义的行为情况,而只是编译程序。当您稍后运行该程序时,您将永远不知道会发生什么,因为行为是未定义的。

因此,您可以编译并运行它,但该程序是有缺陷的(至少如果实现没有指定在这种情况下会发生什么行为的话)。

请注意,尽管糟糕,未定义的行为并不一定会提供错误的结果,因此在C中进行编码时要小心。

英文:

> It throws OutOfIndex in java but performs well in C.

C isn't Java. The C standard does not mandate anything what has to happen when you do prohibited things.

It only describes any constraint violation or violation against the "shall" mandating as "the behavior is undefined" or undefined behavior.

A C compiler doesn't detect such undefined behavior cases and just compiles the program. When you later run the program, you will never know what exactly will happen because the behavior is undefined.

So you can compile and run it, but the program is defective (at least if an implementation does not specify a behavior which shall happen in this case else).

Note that bad as it is, undefined behavior does not need to provide the wrong results, so be careful at coding in C.

答案2

得分: 1

nums[i++] = nums[i + 1]

如果 i++ 发生在 nums[i + 1] 之前,i + 1 将会越界在最后一次迭代中。在这种情况下,Java 会正确地引发错误,而C语言因为不进行边界检查,会毫不怀疑地相信你编写的代码。

那段代码在逻辑上是无效的。你只是不幸的是,在你的C程序中没有做出明显的操作来引起怀疑。

英文:

In

nums[i ++] = nums[i + 1]

If the i++ happens before the nums[i + 1], i + 1 will be out of bounds on the last iteration. In that case, Java rightly causes an error, and C, because it doesn't do bound-checking, happily trusts the code you wrote.

That code is logically invalid. You're just unlucky that it didn't do anything obvious in your C program to cause suspicion.

答案3

得分: 1

这个程序在 C 中表现不佳。

在 C 中,nums[i++] = nums[i + 1] 是“未定义行为”,因为缺乏序列点。参见 https://stackoverflow.com/questions/3575350/sequence-points-in-c,这意味着 C 程序在运行时可能会执行任何操作。在运行程序时无法保证程序会执行什么操作。

在 Java 中,语言规范 确切地定义了如何评估 nums[i++] = nums[i + 1]:赋值语句的左操作数必须首先被评估,因此 i++ 会先被评估。在赋值语句右操作数中随后使用 i 必须使用更新后的值。

英文:

This program does not "perform well" in C.

In C, nums[i++] = nums[i + 1] is "Undefined Behavior" due to lack of sequence points. See https://stackoverflow.com/questions/3575350/sequence-points-in-c This means the C program could do anything at all. You have no guarantees what the program will do when you run it.

In Java, the Language Specification defines exactly how nums[i++] = nums[i + 1] has to be evaluated: The left hand side of the assignment must be evaluated first, so i++ is evaluated first. The subsequent use of i on the right hand side must use the updated value of i.

huangapple
  • 本文由 发表于 2020年7月25日 23:20:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63090052.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定