bool 表达式似乎合乎逻辑但不起作用

bool expression seems logical but doesn't work

我正在我的 C 程序中读取 3 个整数并将它们存储在 int *[] 中。然而,在读取第 3 个 int 时,我想将它与前 2 个进行比较,如果它大于它们两个程序结束,如果不是,程序将继续读取第 3 个。输入直到满足while循环中的条件。

我的问题是,虽然 bool 表达式看起来合乎逻辑(至少对我而言)并且我输入的值已成功存储在数组中,但为什么它总是跳过 while 循环?

#include <stdio.h>

int main(void) { // Stelios Papamichail 4020
    int *sides[3];
    int i;
    for(i=0; i < 3; i++) {
        if(i == 2) {// third side
            scanf(" %d",&sides[i]);
            while((sides[i] < sides[i-1]) && (sides[i] < sides[i-2])) {
                scanf(" %d",&sides[i]);
            }
        } else {
            scanf(" %d",&sides[i]);
        }
    }
    return 0;
}

您代码中的主要问题是,它调用了 undefined behavior.

要详细说明,请在您的代码中说

 int *sides[3];

你正在定义一个包含 3 个 int * 的数组(包含 3 个指向整数的指针的数组),而你需要的是一个包含 3 个 int 的数组。改成

int sides[3];

也就是说,根据你的要求,while条件中的&&应该是||,如果你想检查第三个输入是最小的。

给定大小的数组声明为:

int sides[3];

而未知大小的数组(基本上是指针)声明为:

int* sides;//you should use malloc to allocate the array memory at run time.

使用

int* sides[3];

您正在声明一个指针数组。

您的最终代码应如下所示:

#include <stdio.h>

int main(void) { // Stelios Papamichail 4020
    int sides[3];
    int i;
    for(i=0; i < 3; i++) {
        if(i == 2) {// third side
            printf("%d %d %d\n", sides[i], sides[i-1], sides[i-2]);

            scanf(" %d",&sides[i]);
            while((sides[i] < sides[i-1]) && (sides[i] < sides[i-2])) {
                printf("%d %d %d\n", sides[i-2], sides[i-1], sides[i]);
                scanf(" %d",&sides[i]);
            }
        } else {
            printf("%d %d %d\n", sides[i-2], sides[i-1], sides[i]);
            scanf(" %d",&sides[i]);
        }
    }
    return 0;
}

我添加了一些打印件以了解发生了什么。

你说:

I'm reading 3 integers in my C program and storing them in an int *[]. While reading the 3rd int however, I want to compare it to the previous 2 and if it's greater than both of them the program ends, if it isn't the program will keep on reading the 3rd. input until it satisfies the condition in the while loop.

嗯,int 与指针不同。 int 允许您进行整数运算,而 int * 允许您进行指针运算。 (指针存储 int 变量的内存地址,因此,当您递增它时,它会将其值移动到 next 地址,这与添加一个---因为 int 需要一个以上的字节来适应内存)你可以在你的程序中使用 int * (正如你在评论中所说,你的老师已经指出)但这就像做煎蛋卷,但用苹果代替鸡蛋(好吧,它们都是圆的,但结果不一样)。我猜不出你的老师要求你使用 int * 的原因,但这给了我来自编译器的警告,告诉我这样做的风险(编译器是 CLANG,在 FreeBSD 上)

My issue is, although the bool expression seems logical (to me at least) and the values I enter are successfully stored in the array, why does it always skip the while loop?

好吧,这取决于您尝试检查的内容。关于这个的第一件事就是你在代码中说的是将最后输入的数字与前面的数字进行比较,如果大于或等于其中任何一个,则再次输入第三个数字。如果那是你想要的,那是正确的,但我也猜不出做这样一个测试的目的是什么,所以我唯一可以得出的结论是测试写得不好(主要是因为我要接下来说)。

关于您的程序的第三条评论是:

如果您需要将最后一个值与之前的值进行比较,为什么不在循环之外执行此操作。这样做不仅可以让你的代码看起来更简单,还可以省去 if (i == 2) 测试(你的代码中根本不需要使用 i,只需要写:

    for(i=0; i < 3; i++) {
        scanf("%d",&sides[i]); /* you don't need the space before %d */
    }
    while((sides[2] < sides[1]) && (sides[2] < sides[0])) {
        scanf("%d",&sides[2]);
    }

最后,您在评论中说将 int *sides[3] 更改为 int sides[3] 会使编译失败。我试过了,只是消除了 * 只是消除了我从你的代码编译中得到的三个警告。猜不出来你为什么说它不能用那个消除编译。

注意

您的代码似乎试图检查三角形的三个边是否允许您构建一个。如果这是真的,那么正确的测试是第三个三角形 大于前边的差值 并且 小于前边的总和 ,这不是你上面写的。一个有效的测试应该是:

#define ABS(expr) ((expr) < 0 ? -(expr) : (expr))

while (sides[2] >= sides[1] + sides[0] || sides[2] <= ABS(sides[1] - sides[0])) {
    scanf("%d", &sides[2]);
}