我是一名学生,正在尝试学习来自c ++的c。我写了下面的代码,编译得很好;但是,当我执行它时,我在调用print函数时会得到一个无限循环。我查看了代码,它似乎对我有用,那为什么它会打印无限循环呢?
#include <stdio.h>
#include <stdlib.h>
struct student
{
int id;
int score;
};
void generate(struct student *students, int n)
{
int randomId = rand () % n + 1;
int randomTestScore = rand() % 100 + 1;
students->id = randomId;
students->score = randomTestScore;
}
void sort(struct student *students, int n)
{
/*using insertion sort*/
for (unsigned int i = 1; i < n; ++i)
{
int next = students[i].score;
int j = i;
while(j > 0 && students[j-1].score > next)
{
students[j].score = students[j-1].score;
j--;
}
students[j].score = next;
}
}
void print(struct student *students, int n)
{
for (unsigned int i = 0; i < n; i++)
{
printf("Student at position No: %d Test Score: %d\n", i+1, students[i].score);
}
}
int main()
{
/*user enters num of students to create scores for*/
int num_students;
printf("Enter Num of students\n");
scanf("%d", num_students);
/*allocate memory for the amount of students user wants*/
struct student *userStudents = malloc(num_students*sizeof(struct student));
printf("Randomly filling students IDs & Test Scores...\n");
for (unsigned int i = 0; i < num_students; ++i)
{
generate(&userStudents[i], num_students);
}
printf("Array of students before sorting:\n");
print(userStudents, num_students);
printf("\nNow, sorting students by test scores...\n\n");
sort(userStudents, num_students);
printf("Array of students after sorting:\n");
print(userStudents, num_students);
return 0;
}
答案 0 :(得分:3)
将对scanf
的通话更改为:
/*
* correct way of calling scanf, passing the address of the wanted variable
*/
scanf("%d", &num_students);
^
这消除了分段错误并使代码在我的机器上运行正常。
我之前有一个提示,你需要将userStudents
的声明更改为指向指针的指针,但是我不正确。您显然正确地分配了足够的连续内存来保存*userStudents
指向的所有结构。
答案 1 :(得分:3)
要正确使用scanf()
,它需要改变传递的变量,并且由于c中没有通过refrence传递,你需要传递变量的地址,因此scanf()
能够通过指针修改它,因此你需要使用&
运算符,但这还不够。
scanf()
系列函数返回一个必须先检查的值才能访问扫描值,在任何情况下都不应忽略该值,应该检查它。
您的代码正在执行的操作称为未定义的行为,它将传递的整数解释为是指针,这是未定义的行为。
为了防止你可以激活编译器警告,许多编译器知道*f
函数期望的参数类型,即将字符串作为要解析的格式的函数,并允许函数正确地获取其余的参数通过变量参数传递给它。
在程序中调用scanf()
的正确方法是
if (scanf("%d", &num_students) != 1)
return 1;
即来自main()
,因此它结束了该计划,因为在该条件成立后您无法继续,在这种情况下实际发生的是num_students
未初始化,这将再次导致未定义的行为。