0

我不是 C 的真正粉丝,但我为这个练习做了功课。到目前为止,我得到的是,在 C 中,初始化一个数组,据我所知,不像 JavaScript。C 有固定的数组,而不是由特定值初始化。所以NULL在这种情况下检查将不起作用。

我有一系列结构。我怎么知道数组中的索引是否为空(是否填充了结构)?

#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

此外,我们受限于在此练习中使用数组。如果我们被允许使用链表,这将是在公园里散步,因为我们已经知道如何使用动态列表。

我该怎么做?还是我从错误的角度看待问题(除了必须使用数组而不是链表)?

4

4 回答 4

4

一种选择是在结构中使用某种哨兵值。例如,您可以检查该id字段的长度是否为零,这将指示数组中的一个未占用位置。

缺点是您必须在创建数组时正确初始化所有元素。如果您从数组中“删除”一个元素,您还必须重置标记值。

如其他答案之一所述,您还可以更改为具有指向结构的指针数组,在这种情况下,您可以直接检查 NULL。

于 2012-12-11T16:17:11.007 回答
2

C 中的数组没有空的位置。如果数组存在,则其中的所有元素都存在。

一个元素可能没有被初始化,但没有通用的方法来确定它,除非在你的程序中自己跟踪它。例如,一旦分配了数组,就初始化其中的所有内容。或者保持一个数字 N 表示数组的前 N ​​个元素已经被初始化。

如果您想知道每个单独的元素是否已被初始化,您必须自己维护该信息,要么在单独的数组中,要么在结构中添加一个标志,以便每个元素都有自己的标志,说明其余的是否该元素中的结构已被初始化。当然,您需要初始化这些标志。

于 2012-12-11T16:17:39.657 回答
0

我有一系列结构。我怎么知道数组中的索引是否为空(未填充结构)?

您可以做的是向结构添加一个标志,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(即,分配了指针数组,它指向的结构不一定如此);但是在这里你预先分配了结构,所以你必须以不同的方式来做。

于 2012-12-11T16:17:54.190 回答
0

例如,将“set/valid”字段添加到您的 NODE typedef 中,每次将 NODE 插入 List 时,只需将“set/valid”设置为 1。这样你总是可以判断这是否是有效的数组元素等。

于 2012-12-11T16:24:05.137 回答