単方向リストのエントリを表す C 構造体を考えてみましょう。任意のデータへのポインタ、そのデータのサイズ、および次のエントリを見つける方法が含まれています
typedef struct{
unsigned char *data
unsigned char dataSize
unsigned char nextEntry
} Entry;
次に、次のエントリのコレクションとそれらが表すデータについて考えます。
unsigned char dataA[3];
unsigned char dataB[16];
unsigned char dataC[17];
Entry entryA = {dataA, sizeof(dataA), 3}; //It's important for "3" to match up with the index of entryB once it's put into MasterList below.
Entry entryB = {dataB, sizeof(dataB), 4}; //Likewise
Entry entryC = {dataC, sizeof(dataC), 0}; //0 terminates the linked list
Entry emptyEntry = {(void*)0, 0, 0};
Entry MasterList[8] = {
entryA, //Index 0 - Contains dataA and points to Index 3 as the next Entry in a linked list
emptyEntry, //Index 1 - Unused (or used for something else)
emptyEntry, //Index 2 - Unused
entryB, //Index 3 - Contains dataB and points to Index 5 as the next Entry in a linked list
entryC, //Index 4 - Contains dataC and terminates the linked list
emptyEntry, //Index 5 - Unused
emptyEntry, //Index 6 - Unused
emptyEntry};//Index 7 - Unused
私の質問: コンパイル時に「nextEntry」の値を自動的に把握する方法を考えてもらえますか? 現在、誰かが MasterList のエントリの順序をシャッフルしたり、他のデータを追加して一部のエントリをオフセットしたりすると、バグが発生する可能性が非常に高くなります。単体テストまたは統合テストですべてのバグをキャッチしますが、MasterList への変更が 2 回チェックインされることは避けられません。誰かがそれを編集したときと、コードがテストに失敗したときにリンクされたリストのインデックスを修正するために 2 回目。
私の最初の本能は、「いや、それはばかげている」と「なぜこれを試すのですか」です。しかし、私は過去にかなり印象的な C-Macro の魔法を見てきました。また、マクロの魔法は上記よりも維持するのがさらに悪いと思いますが、試してみる価値はあると思いますよね?
明確化- 情報の消費者がこのようになることを期待しているため、MasterList配列(適切なリンクリストではない)に固執しています。実際には、リンクされたリストの一部ではない、固定インデックスにある必要がある他の情報がそこにあります。その上に、このリンクされたリスト データがあります。これがリンクされたリストである理由は、固定インデックスを持つ他の要素が追加されたときに押し出されないようにするためです。たとえば、特定の文字列をインデックス 3 に押し込む必要があることが判明した場合、entryB と entryC は邪魔にならないように押し出される可能性がありますが、リンクされたリストの先頭 (インデックス 0 に固定) から開始することで発見できます。リストを歩いています。