posted by bluelimn 2011.07.22 14:41

 set autoindent      " 자동으로 들여쓰기를 한다.
set cindent          " C 프로그래밍을 할때 자동으로 들여쓰기를 한다.
set smartindent     " 좀더 똑똑한 들여쓰기를 위한 옵션이다.
set wrap             " 자동으로 <CR>를 삽입하여 다음 줄로 넘어간다.
set nowrapscan     " 검색할 때 문서의 끝에서 다시 처음으로 돌아가지 않는다.
set nobackup        " 백업 파일을 만들지 않는다.
set visualbell       " 키를 잘못눌렀을 때 삑 소리를 내는 대신 번쩍이게 한다.
set ruler             " 화면 우측 하단에 현재 커서의 위치(줄,칸)를 보여준다.
set tabstop=2       " Tab을 눌렀을 때 8칸 대신 4칸 이동하도록 한다.
set shiftwidth=2    " 자동 들여쓰기를 할때 4칸 들여쓰도록 한다.
set showmatch   " 매치되는 괄호의 반대쪽을 보여줌
set ignorecase   " 찾기에서 대/소문자를 구별하지 않음
set incsearch    " 점진적으로 찾기
set title      " 타이틀바에 현재 편집중인 파일을 표시
set background=dark    "화면배경을 좀더 어둡게 한다.
"set background=light  "화면배경을 밝게 한다.
set number         "행번호를 보여준다.  :se nu 와 같은 효과
set nowrapscan       "단어 검색시 문서 처음으로 돌아가지 않는다.
set hlsearch     "검색어 강조기능을 사용한다.

posted by bluelimn 2011.04.28 20:22

Artistic Style


Astyle.exe 파일을 자동 접근 가능한 폴에 복사.
SourceInsight Base project 폴더, Windows\System32 혹은 기타 PATH로 설정한 폴더
Source Insight 에서 Project -> Open Project -> Base 프로젝트를 선택
'utils.em' 파일에 아래 내용 추가 (해당 옵션은 입맛에 따라 변경 가능)


// Run Artistic Style
macro ArtisticStyle()
{
hbuf = GetCurrentBuf()
sFile = GetBufName( hbuf )
len = strlen( sFile ) - 1
exp = ""

while ( sFile[len] != "." )
{
exp = cat( sFile[len], exp )
len = len - 1
}

if ( exp != "java" && exp != "c" && exp != "cpp" && exp != “h” )
{
return -1
}

cmd = "astyle.exe"
if ( exp == "java" )
{
cmd = cmd # " --style=java"
cmd = cmd # " --indent=spaces=4"
}
else
{
cmd = cmd # " --style=ansi"
cmd = cmd # " --indent=tab=8"
//cmd = cmd # " --indent-classes"
cmd = cmd # " --indent-namespaces"
cmd = cmd # " --indent-preprocessor"
}

cmd = cmd # " --indent-switches"
cmd = cmd # " --pad-oper"
//cmd = cmd # " --pad-paren-in"
cmd = cmd # " --suffix=none"

cmd = cmd # " \"@sFile@\""

exitcode = RunCmdLine( cmd, Nil, false )
}

Source Insight의 Option -> Key Assignments

'Macro: ArtisticStyle'를 선택하고 Assign New Key로 사용할 키 설정

===참고 =======
인터넷을 돌다보니 아래의 옵션에 문제가 있다고 한다.
주석으로 삭제해버리자
cmd = cmd # " --indent-classes"
cmd = cmd # " --pad-paren-in"
posted by bluelimn 2008.07.08 21:47
오랜 시간이 걸리는 새로운 일과 마주치면?
1. 맨손으로 힘들여 노가다를 한다.
2. 스크립트 언어를 이용해서 그 일을 자동으로 수행하는 툴을 작성한다.
3. 이미 작성되어 있는 툴을 찾기위해 여러 시간을 보낸다.
=== 잠깐동안 툴을 찾아보고 없으면 더이상 미련을 가지지 말고 간단히 스크립트 언어로 자동 수행 환경을 만들도록 하자.

새로운 툴을 발견하면?
원하는 만큼 알게될 때까지 만지작 거리지 말고 관련 문서를 정확하게 읽어보자.
읽으라고 친절히 설명서까지 만들어놨는데 쳐다보지도 않고 혼자 만지작 거리면서 모르겠다고 투정부리는 일은 하지말자.

툴에 구애받지 않는 실력을 가지는 것도 중요하지만 세상에는 툴이 엄청 많다. 똑똑한 툴을 잘 다루는 프로그래머는 더 똑똑한 프로그래머가 된다. C코드를 툴을 사용하지 않고 어셈블리어로 변환하는 사람이 있다면 정신과 상담이 필요하다.

* 어떠한 툴 들이 있는지 알아보고 어디서 구할 수 있는지 확인해보자. 지금 사용하지 않더라도 충분한 보험이 될 수 있다.

툴의 사용법
* 툴로 무엇을 할 수 있는지 알아둬라.
* 어떻게 조종하는지 배워라.
* 어떤 일에 좋은지 알아둬라. (어떤 일을 할 때 사용하면 유용한지)
* 어떤 문제점을 가지고 있는 확인하라.
* 더 많은 툴을 찾을 분명한 루트를 확보하라.
    메뉴얼, 릴리즈 노트, 온라인 지원, 툴 내부의 도움말 파일, man 페이지 등
* 새로운 버젼이 언제 나오는지 알아내라. (최신 버젼이 무조건 좋은 것은 아니다)
===== 하지만 지금 당장 할 일은 툴들의 정보를 공유하는 커뮤니티를 찾는 것일지도

소스코드 편집용 에디터를 선택할 때의 팁
* 포괄적인 문법 컬러링(여러 언어를 지원)
* 간단한 문법 체킹(강력하면 더 좋겠지만)
* 우수한 검색 / 변환 (찾기, 바꾸기 등이 앞뒤로 가능하도록)
* 키보드 매크로 기능(꽤 유용하다)
* 원하는 플랫폼에서 작동하는지(유닉스, 윈도우계열 등 작업환경에서 돌아가야 한다)

TIP 유닉스 계열에서 사용하는 소스 조작 툴
diff : 두 파일을 비교, 서로 다른 부분을 하이라이트 표시
sed : stream editor; 한줄씩 읽어서 변환하는 것을 원칙으로 하는 툴, 항목의 재정렬이나 global 검색이나 치환, 혹은 행 안에 패턴을 삽입할 때도 사용
awk : sed와 비슷한데 이건 text file을 대상으로 작업한다.
grep : 파일 내의 문자패턴을 검색
find/locate : 파일을 찾는다. 이름, 날짜, 그 밖의 기준을 가지고 검색
wc : 단어와 문자를 세는 일을 한다
sort : 원하는 정렬 기준에 맞추어 재정렬한다
paste, join, cut 등 유용한 것들 꽤 많다. 유닉스의 기본 철칙은 작은 툴들이 모여서 큰 작업을 한다는 것이다.

좋은 프로그래머
* 지루한 일을 반복하기 보다는 적절한 툴의 사용 방법을 배우려고 한다.
* 여러가지 toolchain의 모델을 알아두고, 각각을 힘들지 않게 사용할 수 있도록 한다.
* 편의를 위해 툴을 사용하지만 툴의 노예가 되진 않는다.
* 사용하는 모든 것을 교체 가능한 유용한 도구(툴)로 본다

나쁜 프로그래머
* 몇가지 툴의 사용법을 알고있지만, 모든 문제를 툴에 맞추어 생각하려고 한다.
* 새로운 툴을 배우기 위해 시간내는 것을 꺼려한다.(익숙한 것만 하려고 든다.)
* 어떤 개발환경을 사용하기 시작하면, 그것을 종교처럼 받들고 절대 다른 것의 사용을 시도하려고 들지 않는다.
* 가치있는 새로운 툴을 발견해도 자신의 툴박스에 추가하지 않는다.
posted by bluelimn 2008.06.26 22:00

에러나 예외를 일으킬 때 주의
* 청소는 했는가? - 리소스 누출(동적할당 등), 자료들의 모순상태 등을 확인. 어쩔 수 없이 제대로 청소되지 않는 상황이라면 반드시 기록을 남겨둬야 한다.
* 에러정보에 부적절한 내용을 담지 마라
* 올바른 exception을 사용 - 에러나 예외가 아닌 특이한 값을 return하지 마라. 즉 올바른 자료랑 예외상황을 섞어서 사용하지 말란 말이다.
* 정상적인 실행과정 중 절대 일어나지 말아야 할 진짜 프로그래밍 에러를 잡으려고 한다면 assertion의 사용을 고려해보라. 하지만 assertion은 완성본에 남아있으면 안된다. exception을 활용하는 것이 더 나을수도 있다.
* 사람들이 무시하지 않도록 만들어라.

