이 블로그 검색

2011년 9월 28일 수요일

const 사용

참조: http://drdobbs.com/cpp/231601151?cid=DDJ_nl_upd_2011-09-27_h

헷갈리는 const사용시,
전통적인 const의 사용법과는 좀 틀리지만 알아보기 쉬운 스타일을 소개한 내용이다.
기존에 사용되는 고전적인 방법과 다음에 소개되는 사용 스타일중 어떤것이 더 이해하기 쉬운지는 각자 판단에 맡긴다...

const 사용 style :
1. const 선언을 위해서는 const가 되어야하는것 오른쪽에 const를 위치한다.

예를 들어 const char에 대한 포인터를 선언하는 경우 다음과 같다.

// pointer to const char 
const char a ='a'; 
const char b ='b'; 

// 고전적인 방법
const char* p0=&a; 
p0=&b; //OK 
*p0 ='c'; //Not OK

// 위의 규칙을 적용, 다음처럼 가능.
char const *p; //좀 이해하기 쉬운가?

p=&b; //OK 
*p ='c'; //Not OK

// 위규칙을 적용한 또다른 경우 (문자열)

// 고전적인 방법
 const char* NAME = "Foo"; // NAME=> const char* "Foo"에 대한 포인터

NAME[0] = 'g'; //Not OK 
NAME = "Bar"; //OK

// 위의 규칙을 적용, 다음처럼 가능.
char const* NAME1 = "Foo"; // NAME1=> const char* "Foo"에 대한 포인터 
NAME1[0] = 'g'; //Not OK 
NAME1 = "Bar"; //OK


2. 이선언을 해석하기 위해서는 오른쪽에서 왼쪽으로 가면서 해석한다.

즉, p는 const char에 대한 포인터이다.

참조
char에 대한 const 포인터를 선언하는 경우 다음과 같다.
// const pointer to char 
char a2 = 'a'; 
char b2 = 'b'; 
char* const p2 = &a2; 
p2=&b2; //Not 
OK *p2='c'; //OK
해석 역시, p는 const 포인터 (char에 대한) 로 해석한다.

const pointer to const char* 경우 :
어떤 개발자가 NAME의 내용을 변경못하게 하기 위해,
const char*를 가르키는 포인터 NAME을 다음처럼 선언했다고 가정한다.

const char* NAME = "Foo"; (혹은 앞서 설명된대로.. char const* NAME = "Foo"; )

그래서, 다음처럼 사용될수 없다. 
NAME[0] = 'g'; 

그런데 다음은 가능하다. 이것은 의도했던 상황은 아니다. 
NAME = "Bar"; //"Bar" 역시 const char* 이기 때문. 
이것을 막기 위해서는 상수 char*를 가르키는 포인터 NAME 역시 const로 지정해야한다.

const char* const NAME = "Foo"; //혹은
char const* const NAME = "Foo";

2011년 9월 21일 수요일

protothread

protothred 는 주로 쓰레드 사용의 장점이 필요하지만, 기존 쓰레드 생성시의 부하,
즉 쓰레드별 스택 생성됨으로 인해 메모리 사용양이 문제가 되는 임베디드 시스템등에서
사용할 목적으로 작성되었다. 쓰레드별 스택이 불필요하므로 매우 경량이며
(쓰레드당 2 바이트 메모리만 필요)소스코드의 복잡도 감소등을 장점으로 내세운다.
C 언어로 작성된 몇개의 헤더파일로만 이루어져 있으며 헤더 파일 내부는
C 매크로와 먼저 설명한 switch 구문의 마법을 활용하고 있다.  
일반적인 쓰레드는 커널에 의해 스케쥴링이 수행되지만, protothread는 프로그램 내부에서
각 쓰레드들을 스케쥴링하는 부분을 필요로 한다.

2011년 9월 20일 화요일

protothread : Duff's device

protothread 란 것을 보던중에 아래와 같은 소스를 발견.
그동안 몰랐던 이상야릇한 C언어 switch 구문형태이다~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int counter = 0;
int n = 0;

int somefun()
{
    switch(n){
        case 0: 
   while(1){
     n = 12; 
     case 12:
     if(!(counter == 1000))
         return 0;       
     printf("Threshold reached\n");
     counter = 0;
 }
    }
    n = 0;  
    return 2;
}

int _tmain(int argc, _TCHAR* argv[])
{
 somefun(); // case 0
 somefun(); // case 12
 return 0;
}
Pastie #2495563 linked directly from Pastie.