2012-12-11 43 views
0

我並不是C的粉絲,但是我爲此練習做了功課。到目前爲止,我得到的是,在C中,據我所知,初始化一個數組並不像JavaScript。 C有固定的數組,並沒有用特定的值初始化。因此NULL檢查在這種情況下不起作用。我有一個結構數組。如何知道數組中的索引是否爲空(用一個結構體填充)?檢查結構數組中的索引是否爲空或不在C

#define LIST_LENGTH 30 

//This is the struct that is inserted in the array 
typedef struct node{ 
    char fName[30]; 
    char mName[30]; 
    char lName[30]; 
    char id[8]; 
} NODE; 

typedef struct { 
    int size; //size is the struct's total capacity (at 30) 
    int length; //tracks how many elements are added, but not where 
    NODE nodes[LIST_LENGTH]; //This is the array in question 
} List; 

//somewhere in my code, I have to insert a value to the array at a specific position. 
//if that position is occupied, I have to find the nearest empty position 
//to the right, and shift the values rightward for that spot to be empty 

此外,我們限制使用數組進行此練習。如果我們被授予使用鏈表,這將是在公園散步,因爲我們已經知道如何使用動態列表。

我該怎麼辦?或者我以錯誤的角度看問題(除了必須使用數組而不是鏈接列表)?

+0

如何將所有索引'> = length'視爲空?或者是帶有「孔」的陣列? – chill

+0

至於你的代碼,你的「數組索引」始終是非空的... – sleepsort

+2

你可以做的一件事是有一個指向NODE的指針數組,並將它初始化爲零(例如用memset)。如果一個位置有一個空指針,這意味着它是空的。 –

回答

4

一個選擇是在結構中使用某種標記值。例如,您可以檢查id字段是否爲零長度,這表示陣列中未佔用的點。

不利之處在於,您必須在創建陣列時正確初始化所有元素。如果從陣列中「移除」某個元素,則還必須重置標記值。

正如在其他答案中提到的,您也可以更改爲具有指向結構的指針數組,在這種情況下,您可以直接檢查NULL。

2

C中的數組沒有空位。如果數組存在,則其中的所有元素都存在。

元素可能未被初始化,但沒有通用的方法來確定,除非在程序中自己跟蹤它。例如,一旦分配數組,就初始化其中的所有內容。或者保持數字N,表示數組的前N個元素已經被初始化。

如果你想知道每個單獨的元素是否已初始化與否,你必須自己維護的信息,無論是在一個單獨的陣列或通過添加一個標誌,結構,使每個元素都有自己的標誌說是否該元素的其餘部分已經初始化。當然,您將需要初始化這些標誌。

0

我有一個結構數組。如何知道數組中的索引是否爲空(未用struct填充)?

你可以做什麼要麼添加一個標誌,結構,將IsInitialized,存儲它是否已被填充或不

//This is the struct that is inserted in the array 
typedef struct node{ 
    char fName[30]; 
    char mName[30]; 
    char lName[30]; 
    char id[8]; 
    int isInitialized; 
} NODE; 

,並在陣列中的所有實例初始化爲0

或者您可以使用非法或「無用」的值初始化結構(例如,所有字符串長度爲零或特殊ID)。

int isInitialized(NODE *s) 
{ 
    /* Since C strings are zero-terminated, char id[8] is at most one 
     seven-char string terminated by a binary zero. It can never be 
     normally a sequence of eight 0xFF. */ 
    return memcmp(s->id, 0xFF, 8); 
} 

// You still have to manually mark nodes free at the beginning. 
void initialize(NODE *s) 
{ 
    memset(s->id, 0xFF, 8); 
} 

if (isInitialized(&(myList->nodes[15]))) 
{ 
    ... 
} 

一個需要注意上面的代碼是,現在「ID」不能安全地取出並打印:初始化校驗必須進行,否則的printf()可能無法找到終止零並開始着手,並且在最後一個結構的情況下,可能超出可訪問內存的邊界並確定保護故障崩潰。然而,有人可能會這樣說,因爲打印一個未初始化的結構(無論如何都沒有保存二進制零值)是沒有意義的,所以這樣的檢查將不得不執行。

或者你可以保留一個迄今爲止已經使用了多少結構的計數器(這裏假設你從不標記爲「在數組中間」的結構)。

如果您有指向結構的指針數組,那麼您將能夠在指向尚未初始化的結構的指針中存儲NULL(即,指針數組已分配,它指向的結構不一定所以);但是在這裏你預先分配結構,所以你必須以不同的方式來完成。

+0

對不起,我的意思是*你*會將指針初始化爲NULL。我會重申一遍。 – LSerni

0

將'set/valid'字段添加到NODE typedef,並且每次將NODE插入列表時,只需將'set/valid'設置爲1即可。通過這種方式,您總是可以知道這是否爲有效的數組元素等。