回答編集履歴

6

修正

2021/08/14 06:07

投稿

episteme
episteme

スコア16612

test CHANGED
@@ -80,15 +80,17 @@
80
80
 
81
81
  #include <stdio.h>
82
82
 
83
+ #include <stdbool.h>
84
+
83
85
 
84
86
 
85
87
  /* どんな配列が検索対象であっても使えるスマートな検索関数 */
86
88
 
87
- void* find_if(const void* key, const void* base, unsigned int nelem, unsigned int size, int (*comp)(const void*, const void*)) {
89
+ void* find_if(const void* base, unsigned int nelem, unsigned int size, bool (*comp)(const void*, const void*), void* arg) {
88
90
 
89
91
  for ( unsigned int i = 0; i < nelem ; ++i ) {
90
92
 
91
- if ( !comp(key, base) ) return base;
93
+ if ( comp(base, arg) ) return base;
92
94
 
93
95
  base = (const unsigned char*)base + size;
94
96
 
@@ -100,11 +102,11 @@
100
102
 
101
103
 
102
104
 
103
- /* 比較関数: 等しいならば 0 を返す */
105
+ /* 比較関数: 等しいならば true を返す */
104
106
 
105
- int equals(const void* x, const void* y) {
107
+ bool equals(const void* item, const void* arg) {
106
108
 
107
- return *(const int*)x == *(const int*)y ? 0 : 1;
109
+ return *(const int*)item == *(const int*)arg;
108
110
 
109
111
  }
110
112
 
@@ -118,11 +120,9 @@
118
120
 
119
121
  int key = 3;
120
122
 
121
- int* p = (int*)find_if(&key,
123
+ int* p = (int*)find_if(data, 5, sizeof(int),
122
124
 
123
- data, 5, sizeof(int),
124
-
125
- equals);
125
+ equals, &key);
126
126
 
127
127
  if ( p != NULL ) {
128
128
 

5

修正

2021/08/14 06:07

投稿

episteme
episteme

スコア16612

test CHANGED
@@ -70,7 +70,9 @@
70
70
 
71
71
 
72
72
 
73
- **どうせなら使いまわしの効くコードを書くのがスマート**と考えるなら
73
+ **どうせなら使いまわしの効くコードを書くのがスマート**と考えるなら
74
+
75
+ qsort みたく配列の型にも要素数にも検索条件にも依存しない検索関数を定義します。
74
76
 
75
77
 
76
78
 
@@ -82,9 +84,9 @@
82
84
 
83
85
  /* どんな配列が検索対象であっても使えるスマートな検索関数 */
84
86
 
85
- void* find_if(const void* key, const void* base, unsigned int* nelem, unsigned int size, int (*comp)(const void*, const void*)) {
87
+ void* find_if(const void* key, const void* base, unsigned int nelem, unsigned int size, int (*comp)(const void*, const void*)) {
86
88
 
87
- for ( unsigned int i = 0; i < *nelem ; ++i ) {
89
+ for ( unsigned int i = 0; i < nelem ; ++i ) {
88
90
 
89
91
  if ( !comp(key, base) ) return base;
90
92
 
@@ -112,15 +114,13 @@
112
114
 
113
115
  int data[5] = { 1, 3, 5, 0, 2 };
114
116
 
115
- unsigned int size = 5;
116
-
117
117
 
118
118
 
119
119
  int key = 3;
120
120
 
121
121
  int* p = (int*)find_if(&key,
122
122
 
123
- data, &size, sizeof(int),
123
+ data, 5, sizeof(int),
124
124
 
125
125
  equals);
126
126
 

4

微修正

2021/08/14 05:38

投稿

episteme
episteme

スコア16612

test CHANGED
@@ -78,19 +78,21 @@
78
78
 
79
79
  #include <stdio.h>
80
80
 
81
- #include <search.h>
82
-
83
81
 
84
82
 
85
83
  /* どんな配列が検索対象であっても使えるスマートな検索関数 */
86
84
 
87
85
  void* find_if(const void* key, const void* base, unsigned int* nelem, unsigned int size, int (*comp)(const void*, const void*)) {
88
86
 
89
- unsigned int i;
87
+ for ( unsigned int i = 0; i < *nelem ; ++i ) {
90
88
 
91
- for ( i = 0; i < *nelem && comp(key, base); ++i ) base = (const unsigned char*)base + size;
89
+ if ( !comp(key, base) ) return base;
92
90
 
93
- return i < *nelem ? base : NULL;
91
+ base = (const unsigned char*)base + size;
92
+
93
+ }
94
+
95
+ return NULL;
94
96
 
95
97
  }
96
98
 

3

追記

2021/08/14 05:27

投稿

episteme
episteme

スコア16612

test CHANGED
@@ -61,3 +61,79 @@
61
61
  }
62
62
 
63
63
  ```
64
+
65
+
66
+
67
+ [追記] 後出しジャンケンに対応:
68
+
69
+ > ライブラリ関数の利用は考えていないと書いていませんでした。これも含めようと思います。
70
+
71
+
72
+
73
+ **どうせなら使いまわしの効くコードを書くのがスマート**と考えるなら
74
+
75
+
76
+
77
+ ```C
78
+
79
+ #include <stdio.h>
80
+
81
+ #include <search.h>
82
+
83
+
84
+
85
+ /* どんな配列が検索対象であっても使えるスマートな検索関数 */
86
+
87
+ void* find_if(const void* key, const void* base, unsigned int* nelem, unsigned int size, int (*comp)(const void*, const void*)) {
88
+
89
+ unsigned int i;
90
+
91
+ for ( i = 0; i < *nelem && comp(key, base); ++i ) base = (const unsigned char*)base + size;
92
+
93
+ return i < *nelem ? base : NULL;
94
+
95
+ }
96
+
97
+
98
+
99
+ /* 比較関数: 等しいならば 0 を返す */
100
+
101
+ int equals(const void* x, const void* y) {
102
+
103
+ return *(const int*)x == *(const int*)y ? 0 : 1;
104
+
105
+ }
106
+
107
+
108
+
109
+ int main(void) {
110
+
111
+ int data[5] = { 1, 3, 5, 0, 2 };
112
+
113
+ unsigned int size = 5;
114
+
115
+
116
+
117
+ int key = 3;
118
+
119
+ int* p = (int*)find_if(&key,
120
+
121
+ data, &size, sizeof(int),
122
+
123
+ equals);
124
+
125
+ if ( p != NULL ) {
126
+
127
+ printf("found %d at %p\n", *p, p);
128
+
129
+ } else {
130
+
131
+ printf("sorry, not found %d\n", key);
132
+
133
+ }
134
+
135
+ return 0;
136
+
137
+ }
138
+
139
+ ```

2

微修正

2021/08/14 05:23

投稿

episteme
episteme

スコア16612

test CHANGED
@@ -46,7 +46,7 @@
46
46
 
47
47
  equals);
48
48
 
49
- if ( p != 0 ) {
49
+ if ( p != NULL ) {
50
50
 
51
51
  printf("found %d at %p\n", *p, p);
52
52
 

1

微修正

2021/08/14 00:46

投稿

episteme
episteme

スコア16612

test CHANGED
@@ -32,7 +32,7 @@
32
32
 
33
33
  int data[5] = { 1, 3, 5, 0, 2 };
34
34
 
35
- int size = 5;
35
+ unsigned int size = 5;
36
36
 
37
37
 
38
38