检查结构数组中的索引在C中是否为空

时间:2012-12-11 16:13:33

标签: c

我不是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 个答案:

答案 0 :(得分:4)

一种选择是在结构中使用某种sentinel值。例如,您可以检查id字段是否为零长度,这表示数组中有一个未占用的点。

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

正如其他一个答案中所提到的,你也可以改为拥有一个指向结构的指针数组,在这种情况下你可以直接检查NULL。

答案 1 :(得分:2)

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

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

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

答案 2 :(得分: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(即,指针数组被分配,它指向的结构不一定如此);但是你在这里预先分配结构,所以你必须采用不同的方式。

答案 3 :(得分:0)

在您的NODE typedef中添加'set / valid'字段,每次将NODE插入List时,只需将'set / valid'设置为例如。通过这种方式,您可以始终判断这是否是有效的数组元素等。