2016-09-25 96 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