일반적인 에러 체크 목록
* 함수의 모든 파라미터를 체크
* 관심 있는 실행 지점에서 불변조건(invariant)이 만족하는지 검사
* 외부에서 들어온 값은 사용하기 전에 모두 유효성 검사를 해라. 특히 파일로부터 얻어오는 자료와 사용자가 입력하는 자료는 유효성검사가 꽤 중요하다.
* 시스템 호출과 함수 호출에 있어서는 가능한 모든 호출에 대해서 리턴 상태를 체크

에러 관리하기
* 에러의 원인이 될만한 일은 피해라 - 리소스 할당 에러는 충분한 리소스를 미리 예약(pool)하면 피할 수 있다.
* 프로그램이나 루틴이 비정상적인 상황에서 어떤 동작을 할 것이 예상되는지 정하라(GIGO: Garbage In Garbage Out)
* 자신의 프로그래밍 습관을 체크 : 에러 처리 코드를 나중으로 미루지 마라.

실패 가능성이 있는 코드를 작성할 때는 에러 감지 코드와 에러 치리 코드도 함께 작성하라.

posted by bluelimn 2008.06.24 23:43

에러 처리하기

에러를 처리하기 전에 알아야 하는 것들:
* 에러가 어디서 나왔는가
* 당신을 무엇을 하려 했는가(무엇을 하다가 에러가 발생했는가)
* 일이 왜 잘못 되었나
* 에러가 언제 일어났나
* 에러의 심각성
* 에러를 고치는 방법

에러를 발견했을 때
1. logging (로그기록)
2. report(보고) (임베디드의 경우 보고대신 스스로 처리해야 할 때도 있다)
3. recovery(복구)
3. ignore(무시)
4. propagate(전파) : # 똑같은 에러정보를 전파, # 재해석 후 새로운 메시지를 전파

코드구현 테크닉

좋지않은 if중첩의 예(2)..


중첩을 피한 if문(1)..


중첩을 피한 if문(2)..

posted by bluelimn 2008.06.14 14:00

오류의 발생은 원인에 따라 세가지로 요약할 수 있다.
사용자 에러 : 정확히 다 잡기가 어려워 배포 후에도 발생할 수 있다.
프로그래머 에러 : 나와서는 안되는 에러
예외상황 : 프로그래머가 정상적으로 작성했고 사용자도 정상적으로 사용했다. 하지만 네트워크 연결이 이상할 수도 있고, 하드디스크나 메모리에 용량이 부족할 수도 있고 갑자기 전원이 나갈 수도 있다.

에러를 처리하는데 중요한 몇가지를 먼저 알아보자.
1. 발생은 하위 콤포넌트, 처리는 호출자(caller) : 즉 누군가 일을 잘못하면 시킨 사람이 책임진다는 뜻이다.
2. 잘못이 있을 때는 에러를 발생시켜야 한다.(그냥 뻗도록 해서는 안된다.)
3. 보고도리 수 있는 모든 에러를 감지한다.
4. 감지된 에러를 적절하게 처리한다.
5. 처리할 수 없는 에러는 다른 곳으로 전파한다.
에러 처리는 exception 처리와 거의 같게 취급하면 될 것 같다.

에러 리포트 메커니즘 ( 오류를 알리기 위한 방법 )
1. return값 : return되는 값이 boolean으로 함수의 성공, 실패를 알려주는 용도라면 적당하게 작동한다. 단, 에러의 종류는 알 수 없다. return 값이 필요한 함수에서 오류도 함께 return의 값으로 알려주려고 시도하는 경우도 있다. 가능은 하지만 권장하지 않는다. 그래도 꼭 해야 하겠다면 몇가지 방법이 있다.
  * return값을 좀더 복잡하게 만들어 원하는 결과와 오류정보를 둘다 가지고 있는 구조체나 객체를 return하는 방법 : 네트워크에선 가끔 이용되지만 일반적인 프로그래밍에선 사용되는 경우가 거의 없다.
  * 참조(reference)를 이용하여 파라미터를 통해 보내는 방법 : 이또한 보기에도 좋지 않고 직관적이지도 않다.
  * 오류의 범위를 지정 : return값이 0이상의 값만 의미가 있을 때(count등) 음수를 오류로 처리하거나 참조나 포인터일 경우 NULL을 에러로 처리하는 것이 가능하다.
어떤 방법을 사용하건 지저분해진다. 에러를 발생시키는 것도 어렵지만 처리도 지저분해진다.

2. 에러 상태 변수 : 특수한 값들을 에러로 define해놓는 방법이다. C언어에서 가끔 사용되는데 결국 이런 것도 전역으로 사용되며 프로그램이 실행되는 동안 내내 메모리에 올라가 있는 값이기 때문에 많으면 좋지 않다. 게다가 파일이 여러개면 제대로 확인하기도 어렵다.

3. exception(예외처리)
에러처리를 위해 만들어진 구문으로 throw-catch, throws구문을 이용하여 에러를 handler에게 보내는 방법이다. 에러처리 전문 문법이기 때문에 가장 깔끔하고 직관적이지만 모든 언어에서 지원해주는 것은 아니다. C언어에는 없고, C++, JAVA, .NET등에는 있다.
 * 종결모델(termination model) : 헨들러가 처리한 부분부터 다시 실행(C++, .NET, JAVA)
 * 재개모델(resumption model) : 오류가 발생한 부분으로 돌아가서 다시 실행
예외처리는 안전성에 몇가지 단계가 있다.
==== 기초보장(basic guarantee)
   exception이 발생해도 메모리 누수가 없도록 해야한다. 동적 할당을 받았다면 반드시 확인해보자.
==== 강력한 보장(strong guarantee)
   exception이 발생해도 프로그램의 상태는 아무것도 바뀌면 안된다. 전역변수도, 지역변수도 객체도 그 값을 그대로 유지하고 있어야 한다.
