C

절차지향 언어인 C 언어로 C++과 같은 객체지향 프로그래밍을 하는 방법을 설명합니다.

 

 

출처 : http://www.s34.co.jp/cpptechdoc/article/oop_in_c/index.html

번역 : 최흥배 ( jacking75@gmail.com )


C에 의한 객체 지향'풍' 프로그래밍

 

 

객체 지향 '풍'이란...

이른바 객체 지향프로그래밍의 세 기둥:

  • 추상 데이터형

  • 계승

  • 다태 ( 다양한 기능 )

 

는 각각이 프로그램의 견뢰함과 보수성/확장성을 강력하게 지원하는 개념입니다.

그리고 Java/C++ 등의 객체 지향 언어라고 칭해지는 프로그램 언어는 모두 기본적으로 이 세 개의 개념을 언어 레벨에서 지원하고 있습니다.

한편 C로 대표되는 구래의 '절차 지향'언어에서는 상기의 개념을 언어 레벨에서는 지원하고 있지 않습니다.

그렇지만 코딩 스타일을 궁리하는 것에 의해서 적어도추상 데이터형에 대해서는 대체로 대체안을 제시하는 것이 가능합니다.

 

  나머지 두 개 즉 계승과 다태를 C로 실현하려면  함수에 포인터 등의 복잡한 조작을 프로그래머에게 강요하게 되어 "불가능하지 않지만 현실적이지 않다"라고 말할 수 있겠지요.

 

 

 

C에 의한 추상 데이터형

추상 데이터형이란

  • 데이터의 구조를 외부에 공개하지 않는다

  • 데이터에 대한 참조/조작은 반드시 함수를 개입시켜 행한다.

 

두  개를 준수하는 것으로 실현됩니다. 즉 데이터를 그 구조나 내용이 아닌 그에 대한 적용할 수 있는 조작의 집합으로(추상적으로) 데이터를 정의하는 것입니다.

 

이렇게 하는 것에 의해서 데이터의 내용/구조가 변화했다고 해도 그 변화는 참조/조작 함수로 흡수할 수 있어 그 데이터를 이용하는 측에게 영향이 작도록 억제할 수 있어 견뢰하고 보수성/확장성을 향상시킵니다.

 

예로서 카드(트럼프)게임의 베이스가 되는 '카드'(Card) 및 카드의 'Pack'을 생각합니다.

Pack에 준비하는 조작은

shuffle 내포 하는 카드를 셔플(섞는다)한다
deal 한 장의 카드를 뺀다
replace (뺀 카드를)Pack에 되돌린다

그리고 Card에 준비하는 조작은

identifysuit 슈츠(하트/다이어/클럽/스페이드)를 돌려준다
identifyvalue 값(2,3,4,....,10,jack,queen,king,ace)을 돌려준다

 

Java/C++에서는 오브젝트 인스턴스에 메세지를 보내 그 결과를 받을 때

result instance.message(parameter);

와 같이 적습니다.  예를 들면 Pack으로부터 Card를 한 장 빼서 Pack에 되돌라는 Java코드는:


Pack pack = new Pack();
Card card = pack.deal(); // Card를 한 장 뺀다
pack.replace(card); // (뺀 Card를) pack에 되돌린다

 

같은 일을 C에서 행하기 위한 스타일을 생각해봅시다.

우선 추상 데이터는 그 상세를 외부에 공개해서는 안 되기 때문에 헤더에는 구조체의 포인터만을 공개합니다.

 

typedef struct card_struct* card;

      이 때 card_struct의 실제 구조(멤버)는 헤더에는 명기하지 않고, ard의 구현부에 둡니다.

 

그리고 card에 준비해야 할 조작(함수)의 머리 부분에 'card_'를 붙여 그 후에 조작명을 계속합니다.

또한 첫 번째 인수로서 조작의 대상(오브젝트)를 줍니다.

 

suit card_identifysuit(card) ;

 

또, 모든 오브젝트에는 특수 조작 즉 오브젝트의 생성과 폐기를 행하는 함수 create / destroy를 준비합니다. 생성 함수 create에 한정하여 조작 대상 오브젝트를 인수로 주지 않고 함수의 반환값으로서 생성된 오브젝트를 돌려줍니다.

 

card card_create(suit, value);
void card_destory(card)


suit.h

