2016-09-25 100 views
0

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

C中的Bitfields有很多怪癖,所以我会建议你避免它们,除非你真的需要它们。对于上面的代码,你可以使用'struct date {uint8_t day; uint8_t月; uint16_t年; };',并且您可能会得到相同或更高性能的结构,并且功能更多(可以使用成员地址)。 – user694733

回答

5

当你想scanf()扫描你的东西,你必须通过地址的东西,而不是实际的东西。 (如果你的东西的地址不传递给scanf(),那么如何才能scanf()储存在它的值?)现在

,在C,当你引用数组如e[i].name你实际上指的地址数组的第一个元素,所以你不必做任何特别的事情。 (除了要小心不要输入名称,wh00ps超过900个字符,这是极不安全,小心!)

但随着整数,如e[i].d.day等,你不能仅仅通过int,因为它是,因为scanf()需要指针,因此它会将你的int作为指向int的指针,因此它将允许用户输入一个数字,然后它会尝试将该数字存储在该指针指向的位置,这只是一些在存储器中的随机位置,从而节段错误。

所以,当你要扫描的int,你必须通过int的地址,如:&e[i].d.day

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

所以,恐怕你将不得不写一个特殊功能,用于读取那些struct date小号你的,这将有申报个人int S,通过他们的地址scanf(),然后将得到的值存储在struct date