#include<stdio.h>
int main(){
char name[20];
int total = 0, i, marks[4];
float avr;
printf("Enter name of the student: ");
scanf("%d", &name);
printf("Enter marks of 5 subjects: ");
for(i=0; i<=4; i++){
scanf("%d", &marks[i]);
}
for(i=0; i<=4; i++){
total += marks[i];
}
avr=(float)total/5;
printf("The average marks of %s is %.2f", name, avr);
return 0;
}
使用GNU GCC编译器编译此代码(每个主题的输入标记为90。),我得到了输出 如: Z的平均分数为90.00
然后用Borland Turbo C编译器编译此代码,我得到输出 如: USER的平均分数为90.00
所以,请有人告诉我原因,为什么会这样?
答案 0 :(得分:2)
您使用错误的格式来获取学生姓名。将scanf("%d", &name);
更改为scanf("%s", name);
也int marks[4]
创建4个元素。但是在for循环中,您正在读取5分。当i=4
marks[i]
是第5个元素时。因此,您必须将int marks[4]
更改为int marks[5]
我认为将数组大小定义为常数会更好。
#define MARKS_COUNT 5
int main()
{
// ...
int total = 0, i, marks[MARKS_COUNT];
// ...
for(i=0; i<MARKS_COUNT; i++){
scanf("%d", &marks[i]);
}
for(i=0; i<MARKS_COUNT; i++){
total += marks[i];
}
avr=(float)total/MARKS_COUNT;
// ...
}
处了解格式字符串
答案 1 :(得分:0)
为什么会这样?
数组marks[4]
太小,分配给marks[4]
是无效的。在scanf("%d", &marks[i]);
的{{1}}中,您为i == 4
分配了一个值。该标准说它以任何方式都是未定义的行为访问marks[4]
,因此从标准的角度来看,该程序具有未定义的行为,任何事情都可能发生。
我猜很可能是您的编译器放置了局部变量,使得marks[4]
-&marks[4] == &name[0]
数组末尾的元素地址与marks
数组的地址相同。
很可能在您的系统name
上。当sizeof(int) >= 2
从输入中读取scanf
时,它将90
个字节存储到您指定的指针中。假设sizeof(int)
,&marks[4] == &name[0]
执行时变成scanf("%d", &marks[4])
。
假设您的环境scanf("%d", name);
健全,并且环境为低字节序,CHAR_BIT = 8
实际上将一个字节scanf
存储到指针的第一个字节中,并清除其他字节。因此,90
相当于“ {半”,等于将sscanf("90", "%d", &name[0])
个字节写入sizeof(int)
-一个值为90的字节和name
个字节为零的字节,非常类似于sizeof(int) - 1
。
C中的字符串以0结尾,并且因为整数90是ascii中的字母memcpy(&name[0], (char[sizeof(int)]){90,0}, sizeof(int))
,而零则是字符串终止字符,
Z
printf("%s", name);
实际上指向一个以空终止的字符串,并且第一个字节为name
,第二个字节为零终止字符,因此它仅输出'Z'
。