由于循环绑定,排序会产生不一致的结果

时间:2013-05-26 03:15:18

标签: c

程序设计,我们的第一个作业分配是取4个整数值,将2个最高值加在一起并减去最低的两个并将结果平方。最后,将2个值进行比较,看它们是否相等。

例如,如果您输入:20 10 60 40

你会得到

60 + 40 = 100

20 - 10 = 10 --> 10^2 = 100

所以,100 == 100

我编写了我的程序并测试了各种值,这些值都返回了正确的结果。我的教授告诉我,我的程序在所有10个测试输入中都失败了,他给我发了他得到的结果。他得到的结果与我的不一样,我不知道发生了什么。我给他发了电子邮件,他告诉我其中一个for循环有不正确的界限。他是对的,但我仍然得到了正确的结果,所以......?

这是代码,任何帮助将不胜感激!

/*
 // Author: Jesse W
 // Assignment 1

 // Desciption:
 // This program inputs four integer numbers a, b, c and d and
 // determines if the sum of the two largest numbers is the same
 // as the squared difference of the two smallest numbers
 */

#include <stdio.h>

/* Complete the code for this program below */

int main()
{
    int a, b, c, d, f, k, swap;
    int array_size = 4;
    int return_val;
    int sum, difference, square;
    int small_1, small_2, large_1, large_2;
    int array[array_size];

    //Gather input
    //printf("Enter integer values for a, b, c and d.\n");
    return_val = scanf("%d %d %d %d", &a, &b, &c, &d);

    //Validate input
    if (return_val != 4)
    {
        printf("INVALID INPUT\n");
    }
    else
    {
        //Assign values to array
        array[0] = a;
        array[1] = b;
        array[2] = c;
        array[3] = d;

        //Sort array
        for (k = 0 ; k < ( array_size - 1 ); k++)
        {
            for (f = 0 ; f < array_size ; f++)
            {
                if (array[f] > array[f+1]) /* For decreasing order use < */
                {
                    swap       = array[f];
                    array[f]   = array[f+1];
                    array[f+1] = swap;
                }
            }
        }

        //Assign sorted values to new variables
        small_1 = array[0];
        small_2 = array[1];
        large_1 = array[2];
        large_2 = array[3];

        //Compute math
        sum = large_1 + large_2;
        difference = small_1 - small_2;
        square = difference * difference;

        //Compute logic
        if(sum == square)
        {
            printf("%d equals %d.\n", sum, square);
        }
        else
        {
            printf("%d does not equal %d.\n", sum, square);
        }

        return 0;
    }
}

5 个答案:

答案 0 :(得分:8)

f的范围最高为array_size - 1

        for (f = 0 ; f < array_size ; f++)

但在这种情况下,您可以访问array[ f + 1 ]

array[ array_size ]
                array[f]   = array[f+1];
                array[f+1] = swap;

这会导致未定义的行为。由于超过结尾的值有效地作为数组的一部分进行排序,因此程序是否有效取决于未初始化的值是否大于所有输入值。

答案 1 :(得分:4)

问题确实是内部for循环的上限;它会导致您读取数组的末尾,这会导致未定义的行为

结果程序仍然可以在您的机器上打印正确的结果,但不能保证它可以在其他任何人身上运行。因此未定义。

答案 2 :(得分:2)

您的内部循环将最终访问array[4],这会触发未定义的行为。一旦触发未定义的行为,在此之后就无法保证程序的任何内容。

实际可能发生的事情是,在您的计算机上,array[4] 恰好发生大于array[3]并保留这些以相同的顺序。在教授的计算机上,你交换它们(可能会破坏其他变量),使array[3]成为未定义的值。

答案 3 :(得分:1)

由于程序的输出完全取决于array[4]的值,其中array是一个长度为4的数组,其行为完全不可预测:从源头开始无法估计什么值恰好位于array + 4位置的记忆中。

(事实上,情况甚至更糟 - 你的程序会调用未定义的行为,这意味着它可以完全做任何事情,包括向你的教授发送一个粗俗和侮辱性的e-看起来像你的邮件。但在实践中,它可能打印出一个预期的输出,真的没办法猜测哪个一个。)

答案 4 :(得分:0)

将排序循环更改为此

    for (k = 0 ; k < array_size ; k++)
    {
        for (f = 0 ; f < (array_size -1) ; f++)
        {
            if (array[f] > array[f+1]) /* For decreasing order use < */
            {
                swap       = array[f];
                array[f]   = array[f+1];
                array[f+1] = swap;
            }
        }
    }