teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

6

修正

2021/08/14 06:07

投稿

episteme
episteme

スコア16612

answer CHANGED
@@ -39,28 +39,28 @@
39
39
 
40
40
  ```C
41
41
  #include <stdio.h>
42
+ #include <stdbool.h>
42
43
 
43
44
  /* どんな配列が検索対象であっても使えるスマートな検索関数 */
44
- void* find_if(const void* key, const void* base, unsigned int nelem, unsigned int size, int (*comp)(const void*, const void*)) {
45
+ void* find_if(const void* base, unsigned int nelem, unsigned int size, bool (*comp)(const void*, const void*), void* arg) {
45
46
  for ( unsigned int i = 0; i < nelem ; ++i ) {
46
- if ( !comp(key, base) ) return base;
47
+ if ( comp(base, arg) ) return base;
47
48
  base = (const unsigned char*)base + size;
48
49
  }
49
50
  return NULL;
50
51
  }
51
52
 
52
- /* 比較関数: 等しいならば 0 を返す */
53
+ /* 比較関数: 等しいならば true を返す */
53
- int equals(const void* x, const void* y) {
54
+ bool equals(const void* item, const void* arg) {
54
- return *(const int*)x == *(const int*)y ? 0 : 1;
55
+ return *(const int*)item == *(const int*)arg;
55
56
  }
56
57
 
57
58
  int main(void) {
58
59
  int data[5] = { 1, 3, 5, 0, 2 };
59
60
 
60
61
  int key = 3;
61
- int* p = (int*)find_if(&key,
62
+ int* p = (int*)find_if(data, 5, sizeof(int),
62
- data, 5, sizeof(int),
63
- equals);
63
+ equals, &key);
64
64
  if ( p != NULL ) {
65
65
  printf("found %d at %p\n", *p, p);
66
66
  } else {

5

修正

2021/08/14 06:07

投稿

episteme
episteme

スコア16612

answer CHANGED
@@ -34,14 +34,15 @@
34
34
  [追記] 後出しジャンケンに対応:
35
35
  > ライブラリ関数の利用は考えていないと書いていませんでした。これも含めようと思います。
36
36
 
37
- **どうせなら使いまわしの効くコードを書くのがスマート**と考えるなら
37
+ **どうせなら使いまわしの効くコードを書くのがスマート**と考えるなら
38
+ qsort みたく配列の型にも要素数にも検索条件にも依存しない検索関数を定義します。
38
39
 
39
40
  ```C
40
41
  #include <stdio.h>
41
42
 
42
43
  /* どんな配列が検索対象であっても使えるスマートな検索関数 */
43
- void* find_if(const void* key, const void* base, unsigned int* nelem, unsigned int size, int (*comp)(const void*, const void*)) {
44
+ void* find_if(const void* key, const void* base, unsigned int nelem, unsigned int size, int (*comp)(const void*, const void*)) {
44
- for ( unsigned int i = 0; i < *nelem ; ++i ) {
45
+ for ( unsigned int i = 0; i < nelem ; ++i ) {
45
46
  if ( !comp(key, base) ) return base;
46
47
  base = (const unsigned char*)base + size;
47
48
  }
@@ -55,11 +56,10 @@
55
56
 
56
57
  int main(void) {
57
58
  int data[5] = { 1, 3, 5, 0, 2 };
58
- unsigned int size = 5;
59
59
 
60
60
  int key = 3;
61
61
  int* p = (int*)find_if(&key,
62
- data, &size, sizeof(int),
62
+ data, 5, sizeof(int),
63
63
  equals);
64
64
  if ( p != NULL ) {
65
65
  printf("found %d at %p\n", *p, p);

4

微修正

2021/08/14 05:38

投稿

episteme
episteme

スコア16612

answer CHANGED
@@ -38,13 +38,14 @@
38
38
 
39
39
  ```C
40
40
  #include <stdio.h>
41
- #include <search.h>
42
41
 
43
42
  /* どんな配列が検索対象であっても使えるスマートな検索関数 */
44
43
  void* find_if(const void* key, const void* base, unsigned int* nelem, unsigned int size, int (*comp)(const void*, const void*)) {
45
- unsigned int i;
44
+ for ( unsigned int i = 0; i < *nelem ; ++i ) {
46
- for ( i = 0; i < *nelem && comp(key, base); ++i ) base = (const unsigned char*)base + size;
45
+ if ( !comp(key, base) ) return base;
47
- return i < *nelem ? base : NULL;
46
+ base = (const unsigned char*)base + size;
47
+ }
48
+ return NULL;
48
49
  }
49
50
 
50
51
  /* 比較関数: 等しいならば 0 を返す */

3

追記

2021/08/14 05:27

投稿

episteme
episteme

スコア16612

answer CHANGED
@@ -29,4 +29,42 @@
29
29
  }
30
30
  return 0;
31
31
  }
32
+ ```
33
+
34
+ [追記] 後出しジャンケンに対応:
35
+ > ライブラリ関数の利用は考えていないと書いていませんでした。これも含めようと思います。
36
+
37
+ **どうせなら使いまわしの効くコードを書くのがスマート**と考えるなら
38
+
39
+ ```C
40
+ #include <stdio.h>
41
+ #include <search.h>
42
+
43
+ /* どんな配列が検索対象であっても使えるスマートな検索関数 */
44
+ void* find_if(const void* key, const void* base, unsigned int* nelem, unsigned int size, int (*comp)(const void*, const void*)) {
45
+ unsigned int i;
46
+ for ( i = 0; i < *nelem && comp(key, base); ++i ) base = (const unsigned char*)base + size;
47
+ return i < *nelem ? base : NULL;
48
+ }
49
+
50
+ /* 比較関数: 等しいならば 0 を返す */
51
+ int equals(const void* x, const void* y) {
52
+ return *(const int*)x == *(const int*)y ? 0 : 1;
53
+ }
54
+
55
+ int main(void) {
56
+ int data[5] = { 1, 3, 5, 0, 2 };
57
+ unsigned int size = 5;
58
+
59
+ int key = 3;
60
+ int* p = (int*)find_if(&key,
61
+ data, &size, sizeof(int),
62
+ equals);
63
+ if ( p != NULL ) {
64
+ printf("found %d at %p\n", *p, p);
65
+ } else {
66
+ printf("sorry, not found %d\n", key);
67
+ }
68
+ return 0;
69
+ }
32
70
  ```

2

微修正

2021/08/14 05:23

投稿

episteme
episteme

スコア16612

answer CHANGED
@@ -22,7 +22,7 @@
22
22
  int* p = (int*)_lfind(&key,
23
23
  data, &size, sizeof(int),
24
24
  equals);
25
- if ( p != 0 ) {
25
+ if ( p != NULL ) {
26
26
  printf("found %d at %p\n", *p, p);
27
27
  } else {
28
28
  printf("sorry, not found %d\n", key);

1

微修正

2021/08/14 00:46

投稿

episteme
episteme

スコア16612

answer CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  int main(void) {
17
17
  int data[5] = { 1, 3, 5, 0, 2 };
18
- int size = 5;
18
+ unsigned int size = 5;
19
19
 
20
20
  int key = 3;
21
21
  // VC++ では lfind は deprecated とのこと、しゃーないから _lfind で代用