チェーンテーブルとメモリブロック

15384 ワード

プロジェクトの原因はチェーンテーブルに接触したことがなくて、今日半日かけてチェーンテーブルを研究して、2級のポインタを使うことを発見して、また2級のポインタを研究して、いくつかのチェーンテーブルの小さいプログラムを編纂して、収穫を以下のように整理します.
チェーンテーブルとメモリブロック
チェーンテーブルは実際には、ブロックのメモリをポインタで接続します.これらのメモリは物理アドレスで連続している可能性もあり、不連続である可能性もありますが、チェーンテーブルにポインタがこれらのアドレスを接続しているため、重要ではありません.だから、チェーンテーブルを複数のメモリブロックの接続と見なすことができます.1本のロープにバッタがたくさん詰まっているように、バッタ自体は接続されていませんが、このロープ(チェーンテーブル)で接続されているので、ロープに沿ってすべてのバッタ(チェーンテーブルのノード、つまりメモリブロックのデータ)を見つけることができます.
チェーンテーブルノード構造体(バッタ原型)
次に、保存する必要があるデータを格納するために定義されたノード構造体を示します.構造体の定義は次のとおりです.
struct node
{
    U8 index; //     ,     
    U8 data; //     ,             ,       ,     
    struct node *next;//       (  )   
};
nextポインタはチェーンテーブルの真髄であり、チェーンテーブル内の単一の相互に関連しないノードをnextポインタで相互に接続し、第1のノードは第2のノードを指し、第2のノードは第3のノードを指し、順次類推し、すべてのノードを直列に接続する.
ノードを確立した後、チェーンテーブル全体のノードを操作する必要があります.一般的には、ノードの追加、ノードの削除、ノードの内容の変更などです.
チェーンテーブル操作:ノードの追加
ノードを追加するのは,前のノードのnextポインタを本ノードに向け,本ノードのnextポインタを前のノードの後のノードに向けることである.従来のノードがA B Cに配列されているように、Bの後ろにノードDを追加する必要があります.B->next = D;
D->next = C;
が完了するのは簡単ではありません.もちろん、実際に使うときはこの2つの文より少し複雑かもしれませんが、考えは同じです.以下は私が書いたいくつかのノードを追加する小さなプログラムで、親測が利用できます.
以下のプログラムで定義されるheadはいずれも操作が必要なチェーンテーブルヘッダアドレスであり、itemは追加のノードポインタであり、indexは操作が必要なノードシーケンス番号である.
チェーンテーブルの末尾にノードを追加
/* head --        item --        */
//              head ,  head                 ,         ,  ,       (           ),              ,       
void NodeAddTail(struct node **head, struct node *item)
{
    struct node *temp;

    /*           */
    if (*head == NULL) //          *            (  )
    {
        *head = item; 
        (*head)->next = NULL;
    }
    else
    {
        temp = *head;
        while(temp)
        {
            if (temp->next == NULL)
            {
                temp->next = item;
                item->next = NULL;
            return;
            }
            temp = temp->next;
        }
    }
    return;
}

ノードヘッダにチェーンテーブルを追加し、最初のノードにします.
void NodeAddHead(struct node **head, struct node *item)
{
    /*      */
    if (*head == NULL)
    {
        *head = item;
        (*head)->next = NULL;
    }
    else
    {
        item->next = (*head); /*                 item */
        (*head) = item;         /* item     */
    }
    return;
}

