728x90

예전에 선배가 시집을 선물해준 적이 있었다. '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등으로 사용한다. 이것도 짧은 반복문일 경우에 적당하다.
 - 짧은 범위 : 짧은 범위에서는 지나치게 긴 이름대신 짧은 이름을 사용하고 주석을 달아주면 더 이해하기 쉬울수도 있다.

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

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

728x90
728x90

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

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

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

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

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


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

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

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

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

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

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

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

안전한 데이터를 사용하라
일반적으로 사용하는 배열의 경우 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. 파라미터와 리턴값을 제대로 확인하자.

728x90

+ Recent posts