未だにスマートな記述方法を知らないケースがあります。
「なにをもってスマートとするか」によるんじゃないかと。
コードを書かずに解決するのがいちばんスマートと考えるなら、
検索アルゴリズムは書かずにライブラリに任せます。
C
1#include <stdio.h>
2#include <search.h>
3
4// 検索はライブラリに任せ、比較関数だけを用意する
5int equals(const void* x, const void* y) {
6 return *(const int*)x == *(const int*)y ? 0 : 1;
7}
8
9int main(void) {
10 int data[5] = { 1, 3, 5, 0, 2 };
11 unsigned int size = 5;
12
13 int key = 3;
14 // VC++ では lfind は deprecated とのこと、しゃーないから _lfind で代用
15 int* p = (int*)_lfind(&key,
16 data, &size, sizeof(int),
17 equals);
18 if ( p != NULL ) {
19 printf("found %d at %p\n", *p, p);
20 } else {
21 printf("sorry, not found %d\n", key);
22 }
23 return 0;
24}
[追記] 後出しジャンケンに対応:
ライブラリ関数の利用は考えていないと書いていませんでした。これも含めようと思います。
どうせなら使いまわしの効くコードを書くのがスマートと考えるなら、
qsort みたく配列の型にも要素数にも検索条件にも依存しない検索関数を定義します。
C
1#include <stdio.h>
2#include <stdbool.h>
3
4/* どんな配列が検索対象であっても使えるスマートな検索関数 */
5void* find_if(const void* base, unsigned int nelem, unsigned int size, bool (*comp)(const void*, const void*), void* arg) {
6 for ( unsigned int i = 0; i < nelem ; ++i ) {
7 if ( comp(base, arg) ) return base;
8 base = (const unsigned char*)base + size;
9 }
10 return NULL;
11}
12
13/* 比較関数: 等しいならば true を返す */
14bool equals(const void* item, const void* arg) {
15 return *(const int*)item == *(const int*)arg;
16}
17
18int main(void) {
19 int data[5] = { 1, 3, 5, 0, 2 };
20
21 int key = 3;
22 int* p = (int*)find_if(data, 5, sizeof(int),
23 equals, &key);
24 if ( p != NULL ) {
25 printf("found %d at %p\n", *p, p);
26 } else {
27 printf("sorry, not found %d\n", key);
28 }
29 return 0;
30}