假設你被分配到用 C 語言編寫一個檔案系統。struct file_item
代表一個檔案或目錄。data
union可以包含檔案的內容(作為字串)或一個指向子 file_item
的指標陣列。針對這個問題,假設指標的長度為 4 個位元組。
#include <stdbool.h>
typedef struct file_item {
char *name;
bool is_directory;
file_item_data data;
} file_item;
typedef union file_item_data {
char contents[X];
struct file_item *children[16];
} file_item_data;
/* Copies all characters from src to dest including the NULL terminator */
char *strcpy(char *dest, const char *src);
typedef struct file_item
:
file_item
的結構體,這個結構體用來表示一個檔案或目錄。char *name;
:儲存檔案或目錄的名稱,為一個指向字串的指標。bool is_directory;
:表示該項目是否為目錄。如果是目錄,則為 true
;如果是檔案,則為 false
。file_item_data data;
:是一個 union 類型,根據 is_directory
的值,決定是儲存檔案的內容還是子目錄指標。typedef union file_item_data
:
file_item_data
根據檔案類型儲存不同的資料:
char contents[X];
:如果該項目是檔案,則 contents
儲存檔案的內容,X
代表內容的大小(未指定大小,可能要根據實際需求定義)。struct file_item *children[16];
:如果該項目是目錄,則 children
會存放指向其他 file_item
結構體的指標,這些指標代表目錄下的子項目。最多可以包含 16 個子項目。strcpy
函式:
strcpy
是一個標準函式,目的是將來源字串 src
複製到目標字串 dest
中。它會將字串的所有字元,包括結尾的 NULL
終止符,一併複製到 dest
。我們將 X 設定為不增加 union 大小的最大值。那麼,我們可以在單一檔案中儲存的字串最大長度是多少呢?
B01 = 63
union 的大小由其最大的元素決定,忽略對齊規則(這裡不考慮)。在 32 位系統中,指標是 32 位(4 個位元組)。children
是一個包含 16 個指標的陣列,佔用的空間為 16 × 4 = 64 位元組。因此,我們必須確保 char contents[X]
不超過 64 位元組。由於 1 個位元組被定義為 char
的大小,將 X 設定為 64 可以達到我們的目標。結果,strlen(contents)
會返回 63,因為它不計算字串長度中的結束符號。
撰寫程式碼來建立檔案和目錄。確保即使輸入的字串在稍後被釋放,你的程式碼仍然能夠正常運作。假設輸入的字串可以適當地放入 file_item_data
union 中。
/* Creates a file with the given name and contents,
* and returns a pointer to that file.
*/
file_item *create_file(char *contents, const char *name)
{
file_item *new_file = calloc(1, sizeof(file_item));
new_file->name = name;
B02 /* Fill your code here */ ;
return new_file;
}
/* Creates a directory with the given name and no children,
* and returns a pointer to that directory.
*/
file_item *create_directory(const char *name)
{
file_item *new_dir = calloc(1, sizeof(file_item));
new_dir->name = name;
B03 /* Fill your code here */ ;
return new_dir;
}
file_item *create_file(char *contents, const char *name)
file_item *create_file(char *contents, const char *name)
:
contents
是檔案的內容,name
是檔案名稱。file_item *new_file = calloc(1, sizeof(file_item));
:
calloc
函數分配記憶體來創建一個 file_item
結構體,並初始化為 0。calloc
分配的記憶體會自動初始化為 0,確保結構中的成員變數在分配後不含垃圾值。new_file->name = name;
:
name
參數值,這樣檔案物件的 name
成員變數就會儲存檔案名稱。B02 /* Fill your code here */
:
contents
複製到 new_file->data.contents
,如:
strcpy(new_file->data.contents, contents);
return new_file;
:
file_item
結構,代表新檔案。file_item *create_directory(const char *name)
file_item *create_directory(const char *name)
:
name
是目錄名稱。file_item *new_dir = calloc(1, sizeof(file_item));
:
calloc
函數分配記憶體來創建一個 file_item
結構體,並初始化為 0。這會確保新建的目錄在其初始化過程中是乾淨的。new_dir->name = name;
:
name
參數值,這樣目錄物件的 name
成員變數就會儲存目錄名稱。B03 /* Fill your code here */
:
file_item
物件為目錄,並確保 children
成員已初始化。如:
new_dir->is_directory = true;
return new_dir;
:
file_item
結構,代表新目錄。你的解決方案應該是完全正確的,不能有任何記憶體洩漏,並且不應包含任何額外的行。
B02 = strcpy(new_file->data.contents, contents) (or equivalent statement)
strcpy(new_file->data.contents, contents)
將 contents
的內容複製到新檔案物件的 data.contents
中。strcpy
確保將傳入的檔案內容完整地複製到 new_file->data.contents
中,這樣即使之後原始的 contents
被釋放,檔案內容仍會保持不變。new_dir->is_directory
設定為 true
,這表示該 file_item
是一個目錄,而不是檔案。is_directory
是一個布林變數,必須設定為 true
以明確標示該物件是目錄而不是檔案。file_item
。這兩個部分都是必需的,分別負責複製檔案內容和標示目錄類型,確保程式正確地運作,且不會有記憶體問題。