测试unsigned int值时的一个奇怪的事情

时间:2013-04-02 02:35:13

标签: c

今天,我编写了一些代码来测试unsigned 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 %f\n",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=%d\n",sum,i);
        sum += ele[i];
    }
    return sum;
}

在这个例子中,我有一个错误,变量sum的类型,应该是float,但我写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的相同值,有人可以告诉我吗?

3 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:1)

您必须了解va_arg的工作原理。 Printf是一个接受未定义数量的参数的函数。问题是这些参数没有输入。

当指定int,double,ect时......编译器根据参数分配不同的字节数(按特定顺序)。因此,当您调用具有类型参数的函数时,该函数知道它应该如何读取这些字节。 这里它不知道因为它不是类型。所以printf函数会相信你给它的东西。如果你要求例如4个字节,当你的实际值是8个字节时,该函数将读取前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=%f\n",sum);
    printf("i=%d\n",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 = %d\n",sum,i,c);
  }
  return sum;
}

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

答案 2 :(得分:0)

我认为答案是,在第一种情况下,打印的值根本不是i的值。两个参数传递给printf,然后读取两个参数。传入的内容有两个int s,然后会读取doubleint。因为首先从堆栈读取double,所以当读取int时,它不是从i的值传递的位置,因此是伪造的值。最有可能的是double覆盖了足够的堆栈以包含传递的int

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