我是指针的新手,并尝试使用指向结构的指针。但在第一次进入后,我的程序崩溃了。请帮助我。
这是结构定义:
struct students{//structure students definition
char name[20];
char RegNo[15];
char CourseUnit[10];
int score;
char grade;
};
等级不应由用户输入,而是由程序计算。
到目前为止,这是我写的代码:
int main()//start of main
{
struct students *myStudPtr,myStud[SIZE];
myStudPtr=&myStud[SIZE];
int i;//declare variables
int count;
printf("How many students do you want to deal with?\n");
scanf("%d",&i);//number of entries
for(count=1;count<=i;count++) {
printf("Enter student's name\n");
scanf("%s",&(*myStudPtr).name);
printf("Enter the student's registration number\n");
scanf("%s",&(*myStudPtr).RegNo);
printf("Enter the course unit\n");
scanf("%s",&(*myStudPtr).CourseUnit);
printf("Enter the marks scored\n");
scanf("%d",&(*myStudPtr).score);
}
printf("NAME\tREGISTRATION\t\tCOURSE UNIT\tSCORE\t\tGRADE\n");//tabulates the output
printf("%s\t", myStudPtr->name);
printf("%s\t\t", myStudPtr->RegNo);
printf("%s\t", myStudPtr->CourseUnit);
printf("%d\t\t", myStudPtr->score);
if(myStudPtr->score>100) {
printf("Invalid\n");
} else if(myStudPtr->score<40) {
printf("FAIL\n");
} else if(myStudPtr->score<50) {
printf("D\n");
} else if(myStudPtr->score<60) {
printf("C\n");
} else if(myStudPtr->score<70) {
printf("B\n");
} else if(myStudPtr->score>70) {
printf("A\n");
} else {
printf("Invalid");
}
return 0;
}
请帮助。谢谢。
答案 0 :(得分:9)
您有index-out-of bound错误导致undefined behavior在运行时:
myStudPtr = &myStud[SIZE];
// ^^^^^
// wrong
根据声明struct students myStud[SIZE];
,最大索引值可以是SIZE - 1
。请记住,数组索引以0
开头。
修改强>
据我所知,你已经声明了一个struct数组,并希望使用指向struct的指针从用户那里读取i
个学生的信息。但是代码中还有一些问题,例如在for循环中,您始终可以访问相同的结构元素:
for(count = 1; count <= i; count++)
scanf("%s", &(*myStudPtr).name);
// ^
// points to same struct element in array
每个scanf()
和printf()
语句中都存在此错误。
正确如下:
初始化指向数组中第一个元素地址的指针:
myStudPtr = &myStud[0];
// ^ first element at 0th index
通过指针,您可以通过以下两种方式之一访问struct的元素:
首先:例如,扫描学生的score
值:
scanf("%d", &myStudPtr[count].score);
注意:<{strong> precedence []
'数组下标运算符'高于.
'成员选择,通过对象名称运算符',因此您不需要{ {1}}括号。 ()
运算符的优先级也高于.
&符号运算符,因此即使您不需要任何括号来获取地址(例如,&
不需要)。
第二次:使用指针和&(myStudPtr[count].score)
运算符扫描学生的score
值:
->
注意:scanf("%d", &(myStudPtr + count)->score);
加上运算符的优先级较低,因此我们需要括号来覆盖优先级。
+
成员选择的优先级通过指针运算符高于->
&符号运算符,所以这里也不需要任何括号,如&
。
重要说明:
您应该检查用户输入的值&((myStudPtr + count)->score)
必须小于i
(strcut数组的大小),否则您的代码中可能会有未定义的行为。
要读取字符串,请使用safe SIZE
函数而不是scanf来避免缓冲区溢出。阅读:"Reading a line using scanf()
not good?"
还有一个注意事项:
当你是新的C程序员(我觉得)时,你应该阅读:Indenting C Programs这是一个学习缩进练习的快速教程。
您应该始终在fgets()
和,
之后留出空格以使您的代码可读,并且出于同样的原因,;
之类的表达应该写为count<=i
}。比较你的for循环:
count <= i
接下来我想建议你:
for(count=1;count<=i;count++)
改进代码:
我还建议你改进if-else编码风格,你的if-else部分代码可以写成如下:
for(count = 1; count <= i; count++){
// code after one tab
}
score = myStudPtr->score;
if(0 <= score && score <= 100){
if(score > 70)
printf("A");
if(60 <= score && score < 69)
printf("B");
if(50 <= score && score < 59)
printf("C");
if(40 <= score && score < 49)
printf("D");
if(score < 40)
printf("FAIL");
}
else
printf("Error: Invalid Entry!");
printf("\n");
声明,而是使用了&amp;&amp;。 else
个大括号对。 {..}
变量代替score
,以使代码看起来很简单。 myStudPtr->score
语句中删除\n
,而不是在最后添加新的pritf
(不是很重要)。上次错误:
要打印每个学生记录,您需要一个新的循环,您需要调用printf
函数,并包含if-else逻辑来评估学生成绩。