'CPP'에 해당되는 글. 2건

  1. 2008/06/30 C++에서 const char** (2)
  2. 2008/01/21 Infinite Streams in C++ (2)

EC++ 에 보면 const에 대한 설명이 잠깐 나온다.

설명을 보면..

1. char* a;
2. const char* a;
3. char* const a;
4. const char* const a;

위의 넷이 다른 타입이라는 것을 설명하고 있다.

그렇다면.. 간혹 볼 수 있는 const char** 는  어떤 타입일까?

5. const (const char*)*
6. const (char *)*
7. (const char*)*


일단 5,6,7 중의 하나라고 생각할 수 있겠다.
5,6,7의 차이는 어떤 곳에 const의 속성이 붙느냐에 따라서 명확히 다른 type이다.

그렇다면....
- const char**은 5,6,7 중 어떤 타입일까?
- 셋 중에 하나라면 다른 두 가지는 어떻게 표현해야 할까?

이런 의문점이 생기게 만드는 const char** 표현은 그다지 바람직한 모양은 아닌 것 같다.

일단 정답은 7번
const char**는 (const char*)* 이다.
사용법은 아래와 같다.

char* pc = new char[20];
const char* cpc = new char[20];

const char** cppc;
cppc = &pc; // (X) error: invalid conversion from 'char**' to 'const char**'
cppc = &cpc;
*cppc = pc;
*cppc = cpc;
**cppc = '1'; // (X) error: you cannot assign to a variable that is const

 char** ppc = cppc; // (X) error: invalid conversion from 'const char**' to 'char**'


유의 깊게 볼 점은..
char** 와 const char** 은 상호 conversion이 안 된다는 점인데
char*는 const char*로 conversion이 된다는 점에서 차이가 있음을 알고 있을 필요가 있다.



그렇다면 5, 6번의 타입을 만들고 싶다면 어떻게 해야 할까?
방법 중 하나는 typedef를 쓰면 된다.

typedef char* PCHAR;
typedef const char* CPCHAR;

const PCHAR* a;
const CPCHAR* a;




 

Posted by U∙Seung
TAG C++, char**, const, CPP


이전에 C#으로 SICP에 나온 Infinite Streams을 구현 해본적이 있는데
이번에는 C++로 구현 해보았습니다. 실제로 이런 Lazy한 기법들이 사용될 곳이 있을지는 생각을 더 해봐야 겠지만 일단은 공부 한다는 차원에서 .... 해볼만한 것 같습니다.


만든 Infinite를 사용하는 main코드는 아래와 같은 모양으로 생겼습니다.
(wcout를 쓰기 위해서 그냥 tchar를 사용하지 않았습니다.)

bool isEven(int i) { return (i%2 == 0); }
 
int wmain(int argc, wchar_t* argv[])
{
    fibs()->filter(isEven)->take(10)->out(std::wcout);
    return 0;
}

눈치가 빠르신 분들은 벌써 아셨겠지만 코드는...
피보나치수열(fibs)를 얻어서, 이 중 짝수만 걸러내서(filter) 그 중에서 제일 앞에 10개만(take) 출력(out)하겠다는 코드 입니다. 물론 C++에서 저렇게 exception처리도 없이 ->연산자를 중복해서 사용하는 것은 좋지 않지만 실제로 사용하는 코드가 아니니 이해해 주시기 바랍니다.

아무튼 그래서 피보나치 수열 중에서 짝수 중 앞에 10개는 아래와 같습니다.
위 코드가 아래와 같은 결과를 나오게 만들면 되겠지요?
시간 있으신 분들은 제가 한 방법 말고 다른 방법으로 구현 해보셔도 재미있을 것 같네요 ^^

2
8
34
144
610
2584
10946
46368
196418
832040


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
소스보기 :


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

소스를 직접 까보기 귀찮은신 분들을 위해서..
주요 부분 소스를 붙입니다.. (메모리는.. shared_ptr을 썼다가 지저분해서 뺐습니다.)

class fibo_stream : public make_stream<int>
{
public:
    fibo_stream()
        : make_stream<int>(1, 1)
    {}
    virtual IStream<int>* _tail()
    {
        IStream<int>* super_tail = make_stream<int>::_tail();
        return new fibo_stream(super_tail->head(),
                                head()+super_tail->head());
    }
protected:
    fibo_stream(int head, int tail)
        : make_stream<int>(head, tail)
    {}
};
IStream<int>* fibs() { return new fibo_stream(); }

피보나치 수열 스트림의 포인트는 항상 두개의 값만 계산해 놓는다는 겁니다. 즉, 미리 앞서나가지 않는 것 입니다.


덧)
아래 wafe님의 지적을 받아서 표준이 아닌 문법을 고쳐서 g++에서도 컴파일 될 수 있도록 했습니다.


Posted by U∙Seung