/*
* suit.h
*/
#ifndef __SUIT_H__ #define __S UIT_H__ typedef enum {hearts ,clubs ,diamonds ,spades }suit ;
#define suit_lowest () hearts #define suit_highest () spades #define suit_next (s) (( s)+ 1)
#endif
value.h

/*
* value.h
*/
#ifndef __VALUE_H__ #define __VALUE_H__ typedef enum {
two ,three ,four ,five ,six ,seven ,eight ,
nine ,ten ,jack ,queen ,king ,ace }value ;
#define value_lowest () two #define value_highest () ace #define value_next (v) (( v)+ 1)
#endif
card.h

/*
* card.h
*/
#ifndef __CARD_H__ #define __CARD_H__ #include "suit.h"
#include "value.h"
typedef struct card_struct *card ;
/* 구조체 card_struct로의 포인터 card를 정의한다.*/

card card_create (suit ,value );
/* 새로운 card를 생성한다(생성에 실패하면 NULL) */
void card_destory (card );
/* card를 폐기한다.*/

suit card_identifysuite (card );
/* card의 suit를 얻는다*/

value card_idenfiryvalue (card );
/* card의 value를 얻는다*/
#endif
card.c

/*
* card.c
*/
#include "card.h"
#include
struct card_struct {
suit s ;
value v ;
};

card card_create (suit s ,value v ) {
card c = (card )mall oc (sizeof (struct card_struct )) ;
if (c != NULL ) {
c -> s =s ;
c -> v =v ;
}
return c ;
}
void card_destroy (card c ) {
free (c);
}

suit card_identifysuit (card c ) {
return c -> s;
}

value card_identifyvalue (card c ) {
return c -> v;
}
pack.h

/*
* pack.h
*/
#ifndef __PACK_H__ #define __PACK_H__ #include "card.h"
typedef struct pack_struct *pack ;
/* 구조체 pack_struct로의 포인터 'pack'을 정의한다.
* pack_struct 의 자세한 것은 외부에 공개하지 않는다
*/
#define PACK_MAXCARDS 52 /* pack에 포함되는 card의 최대수*/

pack pack_create (void );
/* pack을 생성한다. 메모리 부족시에는 NULL을 돌려준다.*/
void pack_destroy (pack );
/* pack을 폐기한다. 이 조작 뒤에 pack을 사용해서는 안 된다.*/
void pack_shuffle (pack );
/* pack 안의 card를 섞는다.*/

card pack_deal (pack );
/* pack으로부터 card를 한 장 꺼낸다. pack 안에 card가 한 장도 없을 때는 NULL */
void pack_replace (pack ,card );
/* card를 pack에 되돌린다.*/
#endif
pack.c

/*
* pack.c
*/
#include "pack.h"
#include
#include
struct pack_struct {
int numberofcards ;
card cards [PACK_MAXCARDS ];
};

pack pack_crate (void ) {
pack p ;
p = (pack )malloc (sizeof (struct pack_struct )) ;
if (p != NULL ) {
suit s ;
value v ;
p -> numberofcards = 0;
for (s =suit_lowest () ;s <= suit_highest () ;s =suit_next (s) ) {
for (v =value_lowest () ;v <= value_highest () ;v =value_next (v) ) {
card c ;
c =card_create (s,v );
if (c == NULL ) {
pack_destroy (p);
return NULL ;
}
pack_replace (p,c );
}
}
}
return p ;
}
void pack_destory (pack p ) {
int n ;
for (n =p -> numberofcards -1;n >= 0; -- n ) {
card_destory (p-> cards [n]) ;
}
free (p);
}
void pack_shufle (pack p ) {
int n ;
for (n =p -> numberofcards -1;n >= 0; -- n ) {
int swappos =rand () % (n+1);
card tempcard =p -> cards [n];
p -> cards [n] =p -> cards [swappos ];
p -> cards [swappos ] =tempcard ;
}
}

card pack_deal (pack p ) {
if (p -> numberofcards == 0 ) {
return NULL ;
} else {
return p -> cards [-- p-> numberofcards ];
}
}
void pack_replace (pack p ,card c ) {
assert (p-> numberofcards <<span style="font-family:굴림체; font-size:12pt;"> PACK_MAXCARDS
);
p -> cards [p-> numberofcards ++] =c ;
}

 

 

이러한 스타일을 채용했을 경우 Pack으로부터 Card를 한 장 빼서 Pack에 되돌리는 C 코드는 다음과 같이 됩니다.



