以下是C语言程序,用来计算一个数组a中每个元素之和。当参数len为0时,返回值应该是0,但在机器上执行时,

n却发生了存储器异常。分析原因并修改程序。 float sum_elem(float a[], unsigned len) { int i; float result=0; for (i=0;i<=len-1;i++) result+=a[i]; return result; }

你函数中的len定义的是一个无符号整数,当你传参为0时,len-1为 -1,但因为无符号整形的原因,计算补码得到二进制32位全1,也就是len-1==4294967295,如此for循环访问数组就越界了,当然异常出错

温馨提示:答案为网友推荐,仅供参考
第1个回答  2017-12-14
这道题的问题是这样的,主要在i<=len-1这里出现了问题,由于len是unsgined类型,最高位是没有符号位的,在16位下计算机存储的1111111111111111,而-1的补码是1111111111111111,其中最高位是符号位,两个补码相加就溢出了,所以就报错了,把i<=len-1改为i<len就没有这个问题了
第2个回答  2012-09-18
新手常见错误。
unsigned 类型的数无论如何操作,其结果都不会是负数,所以len-1会得到一个很大的整数,当len为零时。这是现代计算机的普通特征,所以你是你的代码上的逻辑错误,你根本不应该期望一个无符号数变成负数,这就是问题所在。
如果你检查CPU的寄存器标志的话,你可以看到溢出标志会在这种情况下设置的。
第3个回答  2012-09-18
cherayc 的回答已经很清楚了。

len的类型是unsigned ,取值范围0到很大的一个数,没有负数。 当len=0时,for里面,len-1不会是-1,而是那个很大的数。所以数组下表越界,就是你所说的存储器异常。
把 len 的类型改为 int 就正确。
不过最好的是把i的类型也改为 unsigned ,然后for改为:
for (i=0;i<len;i++)
第4个回答  2012-09-17
把函数里的循环条件写成:
for (i=0;i< len;i++)
就可以了。
另外,如果你希望 len 用 unsigned,函数里的 i 最好也用 unsigned。 unsigned int 与 int 数值 范围 不同。
相似回答