1. 항상 초기화를 한다.
1.1. 초기화를 하여, 언제 발생 할지 모르는 trash 값을 미연에 방지한다.
● 구조체
● 포인터
● 일반 변수
2. 인터페이스를 정의 하여 모듈화를 한다.
● int add(int, int); /* 덧셈 함수 */ : 공동 프로젝트 시, 함께 사용 할 함수
는 상의 후 헤더파일에 정의한다.
● 반환값, 매개변수 정의(설계)를 먼저 한다.
3. 개발환경을 직접 만들 수 있어야 한다.
● 각 모듈마다 혹은 통합적인 Test program을 만든다.
4. 주석 사용
4.1. 프로그래밍 시작
/*+======================================================
Project Name: ??? ☞??? : 프로젝트/회사이름
File Name: FormatString.c
Revision: 1.0
Date: 2012.01.12
Author : coz
copyright (c) 2002-2003 ??? Co., Ltd.
All Rights Reserved
========================================================+*/
4.2. 함수
/*=======================================================
insert 모듈이름
Funtion: Insert 함수이름
ProtoType: void Insert(char *) 인터페이스
Author: coz 작성자
Revision: 1.02012.01.12 최초 작성 날짜
Modified: 2012.01.12 By Lee 마지막 수정 날짜와 수정자
========================================================*/
5. 변수를 수직으로 명명 한다.
5.1. 소스의 가독성이 높아진다.
ptr->ySize = 10;
ptr->xStartPosition = 205;
ptr->yStartPosition = 200;
ptr->scale = 10;
6. 함수 튜닝에 좋은 습관
6.1. 의도하지 못한 에러를 방지 하고 소스의 신뢰성을 높인다.
● 매개변수를 사용하여 연산하지 않는다.
● 매개변수 검사문을 삽입한다.
● 반환값을 이용하여 함수의 실행 여부를 판단 할 수 있다.
● printf("[%s][%s][%d]\n", __FILE__, __FUNTION__, __LINE__); 을 사용
한다.
7. 메모리 할당/해제는 함수로 처리한다.
8. 가독성을 높인다.
● if, case문을 적절히 사용한다.
● 3항 연산자를 사용한다. max = (a > c) ? a : b;
● 열거형을 사용한다. typedef, enum Grade {A=1, B, C, D=10, E};
● 띄어쓰기 한다. int a=3; (NO)int a = 3; (OK)
9. 전처리기를 사용한다.
9.1. #ifndef, #define, #endif
● 다중 파일 사용
● 디버깅
#define DEBUG
void main(){
#ifdef DEBUF
printf("디버깅 코드\n");
#else
printf("릴리즈 코드\n");
#endif
}
10. 전역변수를 피한다.
● 매개변수와 구조체를 활용하여 전역변수 사용을 피한다.
● 프로젝트에서 다함께 쓰는 전역변수는 쓰지 않는다.
● 쓰게 된다면 헤더가 아니라 소스 내부에서 사용한다.
11. 자물쇠 const
11.1. void StringCopy(const char *sorce, char *dest)
11.2. 논리적 버그 예방할 수 있는 특징
● const 포인터가 가리키는 값을 변경할 수 없다. 단 포인터의 주소는 변경
가능
● const 포인터는 일반 포인터로 할당될 수 없다.
12. 메모리를 제대로 알고 사용한다. 16진수 기법에 익숙해진다.
● 메모리 주소를 출력할 때 %#x 형식 지정자를 사용한다. (0x5a35ff)
13. 정적 함수로 접근권한을 준다.
● 함수가 정의된 파일 안에서만 함수를 사용할 수 있다는 특성을 이용한다.
● 모듈화 극대화와 디버깅 시간을 줄여준다.
14. 구조체 활용법.
14.1. 패킹 : 32비트 시스템들은 4바이트 정렬을 한다(네트워크 활용시 주의?).
[long(4byte), char(1byte) 로 6바이트처럼 보이지만 패킹 하지 않으면 8바이트가 된다]
typedef struct{
long a;
char b;
char c;
}__attribute__((packed)) DATA
14.2. 배열과 구조체 포인터 연결하여 사용한다.(네트워크 활용)
배열 = "abcdef", 구조체.a(int형), 구조체.b(char형) 일때,
구조체 = 배열; 적용하면
a엔 abcd에 대한 값이 들어가고
b엔 e값이 들어간다.
14.3. 구조체 안에 구조체를 사용한다.
15. union
typedef union _BYTE{
unsigend char byte;
struct _bit {
unsigned char B0 : 1;/* 1비트의 공간 할당 */
unsigned char B1 : 1;
unsigned char B2 : 1;
unsigned char B3 : 1;
unsigned char B4 : 1;
unsigned char B5 : 1;
unsigned char B6 : 1;
unsigned char B7 : 1;
} bit;
} BYTE;
16. 고수들 디버깅.
16.1. ASSERT(), VERIFY()함수를 이용한다.
● #define ASSERT(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
로 정의되어 있다.
둘다 비슷한 기능을 하지만 MSDN에 명시한 차이점은 이렇다.
"
프로그램의 릴리스 버전에서는 ASSERT 식을 계산하지 않기 때문에 디버그 버전과 릴리스 버전에서 nM의 값이 다릅니다. MFC에서는
ASSERT 대신 VERIFY 매크로를 사용할 수 있습니다. 릴리스 버전에서 VERIFY는 식을 계산하지만 결과를 확인하지는 않습니다.
함수를 계산할 때 예기치 않은 의도하지 않은 연산이 발생할 수 있으므로 어설션 문에서 함수를 호출할 때는 특히 주의하십시오.
코드 복사 ASSERT ( myFnctn(0)==1 ) // unsafe if myFnctn has side effects
VERIFY ( myFnctn(0)==1 ) // safe
VERIFY는 디버그 버전과 릴리스 버전에서 모두 myFnctn을 호출하기 때문에 사용이 가능합니다. 그러나 릴리스 버전에서는 여전히 불필요
한 함수 호출의 오버헤드가 발생하게 됩니다.
"
이러한 관계로 verify보다는 디버깅 모드에서만 assert를 사용하는게 좋을듯 생각한다.'정리' 카테고리의 다른 글
site (0) | 2012.10.30 |
---|---|
push server (0) | 2012.10.22 |
뮤텍스와 세마포어 (0) | 2012.03.12 |