ビギナはどうしてもやりたいことをすべてmainに詰め込まないと気が済まないみたいだ。
はじめはそれで構わないが、複雑になるになるにつれ見通しが悪くなる。
できるだけ関数に細分化するクセをつけるが吉。
※ 最初っからこんなの↓書けとは言わないし求めてもいない
C
1/* list.c */
2#define _CRT_SECURE_NO_WARNINGS
3#include <stdio.h>
4#include <stdlib.h>
5#include <stdbool.h>
6#include <assert.h>
7
8struct node {
9 int num;
10 struct node* next;
11};
12
13/* nodeを確保し、numとnextを初期化して返す */
14struct node* node_create(int n) {
15 struct node* new_node = (struct node*)malloc(sizeof(struct node));
16 assert( new_node != NULL );
17 new_node->num = n;
18 new_node->next = NULL;
19 return new_node;
20}
21
22/* headを先頭に、pred(p,arg)がtrueである最初のpを返す
23 head == NULL または見つからなければ NULL を返す */
24const struct node* node_find(const struct node* head,
25 bool (*pred)(const struct node*,void*),
26 void* arg) {
27 const struct node* curr_node = head;
28 while ( curr_node != NULL ) {
29 const struct node* next_node = curr_node->next;
30 if ( pred(curr_node, arg) ) break;
31 curr_node = next_node;
32 }
33 return curr_node;
34}
35
36/* pnodeが末尾nodeであればtrueを返す */
37static bool node_is_last(const struct node* pnode, void* un_used) {
38 return pnode->next == NULL;
39}
40
41/* headで示されたリストの先頭にtargetを挿入する
42 挿入後のリストの先頭を返す */
43struct node* node_prepend(struct node* head, struct node* target) {
44 if ( head != NULL ) {
45 target->next = head;
46 }
47 return target;
48}
49
50/* headで示されたリストの末尾にtargetを挿入する
51 挿入後のリストの先頭を返す */
52struct node* node_append(struct node* head, struct node* target) {
53 struct node* last_node = (struct node*)node_find(head, node_is_last, NULL);
54 if ( last_node == NULL ) {
55 head = target;
56 } else {
57 last_node->next = target;
58 }
59 return head;
60}
61
62static bool node_print(const struct node* pnode, void* arg) {
63 const char* format = (const char*)arg;
64 printf(format, pnode->num);
65 return false;
66}
67
68/* headで示されたリストの各要素を formatで指定された書式で
69 標準出力(stdout)に出力する */
70void node_print_all(const struct node* head, const char* format) {
71 node_find(head, node_print, (void*)format);
72}
73
74/* pnodeを解放する */
75static bool node_destroy(const struct node* pnode, void* un_used) {
76 free((void*)pnode);
77 return false;
78}
79
80/* headで示されたリスト内の全要素を解放し、NULLを返す */
81struct node* node_destroy_all(struct node* head) {
82 node_find(head, node_destroy, NULL);
83 return NULL;
84}
85
86/* さて、以上を踏まえてここからが本番
87 といっても仕込み万端整ってるから
88 必要な関数を適宜呼び出すだけで一丁上がり */
89
90int main() {
91 struct node* head = NULL;
92
93 int x;
94 while( scanf("%d",&x) > 0 ) {
95 /* nodeを末尾に挿入する。 (先頭に挿入なら node_prependせよ) */
96 head = node_append(head, node_create(x));
97 }
98
99 // リストの要素のnumの値を先頭から順に表示する
100 node_print_all(head, "%d\n");
101
102 // 全nodeを解放する
103 head = node_destroy_all(head);
104
105 return 0;
106}
107
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。