ノードを指定した後にノードを追加
U8 NodeAddIndex(struct node **head, struct node *item,U8 addindex)
{
    struct node *temp;

    //    
    if (*head == NULL)
    {
        *head = item;
        (*head)->next = NULL;
        printf("AddIndex= \r
"
); return 0; } else { temp = *head; while(temp) { if (temp->index == addindex)// { item->next = temp->next; temp->next = item; return 1; } else { temp = temp->next; } } printf("AddIndex= \r
"
); return 2;// } }

スプレッドシートアクションスプレッドシートアクション:ノードの削除ノードノサクジョ
ノードを削除する考えも簡単です.例えば、元のチェーンテーブルの順序はA B C D で、2番目のノードであるBノードを削除する必要があります.Bノードを見つけて、A->next = C;にすればいいだけです.ノードBをどのように見つけるかについては、ノード構造体赤のindex変数に基づいて検索するなど、自分で定義したデータ内容に基づいて判断する必要があります.以下にプログラム例を示す
U8 NodeDelIndex(struct node **head, U8 delindex)
{
    struct node *temp1;
    struct node *temp2;

    if (*head == NULL)
    {
        return 0;
    }
    else
    {
        temp1 = *head;

        if (temp1->index == delindex)
        {
            *head = temp1->next;
            return 1;
        }

        while(temp1->next)
        {
            temp2 = temp1;
            temp1 = temp1->next;

            if (temp1->index == delindex) /*    B*/
            {
                temp2->next = temp1->next; //  A->next = C
                return 1;
            }
        }
    }
    printf("DelIndex=        \r
"
); return 2; }

チェーンテーブル操作:ノードデータの変更
データを変更するのは簡単ですが、変更するノードを見つけて変更すればいいです.
//          data          
U8 NodeModifyIndex(struct node **head, U8 *data,U8 modifyindex)
{
    struct node *temp;

    if (*head == NULL)
    {
        return 0;
    }
    else
    {
        temp = *head;

        while(temp)
        {
            if (temp->index == modifyindex)//      
            {
                memcpy(&temp->data,data,sizeof(temp->data));
                return 1;
            }
            else
            {
                temp = temp->next;
            }
        }
        printf("ModifyIndex=        \r
"
); return 2;// } }

チェーンテーブル操作:ノード数の取得
//           
U16 GetNodeNum(struct node **head)
{
    U16 num = 0;
    struct node *temp;

    if (*head == NULL)
    {
        return num;
    }
    else
    {
        temp = *head;
        num++;
        while(temp)
        {
            if (temp->next == NULL)
            {
                return num;
            }
            temp = temp->next;
            num++;
        }
    }
   return num;
}

チェーンテーブル印刷
void NodeListPrint(struct node **head)
{
    struct node *temp;

    if (*head == NULL)
    {
        printf(" \r
"
); return 0; } else { temp = *head; while(temp) { printf("index=0x%02x",temp->index); printf(" data=0x%02x\r
"
,temp->data); temp = temp->next; } } }

以上はチェーンテーブルの特性に基づいて作成されたいくつかの小さな関数であり,テスト後に特定の機能を実現することができる.
次はメイン関数です.
void main()
{
    struct node *NewNodeList = NULL; /*      */
    struct node Node1,Node2,Node3,Nodeadd;/*         */
    U8 datamodify = 0xAB;/*          0XAB */  
    U8 num=0;/*        */

    /*     */
    Node1.index = 0x1;
    Node1.data = 0x11;
    Node1.next = NULL;

    Node2.index = 0x2;
    Node2.data = 0x22;
    Node2.next = NULL;

    Node3.index = 0x3;
    Node3.data = 0x33;
    Node3.next = NULL;

    Nodeadd.index = 0x4;
    Nodeadd.data= 0x44;
    Nodeadd.next = NULL;    


    //1.    Node1,2,3     
    NodeAddTail(&NewNodeList,&Node1);
    NodeAddTail(&NewNodeList,&Node2);
    NodeAddTail(&NewNodeList,&Node3);

    //2.          
    NodeAddHead(&NewNodeList,&Nodeadd);
    NodeListPrint(&NewNodeList);

    //3.           
    NodeAddIndex(&NewNodeList,&Nodeadd,4);
    NodeListPrint(&NewNodeList);

    //4.          
    NodeDelIndex(&NewNodeList,1);
    NodeDelIndex(&NewNodeList,2);
    NodeDelIndex(&NewNodeList,3);
    NodeDelIndex(&NewNodeList,4);
    NodeListPrint(&NewNodeList);

    //5.           
    NodeModifyIndex(&NewNodeList,&datamodify,0);
    NodeListPrint(&NewNodeList);

    //6.         
    num = GetNodeNum(&NewNodeList);
    printf("   %2d\r
"
,num); //7. printf("\r
%2d"
,sizeof(U8)); printf("\r
%2d"
,sizeof(struct node)); }