4

プログラム設計、私たちの最初の宿題は、4 つの整数値を取り、最も大きい 2 つを足し合わせて、最も小さい 2 つを引き、その結果を 2 乗することでした。最後に、2 つの値を比較して、等しいかどうかを確認します。

たとえば、次のように入力するとします。20 10 60 40

あなたは得るだろう

60 + 40 = 100

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

そう、100 == 100

私は自分のプログラムを書き、さまざまな値をテストして、すべて正しい結果を返しました。私の教授は、私のプログラムは 10 回のテスト入力すべてで失敗したと言い、得た結果を送ってくれました。彼が得た結果は私の結果と同じではなく、何が起こっているのかわかりません。彼にメールしたところ、for ループの 1 つに境界が正しくないと言われました。彼は正しいが、それでも正しい結果が得られるので...?

これがコードです。助けていただければ幸いです。

/*
 // 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;
    }
}
4

5 に答える 5

7

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 つ後の値は配列の一部として効果的にソートされるため、プログラムが機能するかどうかは、初期化されていない値がすべての入力値よりも大きいかどうかによって異なります。

于 2013-05-26T03:21:50.643 に答える
4

for問題は確かに内側のループの上限です。配列の末尾を超えて読み取ることになり、未定義の動作が発生します。

結果のプログラムがあなたのマシンで正しい結果を出力する可能性は十分にありますが、他の誰かのマシンで動作するという保証はありません. したがって、未定義です。

于 2013-05-26T03:22:10.130 に答える
2

内部ループは にアクセスすることになりarray[4]、未定義の動作がトリガーされます。未定義の動作をトリガーするとすぐに、その時点以降のプログラムについては何も保証できません。

ただし、実際に起こっている可能性が高いのは、コンピューター上でarray[4] たまたまより大きく、array[3]それらを同じ順序に保つことです。教授のコンピューターで、それらを交換し(おそらく他の変数を破壊します)、array[3]未定義の値にします。

于 2013-05-26T03:23:56.923 に答える
1

プログラムの出力は の値に完全に依存するため、は長さ 4 の配列array[4]arrayあるため、その動作は完全に予測できません。ソースから、場所 のメモリにどのような値があるかを推測する方法はありませんarray + 4

(実際には、それよりもさらに悪いことです — あなたのプログラムは未定義の動作を呼び出します。つまり、あなたからのものであるかのように見える下品で侮辱的な電子メールをあなたの教授に送信することを含む、まったく何でもすることが許可されていることを意味します。しかし、実際には、予想される出力の 1 つを出力する可能性が高く、どれを推測する方法は実際にはありません。)

于 2013-05-26T03:22:53.083 に答える
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;
            }
        }
    }
于 2013-05-26T03:25:45.440 に答える