这是C语言。当我运行以下程序时,无论我给出多小的值,我都会得到运行时分段错误。请帮我找出原因。
#include <stdio.h>
#include <stdlib.h>
struct date
{
unsigned day:
5;
unsigned month:
4;
unsigned year:
12;
};
struct emp
{
char name[10];
struct date d;
};
int compare(const void * a, const void * b)
{
struct emp *orderA = (struct emp *)a;
struct emp *orderB = (struct emp *)b;
return ( orderA->d.year - orderB->d.year );
}
int main ()
{
int i;
struct emp e[5];
for (i = 0;i < 5;i++)
{
scanf("%s %d %d %d", e[i].name, e[i].d.day, e[i].d.month, e[i].d.year);
}
qsort(e, 5, sizeof(struct emp), compare);
for (i = 0;i < 5;i++)
{
printf("%s %d %d %d\n", e[i].name, e[i].d.day, e[i].d.month, e[i].d.year);
}
return 0;
}
答案 0 :(得分:5)
当您希望scanf()
扫描您的内容时,您必须传递 地址 的内容,而不是实际内容。 (如果您未将某些内容的地址传递给scanf()
,那么scanf()
如何在其中存储值?)
现在,在C引用e[i].name
之类的数组时,实际上是指数组的第一个元素的地址,因此您不必对此做任何特殊处理。 (除了小心不要输入超过9个字符的名称,wh00ps,这是非常不安全的,小心!)
但是对于整数,例如e[i].d.day
等,你不能按原样传递int
,因为scanf()
需要指针,所以它会处理你的int
}作为指向int
的指针,因此它将允许用户输入一个数字,然后它会尝试将数字存储在该指针指向的位置,这只是内存中的一些随机位置,并且因此是段错误。
因此,当您要扫描int
时,您必须传递int
的地址,如下所示:&e[i].d.day
除了当整数是记录的字段时,你不能取其地址,因为它没有自己的地址,它存在于存储在地址的某些位中。
所以,我担心你将不得不写一个特殊的函数来阅读你的struct date
,你必须声明个别的int
,将它们的地址传递给{{1然后将结果值存储在scanf()
。