测试无符号整数值时,CA 很奇怪

  • 本文关键字:CA 无符号整数 测试
  • 更新时间 :
  • 英文 :


今天,我写了一些代码来测试无符号的int。

#include <stdio.h>
int sum_element(float ele[], unsigned int len);
int main(void){
    float ele[] = {1.1,2.2,3.3};
    float sum = sum_element(ele,3);
    printf("sum is %fn",sum);
    return 0;
}
int sum_element(float ele[], unsigned int len){
    int sum=0.0; //mistake,should be : float sum = 0.0
    int i=0;
    for(i=0;i<= len-1;i++){
        printf("sum=%f, i=%dn",sum,i);
        sum += ele[i];
    }
    return sum;
}

在这个例子中,我有一个错误,变量 sum 的类型应该是浮点数,但我写了 int,编译命令:

 gcc test.c -o test

我运行这段代码

 ./test

函数sum_element的输出为:

sum=0.000000, i=1
sum=0.000000, i=1
sum=0.000000, i=1

然后我发现了错误,我将总和的类型更改为浮点数,然后再次编译,当我运行它时,输出是:

sum=0.000000, i=0
sum=1.100000, i=1
sum=3.300000, i=2

这次,输出像正常一样,但是在第一次输出中,为什么i的变量总是相同的值1,有人可以告诉我吗?

没什么可看的。你通过将错误的类型传递给printf来调用未定义的行为,因此程序的所有输出都是没有意义的。%f格式说明符需要一个类型 double 的参数(顺便说一下,在这种情况下,float会自动提升为 double,所以float也可以(,但你给它传递了一个类型 int 的参数。

你必须

了解va_arg是如何工作的。Printf 是一个接受未定义数量的参数的函数。问题是这些参数不是键入的。

当您指定整数、双精度等时...编译器根据参数分配不同的字节数(按特定顺序(。因此,当您调用具有类型参数的函数时,该函数知道它应该如何读取这些字节。在这里它无法知道,因为它不是类型。所以printf函数会相信你给它的东西。例如,当您的实际值为 8 字节时,如果您要求 4 个字节,则该函数将读取前 4 个字节,相信它是您要求的值。但是,您尝试匹配的下一个值将从接下来的 4 个字节开始。威奇会给你垃圾。

你可以尝试做 2 个 printf,你会发现 i 的值实际上是好的。只是阅读它的方式是错误的。

int sum_element(float ele[], unsigned int len){
int sum=0.0; //mistake,should be : float sum = 0.0
int i=0;
for(i=0;i<= len-1;i++){
    printf("sum=%fn",sum);
    printf("i=%dn",i);
}
return sum;

}

希望这能有所帮助。

编辑:

也许一个例子更容易理解。试试这个函数:

int sum_element(float ele[], unsigned int len){
  int sum=24222.55455555; //mistake,should be : float sum = 0.0
  char c = 0 ;
  for(i=0;i<= len-1;i++){
    printf("sum=%f, n= %d n2 = %dn",sum,i,c);
  }
  return sum;
}

你应该得到一个有趣的 n2 值。

我认为答案是,在第一种情况下,打印的值根本不是i的值。两个参数传递给printf然后读取两个关闭。传入的是两个int,然后读出一个doubleint。由于首先从堆栈中读取double,因此在读取int时,它不是从传递i值的位置传递的,因此是虚假值。最有可能的是,double覆盖了足够的堆栈,以包括传递的int

当然,结果可能会有所不同,无法定义。

最新更新