서식
코딩 시 모두가 통일된 스타일을 사용하면 프로젝트를 파악하기 쉬워진다.
각자가 모든 서식 규칙에 동의하기 어렵고, 일부는 익숙해지는데 시간이 걸리지만, 프로젝트 구성원들이 규칙에 따라 코드를 작성함으로써 서로의 코드를 쉽게 이해하도록 하는 것은 중요하다
줄 길이
- 코드의 각 줄은 120 문자를 넘지 않게 한다.
문자형식
- 문자는 되도록 ASCII 문자를 사용하고, ASCII가 아닌 문자를 사용할 경우에는 UTF-8 형식을 사용한다.
들여쓰기
단계 당 2개의 스페이스로 들여쓰기(indentation) 하고 탭은 사용하지 않는다.
코드 상의 그 어디에서도 탭을 사용하지 않는다.
중괄호
중괄호로 묶이는 모든 코드블럭에서, 각 중괄호
"{", "}"
는 구문에 따라 같은 줄에 작성하거나 줄바꿈하여 작성한다.// 함수 내용을 여는 중괄호와 닫는 중괄호는 모두 새로운 줄에 작성한다. int Function(int a) { } // 구조체 내용을 여는 중괄호와 닫는 중괄호는 모두 새로운 줄에 작성한다. struct Structure { }; // 열거형 내용을 여는 중괄호와 닫는 중괄호는 모두 새로운 줄에 작성한다. enum eCode { }; // 조건문 내용을 묶는 중괄호는 같은 줄에 작성하고, 닫는 중괄호는 새로운 줄에 작성한다. // 단, 가독성이 현저하게 낮은 경우 가독성 향상을 위해 묶는 중괄호를 새로운줄에 작성할 수도 있다. if (condition) { DoSomething(); } // switch 문을 묶는 중괄호는 같은 줄에 작성하고, 닫는 중괄호는 새로운 줄에 작성한다. // 단, 가독성이 현저하게 낮은 경우 가독성 향상을 위해 묶는 중괄호를 새로운줄에 작성할 수도 있다. switch (var) { case 0: ... }
모든 조건문(if, switch)와 반복문(for, while)에서 중괄호를 반드시 사용한다. 본문이 한 줄인 경우에도 중괄호를 사용한다.
if (condition) { DoSomething(); } while (condition) { DoSomething(); } switch (var) { case 0: ... }
강제 줄 바꿈
모든 조건문(if, switch), 반복문(for, while)의 표현식이 정해진 가로 줄 길이를 초과할 경우, 가독성 좋게 정렬하여 줄바꿈한다.
- 일관성 있게 줄바꿈 한다.
- 각 줄의 시작지점을 통일한다.
- 보통 연선자 뒤에서 줄바꿈한다.
if ((this_one_thing) > this_other_thing) && (a_third_thing == a_fourth_thing) && yet_another && last_one) { .. }
함수 선언과 정의
기본적으로 리턴 타입과 함수이름, 인자를 같은 줄에 작성하지만, 정해진 가로 줄 길이를 초과할 경우 줄바꿈하여 작성할 수 있다.
// 기본 형식 ReturnType FuctionName(Type var1, Type var2) { DomSomething(); } // 한줄에 작성하지 못할 경우, 리턴 타입 작성 후 줄바꿈하여 작성한다. ReturnType ReallyLongFunctionName(Type var1, Type var2, Type var3) { DoSomething(); } // 리턴 타입을 제외한 함수이름, 인자만으로도 한줄에 작성하지 못할 경우, 리턴타입과 함수이름을 한줄에 작성하고, 각 인자를 서로 다른 줄에 작성한다. ReturnType ReallyLongLongLongLongLongFunctionName( Type var1, Type var2, Type var3) { DoSomething(); }
주의사항
- 여는 괄호 "
(
"는 항상 함수 이름과 같은 줄에 작성한다. - 닫는 괄호 "
)
"는 항상 마지막 인자에 붙여서 작성한다. - 함수 일므과 여는 괄호 "
(
" 사이에는 스페이스를 넣지 않는다. - 여는 괄호 "
(
" 및 닫는 괄호 ")
"와 인자 사이에는 스페이스를 넣지 않는다. - 각 인자 사이에는 쉼표 + 하나의 스페이스를 사용하여 구분한다.
- 여는 중괄호 "
{
" 는 항상 닫는 괄호 ")
" 다음 줄에 작성한다. - 닫는 중괄호 "
}
"는 혼자 마지막 줄에 위치해야 한다. - 모든 인자는 이름을 가져야 하며, 선언과 구현에서 같은 이름을 가져야 한다.
- 함수 내 기본 들여쓰기는 2개의 스페이스다.
- 모든 인자들은 가능한 한 정렬되어야 한다.
- 인자들이 다음 줄로 이동할 경우 2개의 스페이스 들여쓰기를 사용한다.
- 인자들이 다음 줄로 이동할 경우 한 줄당 하나의 인자만 작성한다.
- 여는 괄호 "
함수 호출
기본적으로 한 줄로 작성하지만, 정해진 가로 줄 길이를 초과할 경우 줄바꿈하여 작성할 수 있다.
// 기본 형식 bool retval = FunctionName(argument1, argument2, argument3); // 같은 줄에 작성하지 못하는 경우, 첫 번째 인자를 제외한 나머지 인자들을 별도의 줄에 작성한다. // 인자의 시작위치는 동일하다. bool retval = ReallyLongLongLongLongLongFuctionName(argument1, argument2, argument3);
switch문
- case 구문은 스페이스 2개로 들여쓰기 한다.
- case 구문의 본문은 스페이스 4개로 들여쓰기 한다.
- 항상
default
구문을 포함해야 한다, default 케이스가 실행되지 말아야 할 경우 assert()하거나 사용자가 알 수 있도록 로그 출력 등을 수행해야 한다.
switch (var) { case 0: ... break; case 1: ... break; default: assert(false); }
반복문
비어 있는 반복문은 세미콜론
";"
대신 중괄호"{}"
를 사용하고, 중괄호는 조건문 다음에 붙여서 작성한다.for (int i = 0; i < kSomeNumber; ++i) {} while (condition); // 나쁨 while (condition) {} // 좋음
리턴값
return 표현식을 불필요하게 괄호로 묶지 않는다.
return result; // 좋음 - 괄호 사용이 필요 없는 간단한 경우 return (some_long_condtion && another condition); // 좋음 - 복잡한 표현식의 가독성을 높이는 경우 괄호가 허용됨. return (value); // 나쁨 return(result); // 나쁨
전처리기 지시자
전처리기 지시자의
"#"
기호는 항상 그 줄의 처음에 작성한다. (들여쓰기 된 코드의 내부의 전치리기 지시자 포함)// 좋음 - 지시자가 줄의 처음부터 시작한다. #define NORMAL if (lopsided_score) { #if DISATER_PENDING // 좋음 DropEverthing(); #if NOTIFY // 좋음 NotifyClient(); #endif #endif BackToNormal(); } // 나쁨 - 지시자가 들여쓰기 되어 있다. if (lopsided_score) { #if DISASTER_PENDING // 나쁨 DropEverything(); #endif // 나븜 BackToNormal(); }
전처리기 지시자가 코드블럭을 감싸고 있는 경우, 닫는 부분
"#endif"
뒤에는 여는 부분에 명시된 조건을 주석으로 표시한다.if (lopsided_score) { #if DISASTER_PENDING DropEverything(); #if NOTIFY NotifyClient(); #endif // NOTIFY #endif // DISASTER_PENDING BackToNormal(); }
가로 공백
줄 끝에는 공백 문자를 사용하지 않는다.
줄 끝에 공백문자를 두면 같은 파일을 편집하는 다른 사람이 기존의 뒤쪽 공백문자를 삭제할 경우, 코드 내용의 변경이 없이도 코드변경이 발생한다.
가로 공백 - 일반사항
연속적으로 나열된 인자나 변수들을 구분하는 쉼표
","
뒤에는 하나의 스페이스를 넣는다.int i, j; int x[] = { 0, 1, 2};
모든 문장의 콜론
":"
과 세미콜론";"
앞에는 스페이스를 넣지 않는다.int i = 0; // 모든 문장의 세미콜론 앞에는 스페이스를 사용하지 않는다. switch (i) { case 3: // switch 문의 case 구문의 콜론 앞에는 스페이스를 사용하지 않는다. ... } out: // goto 문에서 사용되는 분기구문의 콜론 앞에는 스페이스를 사용하지 않는다.
각 괄호
"(", ")"
와 괄호 안 내용 사이에는 스페이스를 넣지 않는다. 괄호 안 내용 자체는 가독성을 위해 스페이스를 사용할 수 있다.int ret - Fuction(a, b); int result = 1 + (a + b); for (int i = 0; i < 5; ++i)
중괄호
"{", "}"
를 이용한 리스트 초기화 시, 중괄호와 괄호 안 내용 사이에는 하나의 스페이스를 넣는다. 괄호 안 내용 자체도 가독성을 위해 스페이스를 사용할 수 있다.int x[] = { 0, 1, 2 };
가로 공백 - 반복문과 조건문(if, else, if, for, while)
조건문/반복문의 키워드(if, else, if, switch, for, while)와 여는 괄호
"("
사이에는 하나의 스페이스를 넣는다.// 좋음 if (condition) switch (var) while (condition)
조건문/반복문에서 갈 괄호
"(", ")"
와 조건구문/반복구문 사이에는 스페이스를 넣지 않는다.// 좋음 switch (var)
for문에서 세미콜론
";"
다음에는 하나의 스페이스를 넣는다.for (int i = 0; i < 5; ++i) for (; i < 5; ++i)
가로 공백 - 연산자
연산자(=, +, -, /, %, >>, <<, ^, &, |) 전후에는 각각 하나의 스페이싀를 넣는다.
하지만 가독성을 위해서 각 항마다 스페이스를 넣지 않을 수 도 있다.
a = (w * y) + (t / z) - 1; a += 3; a = b >> 3; a = b ^ 2; a = y | 3; a = z & 3; a = (w*y) + (t+z); // 가독성을 위해 스페이스 생략 가능
단항 연산자(예, -, ++, !)와 그 인자 사이에는 스페이스를 넣지 않는다.
x = -5; ++x; if (x && !y)
세로 공백
세로 공백의 사용을 최소화 한다.
꼭 필요한 경우가 아니면 빈 줄을 사용하지 않는다. 더 많은 코드가 화면에 들어올수록 프로그램의 흐름을 따라가거나 이해하기 쉽다. 단, 지나치게 조밀한 코드는 가독성을 저해하므로 적절한 수준을 유지해야 한다.
함수 사이에 3개 이상의 빈 줄을 추가하지 않는다.
함수의 시작이나 끝 부분에 빈 줄을 사용하지 않는다.
함수 내부에서도 빈 줄을 되도록 사용하지 않는다.
단, 가독성 향상을 위해 블록 별로 빈 줄을 구분 할 수도 있다.
if문
else if 또는 else 문은 이전 if문 또는 else if 문을 닫는 중괄호와 같은 줄에 작성한다
필요한 경우 가독성을 위해 이전 중괄호의 다음줄에 작성할 수 도 있다.
// 기본 형식 if (condition) { } else if (condition) { } else { }
'프로그래밍 언어 > [ Coding Style Guide ]' 카테고리의 다른 글
[ Coding Style Guide ] 05. C언어 - 주석 (0) | 2021.01.20 |
---|---|
[ Coding Style Guide ] 04. C언어 - 변수범위 (0) | 2021.01.20 |
[ Coding Style Guide ] 02. C언어 - 헤더파일 (0) | 2021.01.20 |
[ Coding Style Guide ] 01. C언어 - 이름규칙 (0) | 2021.01.08 |
[ Coding Style Guide ] 00. 코딩 명명법 (2) | 2021.01.08 |