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

1つのオプションは、構造体である種の番兵値を使用することです。たとえば、idフィールドの長さがゼロであるかどうかを確認できます。これは、配列内の空いているスポットを示します。

欠点は、配列を作成するときにすべての要素を適切に初期化する必要があることです。配列から要素を「削除」する場合も、番兵の値をリセットする必要があります。

他の回答の1つで述べたように、構造体へのポインターの配列を持つように変更することもできます。その場合、NULLを直接チェックできます。

于 2012-12-11T16:17:11.007 に答える
2

C の配列には、空の位置はありません。配列が存在する場合、その中のすべての要素が存在します。

要素は初期化されていない可能性がありますが、プログラムで自分で追跡する以外に、それを判断する一般的な方法はありません。たとえば、配列が割り当てられるとすぐに、その中のすべてを初期化します。または、配列の最初の N 個の要素が初期化されたことを示す数値 N を維持します。

個々の要素が初期化されているかどうかを知りたい場合は、別の配列で、または構造体にフラグを追加して、その情報を自分で維持する必要があります。その要素の構造が初期化されました。もちろん、これらのフラグを初期化する必要があります。

于 2012-12-11T16:17:39.657 に答える
0

'set / valid'フィールドをNODEtypedefに追加し、NODEをリストに挿入するたびに、たとえば'set/valid'を1に設定します。このようにして、これが有効な配列要素などであるかどうかを常に判断できます。

于 2012-12-11T16:24:05.137 に答える
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])))
{
    ...
}

上記のコードに対する 1 つの注意点は、「id」を安全に取得して出力することができないことです。初期化チェックを実行する必要があります。そうしないと、printf() が終端のゼロを見つけられず、先に進む可能性があります。 、アクセス可能なメモリの境界を超えて、保護違反のクラッシュを判断する可能性があります。ただし、初期化されていない構造体 (2 進ゼロの保存がとにかく不足している可能性がある) を出力するのは意味がないため、そのようなチェックは関係なく実行する必要があると考えることができます。

または、これまでに使用された構造体の数のカウンターを保持することもできます (これは、配列の「中間」にある構造体を使用可能としてマークしないことを前提としています)。

構造体へのポインターの配列がある場合、まだ初期化されていない構造体へのポインターに NULL を格納できます (つまり、ポインター配列が割り当てられますが、それが指す構造体はまだ割り当てられているとは限りません)。ただし、ここでは構造体を事前に割り当てるため、別の方法で行う必要があります。

于 2012-12-11T16:17:54.190 に答える