我如何发现细微的错误

我如何发现细微的错误

我不明白为什么变量的值是0,应该是23?

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int array[] = {23, 34, 12, 17, 204, 99, 16};
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int main(){
    int d = -1, x = 0;
    if (d <= TOTAL_ELEMENTS - 2)
        x = array[d + 1];
    printf("x= %d \n", x);
    return 0;
}

最佳答案

这是由于通常的算术转换。
当运算符的操作数同时包含有符号整数和无符号整数,且无符号类型至少与有符号类型一样大时,有符号值将转换为无符号值。当有符号的值为负值时,它将转换为一个较大的正值。
整数转换规则在C standard的第6.3.1.8p1节中有详细说明:
如果两个操作数具有相同的类型,则不再进行转换
需要。
否则,如果两个操作数都具有有符号整数类型或都具有
无符号整数类型,类型为lesser的操作数
整数转换秩转换为操作数的类型
级别更高。
否则,如果具有无符号整数类型的操作数具有
等级大于或等于另一种类型的等级
操作数,则带符号整数类型的操作数为
转换为无符号整数的操作数类型
键入。
否则,如果带符号整数类型的操作数的类型可以
用无符号表示操作数类型的所有值
整数类型,则无符号整数类型的操作数为
转换为带符号整数类型的操作数类型。
否则,两个操作数都转换为无符号
与带符号的操作数类型相对应的整数类型
整数类型
在这个表达式中:

(d <= TOTAL_ELEMENTS - 2)

扩展到:
(d <= (sizeof(array) / sizeof(array[0])) - 2)

sizeof运算符的计算结果为类型为size_t的无符号值。所以操作数的类型如下:
(int <= ((size_t / size_t) - int)

/运算符的两个操作数都是size_t类型,因此该操作的结果是size_t类型。然后将-的右操作数转换为size_t类型。因为值2适合该类型,所以该值不会更改。
现在我们有一个<=操作符,一个int在一个大小上,另一个size_t在另一个大小上。左操作数将从int转换为size_t,但是值-1不适合该类型,因此将进行转换。转换后的值实际上是asize_t的最大可能值,因此大于右侧的值,从而使<=的结果为false。
要解决此问题,您需要将右侧的无符号值强制转换为有符号值,以防止左侧被转换:
if (d <= (int)(TOTAL_ELEMENTS - 2))

关于c - 我如何发现细微的错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58089584/

10-11 17:55