前回
参考ページ
モノづくりC言語塾 C言語 関数ポインタ【ポインタを使って関数を呼ぶ仕組み解説】
SAMEBASE サメベース 【[C言語]双方向リストとその基本操作(追加、削除、挿入)関数の実装[コード付]】
Programming Place Plus 【連結リスト②(双方向・循環) | Programming Place Plus アルゴリズムとデータ構造編【データ構造】 第4章】
参考文献
問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)
大槻兼資・著 秋葉拓哉・監修
準備
今回はオンラインコンパイラを使用します。
オンラインコンパイラ
ソースコード
sample.c
#include <stdio.h>
#include <stdlib.h>
//Hello_Variable型を定義する
typedef struct Hello_Variable {
long i;
double d[11];
}Hello_Variable;
//関数fを代入することを想定して、関数ポインタfupo型を定義する
typedef void (*fupo)(Hello_Variable*);
//関数fを代入することを想定して、fupo型の変数uを構造体Hello型の内に定義する
typedef struct Hello {
Hello_Variable j;
fupo u;
}Hello;
// ノードの構造体
typedef struct Node {
Hello data;
struct Node* next;
struct Node* prev;
}Node;
// 新しいノードを作成する関数
struct Node* createNode(Hello data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("メモリの割り当てに失敗しました\n");
exit(1);
}
newNode->data = data;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}
// リストの先頭にノードを挿入する関数
void insertAtBeginning(struct Node** head, Hello data) {
struct Node* newNode = createNode(data);
newNode->next = *head;
if (*head != NULL) {
(*head)->prev = newNode;
}
*head = newNode;
}
// リストの末尾にノードを挿入する関数
void insertAtEnd(struct Node** head, Hello data) {
struct Node* newNode = createNode(data);
struct Node* current = *head;
if (current == NULL) {
*head = newNode;
} else {
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
}
}
// リストを表示する関数
void printList(struct Node* head) {
struct Node* current = head;
while (current != NULL) {
//Hello型関数ポインタuを実行
current->data.u(¤t->data.j);
//Hello_Variable型変数j.iを表示
printf("%ld -> ", current->data.j.i);
current = current->next;
}
printf("NULL\n");
}
void f(Hello_Variable* v){
//引数v->dに値を代入
v->d[v->i]=1+(v->i*0.1);
//引数v->dを表示
printf("_%1.2lf_",v->d[v->i]);
//引数v->iに1を加算
v->i++;
if(v->i<=10){
//引数iが10以下のとき関数fを再帰呼び出し
f(v);
}
else{
printf("\n");
//引数iが10より上になったらHELLO_VARIABLEポインタ型vを返す
return;
}
return;
}
int main() {
struct Node* myList = NULL;
Hello data[4];
int i=0;
for(;i<4;i++){
//Hello_Variable型変数j.iに0を代入
data[i].j.i=0;
//関数fを代入
data[i].u=f;
}
// リストに要素を追加
insertAtBeginning(&myList, data[0]);
insertAtBeginning(&myList, data[1]);
insertAtBeginning(&myList, data[2]);
insertAtEnd(&myList, data[3]);
// リストを表示
printf("双方向リスト: ");
printList(myList);
return 0;
}
実行結果
console
双方向リスト: _1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
11 -> _1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
11 -> _1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
11 -> _1.00__1.10__1.20__1.30__1.40__1.50__1.60__1.70__1.80__1.90__2.00_
11 -> NULL