给出分段错误的位字段

Bit fields giving segmentation fault

这是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;
}

当你想要 scanf() 扫描你的东西时,你必须传递 地址 的东西,而不是实际的东西. (如果你不把某物的地址传递给scanf(),那scanf()怎么能在里面存储一个值呢?)

现在,在 C 语言中,当您引用 e[i].name 这样的数组时,您实际上是指数组第一个元素的地址,因此您不必对此做任何特殊处理。 (另外要注意name不要输入超过9个字符,wh00ps,非常不安全,小心!)

但是对于整数,例如 e[i].d.day 等,您不能按原样传递 int,因为 scanf() 需要指针,所以它会处理您的 int 作为指向 int 的指针,因此它将允许用户输入一个数字,然后它将尝试将该数字存储在该指针指向的位置,这只是内存中的某个随机位置,因此出现段错误。

所以,当你想扫描一个int时,你必须传递int的地址,像这样:&e[i].d.day

除了当整数是记录的一个字段时,你不能获取它的地址,因为它没有自己的地址,它存在于存储在地址中的一些位中。

所以,恐怕你将不得不编写一个特殊的函数来读取你的那些 struct dates,它必须声明个人 ints,将它们的地址传递给 scanf(),然后将结果值存储在 struct date.