반응형

  1. void main()
  2. {
  3. int input;
  4. printf("입력 : ");
  5. scanf("%d", &input);
  6. switch(a)
  7. {
  8. case 1:
  9. printf("1번\n");
  10. break;
  11. case 2:
  12. printf("1번\n");
  13. break;
  14. case 3:
  15. printf("1번\n");
  16. break;
  17. case 4:
  18. printf("1번\n");
  19. break;
  20. }
  21. }


위와같은 코드는 유지보수에 있어서 문제가 상당히 큽니다.
case 부분의 실행부분이 커질수록 가독성이 급격히 하락합니다.
그래서 보통 어느정도 생각이 조금 박힌 사람은 다음과 같은 코드를 사용합니다.

  1. void func_one()
  2. {
  3. printf("1번\n");
  4. }
  5. void func_two()
  6. {
  7. printf("2번\n");
  8. }
  9. void func_three()
  10. {
  11. printf("3번\n");
  12. }
  13. void func_four()
  14. {
  15. printf("4번\n");
  16. }
  17. void main()
  18. {
  19. int input;
  20. printf("입력 : ");
  21. scanf("%d", &input);
  22. switch(a)
  23. {
  24. case 1:
  25. func_one();
  26. break;
  27. case 2:
  28. func_two();
  29. break;
  30. case 3:
  31. func_three();
  32. break;
  33. case 4:
  34. func_four();
  35. break;
  36. }
  37. }


프로그램의 구조화를 적용해서 그나마 조금 낫게 만들었네요..
하지만 switch-case 가 남아있어 case 의 몸통이 커질 가능성은 아직 남아있네요..
저 switch-case 를 어떻게 없앨 수 있는가..
여기서 사용할 수 있는게 "함수 포인터 배열" 입니다.

여기서 잠깐
함수 포인터란?
C/C++ 컴파일러는 소스코드를 컴파일할 때, 심벌테이블을 만듭니다(여기까진 다 아시져?)
이 심벌테이블에 들어가는건 변수의 주소 뿐 아니라 함수의 실행코드의 시작위치까지 저장이 되는데요,
(그 단적인 예로 사용자 정의 함수의 이름과 변수의 이름을 똑같이 쓰면 말도 안되는 동작이 가끔씩 나옵니다.)
(변수명 - 주소), (함수명-주소) 의 쌍으로 저장을 합니다. 이러한 특징 때문에 함수의 이름을 포인터처럼 사용할 수가 있는것이져..
말이 너무 길었네요 우선 함수포인터의 선언형태부터 보져

void(*func_ptr)();
와 같은 형식으로 선언합니다.
연산자 우선순위상 다음과 같은 선언을 하게되면
void *func_ptr();
void * 를 리턴하는 함수를 선언하는걸로 인식해서 컴파일러는 에러를 뱉어냅니다.
따라서 () 로 우선순위를 잡아주는거죠...

간단한 함수포인터 사용 예제입니다.

  1. void (*func_ptr)();
  2. void func_one()
  3. {
  4. printf("1번\n");
  5. }
  6. void main()
  7. {
  8. func_ptr = func_one;
  9. (*func_ptr)(); //func_one() 함수 실행
  10. }


위에서 말씀드린것 처럼 함수의 이름이 포인터로 사용되어 호출하는 모습입니다.

이걸 좀더 응용해서 switch-case 를 없애고 가독성을 확보해보도록 하겠습니다.

  1. void (*func_ptr[4])();
  2. void func_one()
  3. {
  4. printf("1번\n");
  5. }
  6. void func_two()
  7. {
  8. printf("2번\n");
  9. }
  10. void func_three()
  11. {
  12. printf("3번\n");
  13. }
  14. void func_four()
  15. {
  16. printf("4번\n");
  17. }
  18. void main()
  19. {
  20. int input;
  21. func_ptr[0] = func_one;
  22. func_ptr[1] = func_two;
  23. func_ptr[2] = func_three;
  24. func_ptr[3] = func_four;
  25. printf("입력 : ");
  26. scanf("%d", &input);
  27. (*func_ptr[input-1])();
  28. }


switch-case 가 사라져서 아주 깔끔한 형태가 되었네요
어때요? 참 쉽져? ㅋㅋㅋ

사족을 달자면, 현재 MFC 에서는 위와 같은 방법으로 메세지를 처리하고 있습니다. 

반응형

+ Recent posts