0

あなたが持っていたと想像してください:

myfile.h

typedef struct _myStruct myStruct;

struct _myStruct
{
    uint32_t uData1;
    uint32_t uData2;
    uint32_t uData3;
    /* More data members */
}

void myStructSetData(myStruct * const pMyStruct, const uint32_t uData1, const uint32_t uData2, const uint32_t uData3)
{
    if (!pMyStruct)
        return

    pMyStruct->uData1 = uData1;
    pMyStruct->uData2 = uData2;
    pMyStruct->uData3 = uData3;
}

main.c

int main(void)
{
    ...
    /* myStructSetData(pMyStruct, 1, 2, 3); */
    ...
    myStructBuild(pMyStruct);
    ...
}

myStructSetData() を提供しますが、ユーザーは必ずしもこの関数を使用して uData1、2、および 3 を設定するとは限りません。myStructBuild() では、uData1、2、および 3 が設定されているかどうかを知りたいのですが、 pMyStruct の作成時にそれらを初期化するか、bIsData1Set などの bool 値を使用しました (これは避けたいと思います)。

では、uData1、uData2、および uData3 を -1 に初期化することは理にかなっていますか?

したがって、 myStructBuild() では、次のようなチェックがあります。

if (pMyStruct->uData1 != -1)
{
    /* Include uData1 when building */
}
4

2 に答える 2

2

投稿で-1のような魔法の値または無効な値を使用するか、特別なフラグ フィールドを使用することをお勧めします。

struct _my_struct
{
    int32_t field1;
    int16_t field2;
    int64_t field3;

    bool    field1_valid;
    bool    field2_valid;
    bool    field2_valid;
};

これにより、特に次のような例の場合、コーディングが簡素化されます。

struct _my_struct x;
memset(&x, x, sizeof(x));

つまり、すべての値をゼロにリセットすると、すべての値がunsetになります。

もちろん、ユーザーは「有効」フラグを設定する必要があります。

x.field1_valid = 1;
x.field1 = 444;

そして、後でコードでチェックを使用できます。

ニーズと好みに応じて、有効性フィールドを分離することも、1 つのビットフィールドに結合することもできます。

struct _my_struct
{
    int32_t field1;
    int16_t field2;
    int64_t field3;

    int    field1_valid:1;
    int    field2_valid:1;
    int    field2_valid:1;
};

使い方は上記と同じですが、ストレージサイズが小さくなります (それが重要な場合)。

于 2013-03-13T16:52:18.230 に答える
0

uData変数が有効な unsigned int 値を持つことができる場合は、いいえ。-1変数に格納するだけなので、使用できませんUINT_MAX(intが32ビットであると仮定します)。

を超える値を格納する必要がなくUINT_MAX、構造変数の型を変更できる場合は、利用可能な場合はより大きな型を定義できます (例: uint64_t)。その場合、許容範囲よりも大きい値を格納できます (変換済みなど-1) を使用して、初期化されていないものとしてマークします。-1これは、ファイル ストリームが EOF で戻るのと同じアプローチであるため、intではなくchar.

于 2013-03-13T16:53:20.303 に答える