프로그래밍을 하다보면 비슷한 기능을 하는 함수를 구현해야 하는 경우가 많다. 그럴때마다 전에 작성했던 코드를 참조하게 된다.
이런 경우, 프로그래밍을 작성하고 검증하는데 소요되는 시간을 줄일 수 있다. 바로 이러한 장점 때문에 디자인 패턴이라는 개념이 나오게 되지 않았나 생각한다.
여기서는 프로그램을 작성하다가 유용하다고 생각되는 함수를 소개할 것이다. 99.99 % C 언어가 기준이 될 것이다.
배열을 이용한 함수 호출
일반적으로 함수호출은 프로그램 루틴 중에 함수의 이름을 적어줌으로서 호출된다. 그렇다면, 어떤 경우에 배열을 이용해서 함수를 호출하는 것일까?
간단한 예를 하나 들어보겠다.
리눅스 디바이스 드라이버를 만들기 위해서는 각 디바이스마다 알아야 하는 여러가지 규칙이 있지만, 그 중에서 모든 드라이버에 공통적으로 해당되는 규칙이 있다면 그것은 바로 open(), close(), ioctl() 등의 함수가 반드시 있어야 한다는 것이다.
함수 이름은 같지만, 각 드라이버마다 루틴은 다르다. 바로 이런 경우에 배열을 이용해서 함수를 호출함으로서 해결할 수 있다.
이제 구체적인 사용 예제를 살펴보도록 하자!
typedef struct _tag_DB_OP { int type; int (*insert)(int value); int (*delete)(int value); int (*print)(int value); }DB_OP_T; ... int db_btree_insert(int value); int db_btree_delete(int value); int db_btree_print(int value); int db_dummy_insert(int value); int db_dummy_delete(int value); int db_dummy_print(int value); ... static DB_OP_T btree_op = { insert:db_btree_insert, delete:db_btree_delete, print:db_btree_print, }; static DB_OP_T dummy_op = { insert:db_dummy_insert, delete:db_dummy_delete, print:db_dummy_print, }; static DB_OP_T * db_ops[DB_MAX] = { &btree_op, /* 0 */ &dummy_op, /* 1 */ }; ... int main(void) { DB_OP_T * set_db; set_db = (DB_OP_T *)malloc(sizeof(DB_OP_T)); set_db->type = db_type; // 0 또는 1 할당에 따라 호출되는 함수가 다름(btree_* 또는 dummy_*) memcpy((void *)set_db,(void *)db_ops[set_db->type],sizeof(DB_OP_T)); set_db->insert(5); // db_btree_insert 함수 호출 ...
아래 예제의 경우, type 변수값에 따라 'set_db→insert' 시에 호출되는 함수가 달라진다.