pack p;
card c;
p = pack_create (); // pack을 생성한다
pack_shuffle (p); // pack을 섞다
c = pack_deal (p); // pack으로부터 card를 뺀다
pack_replace (p, c); // card를 pack에 되돌린다
pack_destroy (p); // pack을 폐기한다

 

 

C++이면 다음과 같은 코드가 되겠지요. 위의 코드와의 대비로부터 C에서 추상 데이터형으로 실현되고 있는 모습을 간파할 수 있습니다.



pack * p;
card * c;
p = new pack ; // pack을 생성한다
p-> shuffle (); // pack을 섞다
c = p-> deal (); // pack으로부터 card를 뺀다
p-> replace (c); // card를 pack에 되돌린다
delete p ; // pack을 폐기한다

 

이 글은 스프링노트에서 작성되었습니다.

by 흥배 2009.03.30 14:38
C, C++

강컴에서 C++ 책을 검색을 하다가 우연찮게 2008년 1월에서 10월9일까지 한국에서 출간된 C/C++ 책

리스트를 보니 생각보다 많이 출간된 것 같더군요.


제가 처음 프로그래밍을 배울 때는 C/C++이 주류 언어로 이때는 C 언어가 프로그래밍 언어에서 왕좌 자리에 있었고 C++이 그 자리를 뺏아아 가는 시기였던 것같습니다.

그런데 요즘은 점점 C/C++ 언어는 그 자리를 자바나 C#, 스크립트 언어 등에 자리를 내어주고 있습니다. 대학교에서도 C/C++ 수업을 별로 하지 않고 잘 모르는 대부분의 대학생들이 잘 모른다고 하더군요.


2008년에 출간된 책을 보니 대다수가 초급자를 위한 책이 대부분이더군요.

중고급자용 책이 나오지 않아서 아쉽지만 그래도 초급자 책이라도 이정도 출간되어서 나름 다행이라고 생각합니다.


아직 게임업계에서는 C++이 주류 언어이고 최소한 몇년은 더 주류 언어로 있을 것같지만 언제까지일지 궁금하기도 합니다.


아래는 강컴에 등록된 2008년 C/C++ 출간 도서 리스트입니다.


1. C언어로 배우는 8051

2. 행복해지는 C & C++

3. Windows Cryptography with C++

4. 화공전산 (C,C++,MATLAB)

5. C++로 시작하는 객체지향 프로그래밍 (핵심요약판)

6. C++ 프로그래밍 완전 정복

7. C++를 이용한 크로스 플랫폼 개발

8. C언어 100문 / 100답

9. C 프로그래밍 완전 정복

10. 멀티미디어 게임 개발을 위한 VISUAL C++ 게임 제작 프로젝트 따라하기

11. Component Development with Visual C++ & ATL

12. C언어 윈도우즈 API 프로그래밍

13. Data Structure & Algorithm with c/c++

14. C 프로그래밍 파워 업그레이드

15. Practical C Pointer

16. 비주얼 c++ MFC입문

17. 비기닝 ANSI C++

18. VC++와 MFC를 이용한 Multimedia Programming

19. ROBOTC로 접근하는 C프로그래밍 입문

20. 씽킹 다이어리: C프로그래밍으로 가는 여행

21. Let's go C : C프로그래밍과의 여행

22. Blog2Book 임베디드 프로그래밍 C 코드 최적화

23. 단계적으로 배우는 C&C++ 언어의 완성

24. C언어 프로그래밍

25. NEW C 언어 입문 : 초급자편

26. 제대로배우는 C Language Programming

27. 친절한 김샘의 함수 포인터 강의 : C/C++

28. New C Programming with a workbook

29. c로 쓴 자료구조론 2/E

30. 카드게임으로 배우는 C++ 프로그래밍

31. 예제로 쉽게 풀어 쓴 C 기초 프로그래밍

32. IT COOKBOOK for Beginner, C++ 기초

33. OK! C Programming

34. iT Energy C

35. 예제로 쉽게 배우는 Visual C++

36. C로 배우는 프로그래밍 기초 2/e


10 번과 30번의 책이 흥미로운 제목을 가지고 있는 책인데 이 책들의 목차를 보니 10번은 주로 DirectSound와 DirectDraw, DirectShow를 중심으로 설명하고 마지막에 이것들을 이용하여 게임을 만드는 예제가 있고, 30번은 C++의 기초부터 설명하면서 사이사이에 카드 게임에 대한 이야기가 있는 것 같더군요.


by 흥배 2009.03.21 12:23
| 1 2 |