チェーンテーブルとメモリブロック
15384 ワード
プロジェクトの原因はチェーンテーブルに接触したことがなくて、今日半日かけてチェーンテーブルを研究して、2級のポインタを使うことを発見して、また2級のポインタを研究して、いくつかのチェーンテーブルの小さいプログラムを編纂して、収穫を以下のように整理します.
チェーンテーブルとメモリブロック
チェーンテーブルは実際には、ブロックのメモリをポインタで接続します.これらのメモリは物理アドレスで連続している可能性もあり、不連続である可能性もありますが、チェーンテーブルにポインタがこれらのアドレスを接続しているため、重要ではありません.だから、チェーンテーブルを複数のメモリブロックの接続と見なすことができます.1本のロープにバッタがたくさん詰まっているように、バッタ自体は接続されていませんが、このロープ(チェーンテーブル)で接続されているので、ロープに沿ってすべてのバッタ(チェーンテーブルのノード、つまりメモリブロックのデータ)を見つけることができます.
チェーンテーブルノード構造体(バッタ原型)
次に、保存する必要があるデータを格納するために定義されたノード構造体を示します.構造体の定義は次のとおりです.
ノードを確立した後、チェーンテーブル全体のノードを操作する必要があります.一般的には、ノードの追加、ノードの削除、ノードの内容の変更などです.
チェーンテーブル操作:ノードの追加
ノードを追加するのは,前のノードの
以下のプログラムで定義される
チェーンテーブルの末尾にノードを追加
ノードヘッダにチェーンテーブルを追加し、最初のノードにします.
ノードを指定した後にノードを追加
スプレッドシートアクションスプレッドシートアクション:ノードの削除ノードノサクジョ
ノードを削除する考えも簡単です.例えば、元のチェーンテーブルの順序は
チェーンテーブル操作:ノードデータの変更
データを変更するのは簡単ですが、変更するノードを見つけて変更すればいいです.
チェーンテーブル操作:ノード数の取得
チェーンテーブル印刷
以上はチェーンテーブルの特性に基づいて作成されたいくつかの小さな関数であり,テスト後に特定の機能を実現することができる.
次はメイン関数です.
チェーンテーブルとメモリブロック
チェーンテーブルは実際には、ブロックのメモリをポインタで接続します.これらのメモリは物理アドレスで連続している可能性もあり、不連続である可能性もありますが、チェーンテーブルにポインタがこれらのアドレスを接続しているため、重要ではありません.だから、チェーンテーブルを複数のメモリブロックの接続と見なすことができます.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));
}