==== no throw(nothrow guarantee)
   operation이 exception을 던질 수 없도록 만든다. 3가지 보장 중 가장 강력한 방침인데 예외상황을 발생시키지 않는다. 가장 중요한 것은 소멸자에서 exception을 던지지 않는다는 보장이 있어야 한다는 것인데 객체지향언어에서 소멸자는 객체의 생명이 다할 때 자동으로 호출되며 exception이 발생했을 때도 스택이 풀리면서 호출된다. (C#에서는 소멸자에서 exception을 던지는 것이 의미가 있으며 그것을 인정한다)

4. signal
극단적인 에러 리포트 메커니즘으로 전기 신호로 에러를 발생시키고 시그널 핸들러를 설치해야 한다.

=======================================================================
exception을 무시하더라도 감지하는 코드는 만들어둬야 한다.
그래야 나중에 코드를 봤을 때 exception의 가능성이 있다는 것을 알 수 있다.
=======================================================================

posted by bluelimn 2008.06.11 21:26

일관성
코멘트도 일관성을 유지하는 것이 좋다. 보기 좋은 떡을 만들라. 누가 뭐래도 코멘트는 사람에게 보여주기 위해 작성하는 것이 아닌가!

뚜렷한 블록 코멘트
에디터에서 색이 다르고 굵게 표시되는 경우가 많지만 흑백으로 프린트해서 봐야 할 수도 있다.(특수한 경우를 생각하지 말고 일반적인 것을 생각하라!)
코멘트의 시작과 끝은 들여쓰기 등으로 다른부분과 구분을 지어야 한다.

/*
  * 좋은 예시의
  * 블록 코멘트
  * 알아보기가 쉽다.
*/

/* 나쁜 예시의
          블록 코멘트
알아보기 어렵다.
*/


1행 코멘트
코드 중간에 들어가지 않도록 해야 한다. 만약 코드 중간에 한줄을 잡는다면
코드의 들여쓰기와 맞춰 알아보기 쉽도록 해야한다.
행 끝에 따로 띄어서 코멘트를 작성하는 것도 괜찮다.
오른쪽에 코드로부터 분리하여 코멘트들을 작성하는 것인데 알아보기는 쉬우나 코드를 수정할 때 간격을 다시 맞춰야 하고 코드가 긴 행을 만나면 화면 밖으로 나가버릴 가능성도 있다.

일반적인 약속(관례)
코멘트는 코드의 위쪽에 쓰인다. 즉, 코멘트가 먼저 나오고 그에 해당하는 코드가 나온다.
코멘트가 단락의 시작으로 여겨지도록 한다.

유지보수가 저렴한 스타일을 선택
/***********************************
*******     모양은 이쁘지만    ********
*******  간격맞추기가 어렵다  ********
***********************************/

게다가 스페이스를 사용하느냐 탭을 사용하느냐에 따라 모양이 다르고 탭을 사용하는 경우 탭의 너비설정이 다르면 또 모양이 달라진다. 쓸데없는 곳에 열정을 낭비하지 말자.

방파제 코멘트
가끔 코멘트가 코드 사이에 방파제 역할을 하는 경우가 있다.
프로그래머는 중요한 코멘트를 특별하게 표시할 필요가 있는데 한 소스파일 안에 여러개의 클래스가 구현되어 있는 경우, 중요 섹션을 구분하기 위해 방파제 코멘트를 사용한다.
/***********************************
* 방파제 코멘트
* 가끔 필요할 때가 있다
***********************************/

좀 전에 함부로 사용하지 말라고 한 것과 비슷한 모양이지만 눈에 띄는 것이 중요하지 ASCII예술을 통해 이쁘게 하지 마라. (ASCII예술이란 특정한 상황에서 띄어쓰기 등으로 화면에 보이는 것을 미술적으로 표현하는 것을 말하는 듯하다.)

플래그
다른 사람의 코멘트를 읽을 때 약속된 플래그를 알아두는 것이 좋다.
// XXX      : 문제를 일으키는 코드나 재작업이 필요하다는 표시
// FIXME   : 고장 난 부분
// TODO    : 누락된 기능(나중에 돌아왔을 때 추가해야 할 기능)
TODO를 사용하기 보다는 exception을 던지는 것이 훨씬 매끄럽다. 하지만 다른 사람이 해놓은 것을 알아볼 필요는 있겠지.
하지만 플레그를 두려워 하지 마라. 코드를 마무리하기 전에 플레그를 검색해보면 된다.

파일헤더 코멘트
앞에서도 이야기 했던 내용이다. 모든 소스 파일에는 헤더 코멘트로 시작해야 한다.

불필요한 코멘트
코드를 수정할 때 코멘트를 달지마라.
어떠한 내용을 무엇때문에 어떻게 고쳤다..라고 코멘트를 다는 것은 불필요하며 지저분하다. 필요한 경우 결함 추적 시스템(fault-tracking system)을 이용해 결함을 찾고, 파일의 예전 리비전을 끄집어내어 조사할 수 있다. 이러한 불필요한 코멘트는 오히려 코드를 어지럽힌다.

코멘트 유지보수
바로 위에서 코드를 수정할 때 코멘트를 달지 말라고 했다. 그렇다면 코드를 수정할 때는 그냥 넘어가면 되는 것인가? 절대 아니다.
코드를 수정할 경우 그와 관련된 코멘트를 모두 확인하고 보수해야 한다.

코멘트를 의심하라
코드를 코멘트로 막아두는 경우가 있다. 일시적인 경우지만 때로는 오래갈 때도 있다. 이런 경우 적당한 설명을 함께 두거나 아예 코드 자체를 지워야 한다.
코멘트가 있더라도 코드의 수정과 함께 유지보수가 되지 않은 코멘트일 수 있고 작성한 사람이 잘못 작성했을 가능성도 있다. 항상 코드를 신뢰하고 코멘트는 의심해야 한다.


-----------정리-------------
* 소량의 코멘트를 작성하라
* 왜(why)에 대해 작성하라
* 코멘트보다 코드의 작성에 집중하라
* 코드와 함께 유지보수하라
& 코드의 내용을 중복하지 마라
& 자신만 알아보는 코멘트를 작성하지 마라

posted by bluelimn 2008.06.05 15:03
코멘트(주석, comment)란?
컴퓨터가 보는 것이 아니다. 대상은 사람이다.(작성자 자신도 포함)
C언어는 /* 주석 */ 으로 여러행에 걸쳐 주석을 넣을 수 있다.
C++, C99, C#, Java에서는 여기에 // 뒤에 한줄로 된 코멘트가 추가된다. 내가 알기론 그렇데 교수님이 수업할 때 학생 중 하나의 말에 따르면 C언어 표준의 최신 정의를 보면 C언어에 //로 된 한줄짜리 코멘트도 인정했다고 한다.
언어마다 comment를 정의하는 문법은 조금씩 다르지만 다들 가지고 있다.
@ comment, #comment, $comment, <! comment --> 등 다양하지만 웬만한 언어는 모두 코멘트를 작성할 수 있도록 지원해준다.
코멘트는 코드와 가장 가까이(내부)에 있는 문서로 코드를 읽어갈 때 방향을 잃지 않도록 도와준다.

코멘트는 적게 사용하는 것이 좋다?
코멘트의 양이 많을수록 코드를 읽기 어려울 수도 있다. 잘못된 코멘트는 심각한 오해를 불러일으키며, 잘못된 코멘트가 아니더라도 양이 많고 위치가 뒤죽박죽이면 읽기 힘들어진다.
코멘트는 오해의 소지가 있는 곳, 읽기 힘든 곳, 알아보기 힘든 곳에서는 반드시 있어야 한다. 하지만 잘 만들어진 코드는 논란의 여지가 없고 알아보기 쉬운 코드이므로 코멘트가 그만큼 줄어든다. 많은 코멘트가 필요없는 코드를 작성하기 위해 시간을 투자하자!

어떻게(How)가 아니라 왜(Why)를 기술하라
코멘트의 기본이다. 그리고 코멘트에서 가장 중요한 부분이다. 어떻게 돌아가는지는 코드를 보면 충분히 알수 있다. 왜 이런 코드를 작성했는지에 대한 것을 적어라. 명심히라. 코멘트는 How가 아니라 Why를 기술해야 한다.

코드를 묘사하지 마라
How를 기술하지 말라는 것과 같은 내용이다. 코드에 있는 사실을 다시 코멘트로 만들지 마라

코드를 대신하지 마라
코멘트가 길어지고 있다면 코멘트를 잘 쓰기보다는 코드를 알아보기 쉽게 고치도록 하자.
코멘트의 내용이 지나치게 중요하다면 코드는 수정되어야 한다.

유용성을 유지하라
- 의외의 것을 기록하라
    일반적이지 않은 코드, 특이한 녀석은 반드시 코멘트를 달고 뻔한 코드는 코멘트를 달지 마라. 특이한 녀석은 적을수록 좋다.
- 진실을 말하라
    잘못된 코드는 오히려 심한 오해를 불러들인다. 코드를 수정하면서 코멘트는 가만히 두는 경우 이런 문제가 발생할 수 있다. 코드를 수정할 때 코멘트도 잘 봐야 한다.
- 가치 있게 만들어라
    농담, 비속어, 이모티콘, 장난, 암호 금지... 장난치지 마라. 당신은 지금 얼마나 오래갈지 모르는 소스를 만들고 있다.
- 명료하게 만들어라
    구체적이고 정확하게 써라. 누군가 당신의 코멘트를 읽고 무슨 뜻인지 몰라 어리둥절해지면 당신은 코드를 악화시킨 것이다.

블록의 끝을 무조건 //end of if( a < 1 ) 이런 식으로 하는 것 나쁜 습관이란다. 난 이렇게 하려고 습관들이고 있었는데..
왜냐하면 블록은 한 페이지 안에 들어와야 하고 알아보기 쉽게 되어있어야 하기 때문이란다.

코멘트를 잘 달기보다 이름을 잘 짓는것에 더 투자하라.
posted by bluelimn 2008.05.30 22:22

파일 헤더를 제공하라
사소하지만 꽤 중요하다. 난 지금까지 제대로 지키지 않았다. 앞으로는 잘 하도록 노력해야겠다. 대부분의 회사에서는 법률적인 이유로 모든 소스 파일에 가시적인 저작권 공지를 포함시키도록 의무화하고 있단다.
/*************************************
* 파일 : FileName.java
* 목적 :
* 알림 : 저작권표시
*************************************/

에러를 적절하게핸들링하라
에러는 발생한 곳과 가까운 곳에서 처리하는 것이 좋다. 에러가 발생하면 어디서 왔는지, 에러의 이유가 무엇인지, 에러가 발생한 것은 무엇을 의미하는 것인지 알기 쉽도록 해라.(어떻게? 잘~)

의미 있는 코멘트를 작성하라
학교에서 처음 프로그래밍을 배우면서 코드를 작성하고 발표수업이 있을 때 모든 문장에 코멘트를 달도록 강요받은 기억이 있다. 코멘트가 너무 많은 코드는 오히려 보기 불편하다. 가능하면 코멘트가 필요없도록 작성하되 그러고도 남아있는 부분에 대해서는 적절한 분량의 코멘트를 추가해야 한다.
* 파일헤더, 함수의 설명, 변수에 대한 설명은 가능하면 생략하지 마라.


문서화의 여러가지 방법


문학적 프로그래밍(프로그램을 작성하지 말고, 문서를 작성하라. 소설처럼 써라.)
장점

* 문학적 프로그래밍은 문서작성에 강점을 둔다.
* 문서가 가까이 있으므로 업데이트할 때 문서도 함께 업데이트 하기 쉽다.
* 전체 코드베이스에 대해 단 하나의 문서만 존재한다는 사실이 보장된다.(코드 자체가 문서기 때문)
* 일반적으로 코멘트에 쓰이지 않는 항목도 문서화하도록 유도한다.(사용된 알고리즘에 대한 설명, 코드가 올바르다는 증명, 그렇게 설계하게 된 결정의 정당성.)
* 유지보수에서 빛이 난다.
단점
* 코드가 아니라 문서 전체를 작성해야 하므로 대부분의 프로그래머들이 힘들고 귀찮아 한다.
* 또 하나의 컴파일 단계가 필요하고, 그것이 작업 속도를 느리게 만든다.(아직 바로 컴파일해줄만한 툴은 없단다. 당연하지!)
* 정말 문서화가 필요하지 않은 부분까지도 문서화하게 될지도 모른다. 또는 일부를 문서화하지 않게 될지도 모른다. 귀찮으면 아예 하지 않는 것이 좋다. 이도저도 아니면 안된다.
* 프로그램 잘 짠다고 글도 잘쓰는 것은 아니다. 훌륭한 프로그래머라고 해서 반드시 유능한 문학적 프로그래머가 되는 것은 아니다.


문서화툴
문서화를 도와주는 툴이 많이 있다는 말이다. 책에서는 Javadoc를 예로 들었는데 이는 다음과 같은 일을 도와준다.
 * 저작권 정보를 명시한다
 * 생성일자를 기록한다
 * 정보를 상호 참조시킨다
 * 오래된 코드에 deprecated라고 표시한다.(오래됐다고 바꾸라고 권장한다는 뜻)
 * 빠른 참조용의 짤막한 개요(synopsis)를 제공한다
 * 함수 파라미터 각각에 대한 설명을 제시한다
javadoc, C#의 NDoc와 Doxygen(www.doxygen.org)등이 있단다.
장점
* 코드의 문서화와 업데이트를 촉진
* 컴파일할 수 있는 코드를 위해 별도의 단계가 필요하지 않다(문학적 프로그래밍과의 차이)
* 비교적 자연스럽게 보인다.
* 문서화 툴은 풍부한 검색, 상호 참조, 코드 아웃라인 기능을 지원
단점
* API의 문서화에만 정말로 유용하고, 내부 코드의 문서화에는 일반 코멘트를 사용해야 함
* 소스 파일을 훑어보고 개략적인 내용을 파악하기 어렵다.(이런 건 문학적 프로그래밍이 한 수 위)
주의
* public 항목에 대해서는 하나 또는 두 개의 문장으로 구성된 설명을 작성하라. 쓸데없이 주절주절 늘어놓지 말란 말이다.
* 변수나 파라미터가 어디에 사용되는지 분명하지 않으면 문서화하라. 단 이름만 보아도 확실하게 알수 있으면 문서화하지 마라.
*함수 파라미터 중 어떤 것은 입력에 사용되고 어떤 것은 출력에 사용된다면, 그런 사실을 파라미터 설명에 명확히 기술하라
* 함수의 전제조건, 후행조건, 발생할 수 있는 exception, side effect를 모두 문서화 하라.

생각해보니 2학년 때 이현아교수님이 문서화 툴에 대해 언급했었고 임은기 교수님도 권장한 적이 있다. 다만 귀찮아서 사용하지 않았다. 잠시 알아본 적도 있었지만 귀찮아서 사용하지 않았다. 문서화 툴은 형식이 일정한 것이 아니라 툴 마다 다르기 때문에 필요하다면 실무에서 사용되는 공통된 것을 이용하면 될 것 같다. 사용법이 그리 어렵지 않으니 그때그때 필요한 것을 배우면서 사용할 수 있다. 문서화 툴에 의존하기보다는 필요한 정보는 코멘트로 달아두는 습관을 기르는 것이 더 도움이 될 것 같다.

+ 파일에는 헤더를 유지 (파일명, 목적, 저작권 [, 특이사항])
+ 함수에도 헤더를 유지 (parameter, return value, 목적)
+ 변수는 이름만으로 명확한 것이 아니면 반드시 설명(객체형식이라면 이름이 확실해도 설명을 붙여두는 것이 좋다.)

posted by bluelimn 2008.05.14 23:03

의미있는 이름을 사용하라.
변수, 타입, 파일, 함수등 모든 것들의 이름은 의미가 있는 것이어야 한다. x,y,z,a,b,c같은 이름들은 나중에 자신이 봐도 정확히 이해하기 어려울지도 모른다.

함수 작성 시 유의
- 하나의 함수는 하나의 동작! (동사로 이름짓는 것이 원칙)
- side effect를 최소화하라(side effect란 함수가 실행되는 도중에 외부에 있는 값이나 상태를 바꾸는 것을 말한다.)
-  짧게 만들라. 한 화면에 모두 들어갈 수 있도록 하되 코드를 짧게 만들기위해 무리하게 줄이지는 마라.

제약을 많이 가하라.
- const등을 이용해서 값이 바뀌면 안되는 것들은 모두 상수화해라.
- 양수만 가진다면 unsigned type을 사용하라. 귀찮다고 그냥 넘기는 경우가 많다.
- 몇가지 선택사항이 있다면 열거형식(enum)을 활용하라.
(가끔 생각하는데 boxing과 unboxing에 대한 것, 혹은 casting에 관한 것이 이러한 제약들과 겹칠 경우 어떻게 해야 하는가..하는 문제다. unsigned type의 변수를 선언했는데 signed형식을 parameter로 사용하는 method를 이용해야 할 경우 강제형변환(type casting)이 필요하다. 이러한 형 변환이 많이 사용될 때는 그냥 처음부터 signed로 하는게 좋지 않을까?)

마법의 수를 피하라.
코드내에 숫자가 들어가는 경우를 magic number라고 한다. if(counter == 76)과 같은 코드를 만나게 되면 76이 무엇을 뜻하는지 모르게 된다. #define과 같은 코드를 사용해서 문자상수를 사용할 수도 있고 상수를 선언해서 사용할수도 있다.
더욱 심한 경우를 초보자들이 많이 사용하는데 문자를 구분할 때 숫자를 적어버리는 경우가 있다. 이러한 경우는 C언어에 한해서 많이 나타나는 상황인데 특정한 문자인지 확인하기 위해 그 문자의 ASCII코드값을 적어버리는 경우가 있다. source를 유니코드를 사용하는 언어에 그대로 사용할 경우가 생길지도 모른다. 코드값이 다른 상황이 생길지도 모른다. 문자와 상수가 비교되지 않는 컴파일러를 만날지도 모른다.
코드에 숫자를 직접 넣어버리는 것은 피하도록 하자.

연관된 정보는 묶어라.
프로젝트의 크기가 커질수록, 코드의 길이가 길어질수록, 함수와 클레스가 많아질수록 분류의 중요성은 더욱 강조된다. 큰 물에서 놀고싶으면 애초에 큰 물에서 하는 습관을 들여놔야 한다.
- 한 콤포넌트를 위한 API는 한 파일안에 표현해야 한다.
- namespace나 package등을 이용하여 그룹화하라. 관계가 있는 상수들은 enum으로 정의하라.

posted by bluelimn 2008.05.13 10:29
외부 문서의 지원이 필요한 코드는 작성하지 마라. 그런 코드는 취약하다. 코드 자체만으로 명료하게 읽히도록 만들어야 한다.
 - 외부 문서가 필요한 코드의 경우 수정 될 때마다 외부 문서를 같이 수정해야 한다. 처음 작성되었을 때 어떻게 되었는지 알 필요가 있는 경우 이러한 문서 작업은 더욱 복잡해 질 것이다. 큰 프로젝트를 작업하는데 이렇게 진행하면 힘들어서 제대로 진행하질 못한다.
 - 그렇다고 지나치게 상세한 코멘트(주석)로 코드 자체의 내용을 가리는 것도 옳지 않다. 코드만 보고도 쉽게 알 수 있는 곳이라면 코멘트를 자제하자. 어차피 코드만 보고 이해하기 쉽도록 만드는 것이 목표이니 코멘트는 필요없는 것인가? 코멘트가 필요한 곳과 작성요령은 나중에 다시 다룬다.

코드가 명료해지면 실수할 가능성이 적어지기 때문에, 코드의 품질이 높아지고, 유지보수 비용이 줄어든다. (가독성을 높이는 것이 최대 목표라고 생각해라.)

가끔 자신이 만든 소스를 다른 사람들이 쉽게 알아보지 못하는 것에 대해 쾌감을 느끼는 변태들이 있다. 단점은 그런 변태들과 같이 일하고 싶어하는 사람이 적다는 것이다.

읽기어려운코드..


같은 일을 하는 함수다. 어떻게 보이는지 감상해보자.

스스로 문서화된 코드..


중요한 것은 짧은 코드를 작성하는 것이 아니라 다른 프로그래머가 봤을 때 쉽게 읽을 수 있고 명확한 코드를 작성하는 것이다.

if문의 함정에 조심하라!
 - 이건 책에서 강조하는 것이 아니라 내가 강조하는 내용이다. 책에서는 if-then-else 구조를 작성할 때 "정상"인 경우가 "에러"인 경우보다 항상 앞에 나오거나 그 반대가 되도록 하라고 권한다.

내가 권하는 방법은 if문은 가능한 처음부터 사용하지 말라는 것이다. 초보 프로그래머가 쉽게 작성하는 코드는 많은 문제를 if, else문으로 처리하려고 들고 if문 내에 전체 코드를 다 넣으려고 한다. 특히나 if문으로 오류처리를 하면서 전체 코드를 다 집어넣는 경우 처리할 오류가 많아질수록 중첩수준이 깊어진다.

그래서 일단 이론적으로 올바른 입력이 있을때(아무런 오류처리도 필요없을 때)의 코드를 먼저 작성하고 오류처리는 if문으로 나중에 추가하라고 권한다. 불필요한 경우 else문도 절대 사용하지 말것을 권한다. 이것이 올바른 것인지는 모르겠지만 중첩의 깊이가 적을수록 코드를 읽을 때 생각할 것이 줄어든다는 믿음에는 변함이 없다.
posted by bluelimn 2008.04.11 19:17
변수 :
- 명사로 이름 짓는다. ( 변수는 data 자체를 가리키는 경우가 많다.)

- 명사로 사용할 수 없을 땐 명사화된 동사를 사용(ex: count)

- 변수이름의 첫글자는 영문 소문자로 시작

※ 헝가리언 노테이션 : type에 관한 정보를 이름에 포함시키는 방식으로 멤버변수의 경우 m_으로 시작하고, 포인터의 경우 이름 뒤에 _ptr... 뭐 이런 식의 작명법을 말한다. 이 책에서는 그러한 방법을 따르지 말라고 경고하고 있다. Win32와 MFC의 라이브러리에서 헝가리언 노테이션을 따르는 것이 대중적인 사용의 주된 이유지만 type에 관한 정보는 선언할 때 보는 것으로 충분하며 그러한 것들을 표시해줘야 할 정도라면 함수의 크기가 너무 커서 불편하다는 것이므로 나누라고 권한다.
단, type정보가 아니라 기능에 대한 정보라면 이름에 포함하는 것이 맞다. (index기능을 하는 변수를 idx_로 시작하기도 한다.)

※ 머리글자 조합 : 각 단어의 머리글자를 따서 이름짓는 방식이다. (예를 들어 SomeTypeWithMeaningfulNaming 라는 이름이 있다면 stwmn으로 줄이는 것이다. 일반적으로는 사전에 나오는 내용으로 구성하는 것이 원칙이다. 하지만 변수가 좁은 범위에서 사용된다면 너무 긴 이름 대신 짧은 이름으로 대치하고 주석을 달아두는 것도 좋다.


함수:
- 동사로 이름 짓는다.

- be, do, perform등과 같은 의미없는 동사의 사용은 피하라.

- 주의 : 사용자의 입장에서 생각하라
. 초보자들이 흔히 하는 실수로 함수의 입장에서 이름을 짓는 것이다. 항상 함수를 사용하는 사용자 입장에서 이름을 지어야 한다.  어떻게 해야할지 모르겠다면 왜 이 함수를 만드는지 생각해보자. 적절한 예시가 떠오르지 않는다. 이건 자꾸 연습하다 보면 저절로 될 것이다.

- 주의 : 함수의 내부적인 구현 방법은 생각하지 말고 그 함수의 역할을 생각하라. 함수는 하나의 기능만 가지고 있고 그 기능이 무엇인지에 대해서 이름을 짓는 것이다. 기능을 구현하기 위해 어떤 일을 하건 상관하지 마라. 사과가 몇개인지 알기 위해 사용하는 함수라고 하자. 그럴때 보통 int countApples(); 이런 식의 이름을 지을 것이다. 그러면 사과가 몇개인지만 알면 됐지 이 함수가 재귀호출을 하건 file을 건들건 쓰레드를 만들건 신경쓰지 말라는 말이다.

타입(클레스):
- 클레스 이름은 객체가 아니라 클레스를 묘사해야 한다.(사소하지만 중요한 차이: '사람'이란 클레스 이름대신 '홍길동'이란 클레스 이름을 사용한다면?)

- 상태 값을 가지는 객체를 묘사한다면 명사.

- 함수객체(functor : 함수들 만으로 구성된 객체로 static으로 구현되는 경우가 많다.)거나 가상 call back interface를 구현하는 클레스는 동사 or 잘 알려진 디자인 패턴의 이름

- 클레스가 위의 두가지 성격을 모두 가진다면 이름 정하기가 어렵고, 잘못된 설계일 가능성이 크다.

- DataObject와 같이 당연한 내용을 포함하는 이름은 좋지 않다.(클레스는 data를 포함하는 경우가 많고, 객체화 한다면 당연히 object가 되는 것이 아닌가! 그러니 중복해서 언급할 필요가 없다.) : 좋지 않은 단어 -> class, data, object, type
 

namespace, package:

- 전체적인 내용을 봐라. 이건 꽤 큰 범위라 어휘력에 맡긴다.

- 불필요한 부가적 설명은 피하라 : UI, filesystem, controls등과 같은 이름은 다 좋은 이름들이다. controls_group와 같이 이미 알고있는 내용을 덧붙이지 마라. 길고 쓸데없는 내용은 보기 싫다.

매크로:
= 매크로는 위험하다. (단순 무식 과격하며 힘도 엄청나게 쎄다 : 소스코드가 컴파일 되기 전에 전처리 단계에서 매크로에 해당하는 내용은 모두 지정된 매크로를 거친 값으로 바껴버린다.) 아주 위험하므로 반드시 눈에 띄는 표시가 필요하다.(#define 문을 생각하면 쉽다.)

- 모두 대문자로 표기 (그래야 눈에 잘 띈다)

- 충분히 독특한 이름을 사용해야 한다.(독특한 파일이름이나 프로젝트 이름을 접두사로 붙이는 것이 도움이 될수도 있다. 절대 다른 곳에서 실수로 같은 이름이나 그 이름이 포함된 이름을 사용하면 안된다.)

파일:
- 대소문자에 주의하라. 파일검색은 대소문자 구분을 무시하지만 대소문자를 구분해서 사용하는 곳이 분명히 있다. 책에서는 파일이름을 모두 소문자로 하는 것도 좋은 방법이라고 소개하고 있지만 JAVA에서는 클레스와 인터페이스 이름에 PropreCase를 사용하며 이 이름과 파일 이름이 같아야 제대로 작동한다.

- 헤더파일과 헤퍼의 내용을 구현한 파일의 이름은 같도록 해라. stack.hstack.cpp와 같이 쌍을 이루란 말이다.

- 여러 언어를 혼용해서 사용할 경우 같은 이름에 확장자가 다른 것은 같은 디렉토리에 두지 마라. stack.c, stack.cpp, stack.java가 한 디렉토리에 들어있다면 stack.o파일은 뭘 나타내는 것일까? 자식은 하난데 아빠가 셋이다. 가정에 큰일이 날 수도 있다.

- 확장자를 신경써라. C++에서는 확장자를 .C  .cc  .cpp  .cxx  .c++등 여러가지가 있으며 특이하게 헤더파일의 확장자가 .h대신 .hpp로 쓰이는 경우도 있단다. 이런 마구잡이로 쓰인 확장자는 꽤 거슬리는데 MS의 노예가 된 우리는 .cpp와 .h로 거의 통일되어 있다.

more..


대문자 사용의 관례

more..


일관성을 유지하라
- 하나의 이름에 다양한 규칙을 적용하는 바보는 없을 것이다. Using_underscores_AndProperCase 이런거나 Another_Case 같은 이름은 사용하면 안된다는 말이다.

- 프로젝트 전체에 일관된 규칙을 적용해야 한다.
다음과 같은 코드는 일관성이 없어 제대로 분석되기 어려울 것을 예감할 수 있다.

more..


콘텍스트 활용
※ 범위(scope)
- 이름의 범위는 global, namespace, class, function(method), loop등 다양하다. 범위에 따라 이름이 조금씩 바뀔 수도 있다는 것을 참고하자. 같은 변수라고 해도 함수내에 사용되느냐 전역이냐에 따라 이름이 다르게 사용되는 예가 가끔 있다.

※ 타입(type)
- 위에서 이미 말했지만 type을 이름에 넣지 말라는 것이 Code Craft란 책의 주장이다. string형식의 변수에 address_string이란 이름을 주어 재언급을 하는 것은 피하자는 것이다. 헝가리언 노테이션은 이런 재언급을 목적으로 하고 있기 때문에 종종 비웃음 산다고 한다.)
그러나
내가 생각하기에 이 책의 저자는 구식 사고방식을 가지고 있는 것 같다. JAVA나 C#등과 같이 다양한 콤포넌트들이 구현되어 있고 그것들을 따와서 사용하는 방식의 프로그래밍은 객체의 형식을 모두 기억하기 어렵다.
윈도우 응용 프로그램을 예로 든다면 form하나에 들어가는 구성요소(label, textbox, button등)의 종류가 많으면 이것들을 다 기억하기 어려울 수가 있다. 대체로 이러한 구성요소들은 form이 생성될 때 같이 생성되어서 form이 사라질 때까지 운명을 함께하기 때문에 scope가 너무 크다. 함수 내에서 사용되는 변수들은 type을 사용하는 것이 오히려 거추장스럽지만 범위가 넓은 경우 이름에 포함시켜 주는 것이 맞는 것 같다.(필요하니까 주장하는 사람들이 있는거다.) 다만 어떤 경우에 type을 적어주고 어떤 경우에 뺄 것인지 명확하게 구분지어 놔야 한다.
scope가 작은 경우 빼는 것이 좋고, 넓은 경우 넣는 것이 좋지만 프로젝트 전체에서 형식을 통일시켜야 일관성이 유지되니 심각하게 고민해봐야 할 사항이다.

(나의 경우엔 type을 적지 않는 편이다. 요즘은 tool들이 좋아서 이름만 있으면 어떤 형식인지 다 알려주기 때문에 그닥 필요하지가 않다. tool에 지배당하고 있는건가?)
posted by bluelimn 2008.04.07 20:54

예전에 선배가 시집을 선물해준 적이 있었다. 'love adagio'란 책으로 시인의 이름이 '박상순'이었는데 한동안 그분이 여성작가인줄 알았다. 이름으로 인한 오해는 확실히 알아보기 전에는 계속 작용하기 때문에 그만큼 위험하다. 이름을 잘 붙이는 것은 코딩할 때 상당히 까다롭고 중요한 일이다. 내가 이 카테고리를 만들고 책을 사서 정리하는 이유가 사실은 작명 때문이다.

이름은 다음 3가지를 나타낸다.
identity(신원) : 무엇인지 나타내는 기본적인 것으로 주로 변수(혹은 속성)
begavior(행동) : 무엇을 하는 것인지 나타내는 것으로 주로 함수(혹은 메쏘드)
recognition(인지) : 추상적인 것을 표현함(사상, 우주등 실체를 확인하기 힘든 것들)
이름만 잘 지어도 특별한 주석이나 추가 설명문 없이도 이해하기 쉬운 코드가 된다.

잘못 지어진 이름은 자칫 커다란 위험이 될 수도 있다. 책에는 이런 예를 들었다
void checkForContinue(bool weShouldContinue)
{
      if (weShouldContinue) abort();
}

argument로 넘어오는 weShouldContinue은 이름만 봐도 계속 진행할 필요가 있으면 true, 정지해야 하면 false가 들어오는 것을 예상할 수 있다. 그런데 if문에서 만약 true면 중단하라고 하고있다. 정말이지 어이가 희박한 상황이다.
그렇다면 잘못 지어진 이름 말고 대강 아무런 생각 없이 지어진 이름은 어떨까?

void fun(bool a)
{
     if( a ) b();
}
난 이 함수가 의도하는 것을 도무지 이해할 수가 없다. 처음 언어를 배우는 사람들이 실습용 코드를 작성할 때 변수명을 x,y,z,a,b,c.. 이런 식으로 이어가는 경우가 있다. 이렇게 이름을 짓는다면 무슨 기능을 하는지 하나하나 다 설명해줘야 한다. 설명이야 귀찮지만 하면 된다. 그러나 작성하는 프로그래머조자 코드를 작성하는 도중에 헷갈린다. (인간인 주제에 헷갈리지 않을 것이라고 장담하지 마라.)

* 이름을 붙이는 대상
 - 변수(속성, attribute)
 - 함수(메쏘드, method)
 - 타입: class, enum, struct, typedef
 - C++의 namespace, JAVA의 package
 - 매크로
 - source file(파일명)

기본원칙

묘사적인 이름 :
무엇을 나타내는지 정확해야 한다.

적법한 이름 :
이름도중 공백불가, 대소문자구분 허용, 특수문자불가, (언어에 따라 길이와 사용하는 문자셋(unicode,ascii등)의 차이가 있을 수 있다), 예약서 사용불가. C언어에서는 코드 중간에 선언불가, C/C++에서는 global식별자는 str로 시작하고 다음에 소문자나 밑줄불가하며, std namespace에 속하는 이름도 사용불가.

관용구 사용 :
많은 사람들의 코드를 보고 일반적으로 사용하는 이름이 무엇인지 알면 그걸 지어라. 많이 사용하는 이름 일수록 더 알아보기 쉽다.

정확한 이름 : 사전에 없는 단어를 사용하지 마라. 영어 사용에 약한 한국과 일본에서 간혹 영어대신 자국어를 발음나는대로 적어서 사용하는 경우가 있다. 주문을 나타내는 order대신 jumoon이나 joomoon, jumun(주문)이라고 적어버리는 경우가 있다는 말이다.(허접한 인터넷 사이트에서 간혹 보인다.) 심지어 위의 보기에서 jumoon과 joomoon을 같이 사용하면 다른 기능을 표현하는 경우도 있다.(미친 짓이다.) 사전에 없는 단어를 새롭게 만들어내면 나중에 본인도 무엇을 나타내는지 알아보지 못하는 수가 있다. 뭔지 몰라서 사전을 찾아도 소용 없다.

적절한 길이 : 프로그래머는 단어를 짧게 줄이고 싶어하는 충동을 가지고 있다. 하지만 그렇다고해서 함부로 줄이면 큰일난다. 가능하면 모든 이름에 있어 사전을 따라는 것이 좋다.
단, 줄일 때는 몇가지 규칙이 있다.
 - 반복문의 카운터 : 보통 i,j등으로 사용한다. 이것도 짧은 반복문일 경우에 적당하다.
 - 짧은 범위 : 짧은 범위에서는 지나치게 긴 이름대신 짧은 이름을 사용하고 주석을 달아주면 더 이해하기 쉬울수도 있다.

처음부터 잘 지어라 : 나중에 고치지 뭐..같은 건 없다. 임시로 급하게 작성하는 코드라 해도 생각보다 오래가는 경우가 많다. 나중에 창피당하지 말고 첨부터 잘해라.

-다음번엔 대상별로 이름 붙이는 방법을 알아보도록 하자...

posted by bluelimn 2008.03.26 17:06

중괄호를 쓰는 방식으로는 3가지가 많이 쓰인다고 한다. 하지만 그중 하나는 거의 사용되지 않으니 두가지로 볼 수 있겠다.

1.  K&R 중괄호 스타일
C의 아버지 (Kernighan, Ritchie)가 쓴 저서 'The C Programming Language'라는 책(88`)에서 사용한 스타일이다. 이 사람의 영향력 때문에 코딩 스타일의 원조이자 최고의 스타일로 취급되는 경우가 종종 있다.
(울 학교에서 배울 때도 이 스타일대로 가르쳐 줬다. 책에서는 자바코드에서 우세한 스타일로 여겨진다는 말이 나온다. 자바 프로그래머들이 이 스타일을 많이 쓴다는 말 같다.)

more..

장점 : 한 화면에 더 많은 코드를 표시할 수 있다.
         닫는 괄호를 보고 위쪽으로 올라가면 시작하는 위치를 찾을 수 있다.
단점 : 여는 괄호와 줄이 맞지 않아서 찾기 어렵다.
         여는 괄호가 오른쪽으로 밀려나가도 알아차리기 어렵다.
         명령문들이 너무 빽빽해 보인다.

2. exdented(Allman) 중괄호 스타일
공간을 비교적 넉넉하게 사용하는 방법. visual studio와 이클립스에서 이 스타일을 기본으로 사용하며 내가 좋아하는 방식이다. 사실 K&R방식을 사용하다가 최근 exdented방식으로 바꾸려고 노력 중이다.

more..

장점 : 명료하고 산만하지 않다.
        여는 괄호와 닫는 괄호가 같이 보이므로 각 코드의 블록이 명확해진다.
단점 : 수직공간을 많이 차지한다.
         블록의 내용은 짧은데 많은 블록으로 둘러싸인 경우엔 심한 공간낭비로 보여진다.


참고- indented 중괄호 스타일
초창기 Whitesmith C 컴파일러에서 예제코드에 사용된 스타일이며 일반적이진 않지만 아직 사용되고 있단다.

more..

장점 : 코드블록과 중괄호가 이어진다.
단점 : 일반적으로 사용되지 않는다.

주의: 팀에 코딩 표준이 이미 있다면 그것을 사용해야 한다. 자기만의 애호 스타일을 사용하지 마라!
posted by bluelimn 2008.03.26 16:36
혼자서만 일하는 프로그래머가 아니라면 레이아웃과 프리젠테이션은 상당히 중요하다.
띄어쓰기 대괄호의 위치 등 사소한 것들이 엄청난 역할을 해준다. 동일한 레이아웃을 구사한다면 사투리가 없는 동일한 언어를 사용하는 것처럼 편안하게 배울 수 있을 것이다.

more..


우리가 작성한 소스를 읽는 대상은 3종류로 볼 수 있다.
우리자신, 컴파일러, 다른 프로그래머(다른 프로그래머가 진짜 독자라고 생각하라.)

좋은 프리젠테이션이란?
1. 일관성있게
   소스파일을 작성하는 도중에 스타일을 바꾸면 안된다. 만약 다른 사람이 작성한 소스를 부분적으로 수정해야 한다면 원래 있던 소스의 스타일을 따르는 것이 좋다. 소스는 처음부터 끝까지 같은 스타일로 코딩되어야 한다.

2. 관례를 따른다
    자기만의 스타일을 고집하지 마라. 자기만의 스타일을 고집하는 사람은 아무도 같이 일하고 싶어하지 않을 것이다.

3. 간단명료(한눈에 들어오는)
    간단 명료하게 하는 것은 중요하지만 길이를 짧게 만든다고 좋은 소스는 아니다. 결국 알아보기 쉽게 작성하는 것이 최우선이다.
posted by bluelimn 2008.03.20 00:38

안전한 데이터를 사용하라
일반적으로 사용하는 배열의 경우 index가 배열의 크기를 넘어설 수 있다는 위험을 안고 있다. 특히 char배열을 사용한 문자열인 경우 쉽게 그 범위를 벗어나는 경우가 많다.
char *unsafe_copy(const char *source)
{
    char *brffer = new char[10];
    strcpy(buffer, source);
    return buffer;
}
책에서 위와 같은 소스를 예로 들었다. 이러한 내용은 다른 데이터구조에 겹쳐 써질 수 있으며 악의적인 사용자에 의해 스택에 실행가능한 코드를 올려놓고 그 코드를 이용해 마음대로 실행시키는 방법으로 사용될 수 있단다. 무섭다. string클레스처럼 관리기능이 있는 버퍼를 사용하라. 그러한 것이 없다면 최소한 strncpy처럼 크기제한이 있는 operation을 사용하라.

모든 리턴 값을 체크하라
printf나 scanf같은 함수들도 리던값이 있다. 모조리 다 체크하라는 것이 아니라 return이 있으면 최대한 활용하라는 것이다.

변수는 선언지점에서 초기화

변수를 가능한 늦게 선언하라
불행히도 C언어처럼 코드 중간에 변수의 선언을 인정하지 않는 언어도 있지만 대부분 중간에 선언하는 변수들도 인정해준다.
1. 반복문 안에 사용하는 변수를 밖에서 선언하지 마라.
for(int i = 0;...)과 같이 사용하라는 말이다.
2. 임시 변수를 여러곳에서 재사용하지 마라.
temp라는 이름의 변수 아깝다고 여기저기서 재사용했던 기억이 난다. 그런거 하나도 아까울 것 없다. 임시변수라고 해도 한곳에서 한가지로 써라.
*** 효율성에 관한 문제는 컴파일러가 처리한다. 컴파일러를 믿어라. 그거 꽤 공부 많이 한 사람들이 머리 싸매고 같이 만든 것들이다.

언어의 표준을 생각하라.
C와 C++이 특히 심하다. 컴파일러마다 표준을 포함하고는 있지만 다른 추가기능들을 보태서 만들어버린다. 표준이 나중에 나와서 그런 것 같다. 심지어는 표준에 맞추어 작동하지 않는 경우도 있다.
컴파일러의 특정한 기능에 의존하면 안돌아가는 코드 만들어놓고 연장 탓하는 프로그래머가 될 수 있다.
우리가 많이 사용하는 MS visual studio 6.0버젼에서는 반복문 안에 선언된 변수가 다른 곳에서 다시 선언되면 에러를 내고 템플릿도 표준에 맞추어 사용되지 않고 있다.

Cast는 신중하게.
대부분의 언어는 타입케스팅을 허용한다. (int)double_num; 이런걸 허용한다는 말이다. 강제로 모양을 바꾸는 것이니 조심해야 한다. 그 순간만 돌아간다고 넘어가면 다른 곳에서 재사용할 때 반드시 문제가 생긴다.

언어의 관용구(idiom)따르기
많은 사람들이 사용하는 단어를 사용하라. 익숙한 말은 오해를 줄여준다.

수치의 범위 체크하기
1. 수치 변수의 오버플로나 언더플로를 조심하라. 확실히 알고 사용하라.
(얼마 전 파일을 byte단위로 달라서 배열에 저장하는 프로그램을 작성한 적이 있었다. 용량이 작은 것은 문제가 없었는데 index범위가 int의 범위를 넘어서자 문제가 생겼다.)
2. 각각의 계산이 완전한지 체크하라. 0으로 나누는 에러등을 생각하라

***********제약***********
1. 배열에 대한 모든 접근이 배열의 범위 안에서 이루어지는지 체크
2. 포인터로 데이터에 접근하기 전에 포인터의 값이 NULL인지 확인
3. 객체에 대한 operation을 하기 전에 그 객체의 상태에 모순이 없는지 증명
(연산자 오버로딩을 할 경우 연산자 양쪽에 각은 객체가 있을 경우도 생각해야 한다.)
4. 파라미터와 리턴값을 제대로 확인하자.

posted by bluelimn 2008.03.17 12:11

기사원문

more..

========================================================================
같은 소스를 컴파일해도 터키에서는 돌아가지 않는단다. 언어의 문화적 차이 때문이다.
소수점을 마침표(.)와 쉼표(,)로 구분하는 차이, ToLower, ToUpper등 언어의 인식 차이(미쿡에서는 ToUpper를 소문자에서 대문자로 바꾸는 것으로 인식하지만 터키에서는 글자의 크기를 크게 만드는 것으로 인식한다.)
같은 코드를 컴파일하면 에러가 발생하는데 그나마도 브라우저를 터키어로 맞추지 않으면 볼 수 없단다.
.NET에서는 그러한 문화적 차이를 표시해주는 코드가 포함되어 있는데 'Invariant'가 그것이란다.

한국도 마찬가지다. 많은 한국인들이 다분히 미쿡을 동경하지만 언어에 있어서는 한국어를 사랑한다. 일상생활에서 영어를 능숙하게 말하고 다니면 '어머 웬 잘난척? 즈질이야~'정도의 말을 듣는다.(나도 그런말 들어보고 싶다.) 한국어를 좋아하고 주로 사용하는 것은 좋은 현상이다. 그런데 상황에 맞게 사용해야 한다. 프로그래밍을 할 때 시간표시나 숫자표시등이 일치되지 않는 부분이 꽤 있다.
시간표현은 표현방식이 아주 다양하다.
24시표현, AM/PM, 오전/오후
시:분, 시/분, 시-분, 시 분
이렇게 다양한 표현을 모두 한국 문화에서 사용한다. 숫자표현은 어떤가? 그냥 숫자를 바로 사용하기도 한다. 그건 세계 공통이다. 하지만 숫자의 자릿수를 좀 더 명확히 하기위해 ,로 세자리 단위씩 끊어서 표현한다.
그리고 읽을 땐 4자리 단위로 읽는다. 한국에서 사용하는 숫자의 단위는 4단위다.
일, 만, 억, 조, 경, 해... 그런데 숫자는 3단위다. 미쿡에서는 숫자의 단위가 3단위다. 어렸을 적 새로운 단위가 제대로 정착되는데 혼란이 없다면 표기단위를 4단위로 하는 것이 좋을 것이라고 생각했었다.

글에서 문화적 차이를 뛰어넘으려면 ISO표준을 따르라고 권하고 있다.

물론 국제표준을 따르는 것이 가장 좋다. 그리고 그렇게 하지 못할 땐 입장을 확실하게 해야 한다. 무슨 말이냐면 한국식으로 하고싶으면 해당 scope내에서는 확실히 한국식으로 하고, 미쿡식으로 하고싶으면 확실히 미쿡식으로 하고 ISO대로 하고싶으면(ISO표준이 미쿡식은 아니다) ISO에 맞추어서 하란 말이다.
가끔 실무에서도 변수 이름으로 한국어발음을 억지로 영어로 적어놓은 경우를 자주 볼 수 있다.
(실제 이런 이름을 쓰진 않겠지만 굳이 예를 든다면 show, view, print등의 내용을 bogi(보기)와 같이 억지로 쓰는 경우가 있다.)

상대가 정 모르면 사전을 찾아서라도 알 수 있으면 그건 괜찮다. 자신이 있지도 않은 단어를 만들어버리는 도대체 어떻게 알아보란 거야? 이도 저도 아닌 어중간한 지점에서 타협하지 마라!!

posted by bluelimn 2008.03.16 02:13
사용자 삽입 이미지
역시 내 머리는 체계적이지 못해서 'Code Craft'란 책의 힘을 빌리기로 했다. 그런데 이거 원서를 읽기는 부담스럽고 번역서를 읽자니 번역이 엉망이다. 일단 샀으니 열심히 보겠다만 번역한 사람이 어디서 굴러먹던 프리렌서인지 몰라도 번역 후 자기 글을 얼마나 열심히 읽었는지 알 수가 없다. 내용은 좋은 책이니 나한테 필요한 부분만 골라서 열심히 정리해보자

기본 습관 : 에러체크, 테스트, 디버깅
에러체크 : 코드를 작성하는 도중에 발생가능한 에러를 체크하고 막는 과정
테스트 : 발생가능한 에러가 있는지 찾아보는 과정(일단 테스트할 부분은 완성되었다고 가정)
디버깅 : 찾아낸 에러를 수정하는 과정이다.(말 그대로 버그잡기, 글로 따지면 퇴고다.)

코드 작성을 서두르지 마라.
gotcha : 문법적으로는 맞지만 원하는 것과 다르제 작동하는 것. ==를 =로 잘못 타이핑 하는 것등.

아무도 믿지마라.
당신의 코드가 사용되는 곳은 다음과 같다
* 우연히 엉터리 데이터를 입력하거나, 프로그램을 잘못 작동하는 정직한 사용자
* 의식적으로 프로그램에 오작동을 일으키는 악의적인 사용자
* 잘못된 파라미터(주1)를 가지고 함수를 호출하거나 모순된 데이터를 입력하는 클라이언트 코드
* 프로그램에 적절한 서비스를 제공하지 못하는 실행환경(OS등)
* 오작동을 하거나, 당신이 의존하는 인터페이스 규격을 따르지 않는 외부 라이브러리

짧은 코드가 아니라 명료한 코드를 작성하라
코드는 한눈에 들어와야 한다. 함수나 method는 20~30줄을 넘지 않는 것이 좋다. 그렇지만 짧다고 좋은 코드는 아니다. x += ++y; 이딴 식의 복잡한 수식은 절대 쓰지마라.
++y;
x = x + y;
이렇게 두줄이면 충분할 것을 괜히 줄인다고 복잡한 수식을 사용하면 알아보기가 어렵다. 당신이 연산자 우선순위를 잘 알고있다는 것은 자랑할 수 있지만 아무도 같이 일하려 들지 않을 것이다. 극단적인 경우 지나치게 복잡한 연산식 때문에 컴파일러가 잘못된 코드를 생성할 수도 있다.(최적화 과정에서 발생하는 에러는 이러한 경우가 많다. 컴파일러를 거치고 난 어셈블러를 분석해보면 원래코드랑 조금 다른 것을 볼 수 있다. 그건 최적화를 거쳐서 그렇다.)

어설프게 만지면 안되는 것은 아무도 못 만지게 하라
* 객체지향언어에서는 맴버변수를 모두 private로 한다.
* 모든 변수는 그 변수가 속할 수 있는 가장 좁은 범위(scope)안에 둬라.
-- 무지하게 잘난 인간이 아니면 전역은 쓰지마라.
-- 루프안에 선언해도 되는 변수는 루프안에 선언해라.
-- method 내에서만 사용해도 되는 변수를 맴버변수로 올리지 마라.

경고를 무시하지 마라.
컴파일하면 경고(warning)이 뜨는 경우가 있다. 위험하다고 경고하는 거다. 그냥 넘어가면 안된다.
만약 특정 경고가 당신에게 중요치 않더라도 그대로 두지 마라. 나중에 그로인해 정말 중요한 경고가 눈에 안 띄게 될수도 있다.
posted by bluelimn 2008.03.13 01:25
bluelimn's programming

우리 귀여운 변수, 함수들 이름 잘지어서 '누구냐 너는'따위의 말 듣지 않도록 해주자.


요즘 세상은 메모리가 심하게 부족하지도 않고 컴퓨터가 무지 느리지도 않다. 그리고 프로젝트이 규모가 점점 커지고 있어 혼자서 프로젝트를 기획하고 완성시키는 경우는 거의 없다. 이런 세상에서 훌륭한 코드란 알아보기 쉬운 코드다.
물론 기본이 되는 것은 정확성이다. 제대로 작동하지 않으면 아무런 소용이 없다. 여기서 말하는 것은 어떤 프로그램을 만드는가가 아니다. 이곳은 프로그램이 돌아가는데는 큰 지장을 주지 않지만 알아보기 쉽고 유지보수에 편리한 습관이 무엇인지에 대해 고민하는 곳이다.

이름이 생명이다.
이름만 잘 지어놔도 설명할 것이 거의 없어진다. 특히 영어에 익숙하지 않은 사람들은 한영사전이 필수다.
그럼 어떻게 이름을 지어야 한단 말인가?

1. 변수 -> 명사로
   함수 -> 동사 or 동명사
로 짓는다.
변수(멤버변수, 속성)는 data의 의미를 가지고 있기 때문에 명사로 이름짓는다.
함수(멤버펑션, 메쏘드)는 동작하는 하나의 기능을 나타내기 때문에 동사로 짓되 힘든 경우 동명사로 짓는다.

2. 대문자 혹은 _로 단어를 구분한다.
numOfValuses 혹은 num_of_values // getData(...) 혹은 get_data(...)
이런 식으로 사용하는 것이 원칙이다. 나의 경우엔 변수는 _로 구분하고 함수는 대문자로 구분하여 이름만으로 변수인지 함수인지도 구분할 수 있도록 사용하고 있다.

3. 알파벳으로 시작하라.
C#이나 JAVA같이 유니코드를 사용하는 언어는 한글로 변수화 함수를 작성해도 무관하다. (난 가끔 한글로 작명하기도 한다.ㅋㅋ) 하지만 한국에서만 사용되는 source로 만들고 싶지 않다면 아무래도 영어를 사용하는 것이 좋다. 영어로 작명을 하는 경우 이름 중간에 공백이나 특수문자를 사용할 수 없고 숫자로 시작할 수 없다는 대 원칙만 지키면 이름으로 사용할 수 있지만 그럼에도 주의할 것은 있다.
_(under bar)로 시작하는 이름은 system변수와 이름이 같을 수도 있으니 주의해야 한다. 당신이 무지 잘난 인간이 아니라면 사용하지 말기를 권장한다.
대문자로 시작하는 것은 class다. class의 경우 반드시 대문자로 시작해야 한다. 그러니 다른 것(변수,함수)들은 소문자로 시작하는 것이 좋다.