C/C++코드를 빠르게 고치기 위한 체크리스트

2023. 10. 29. 14:21PS

체크리스트

  1. 대부분의 IDE에서는 컴파일 에러 이유를 보여줍니다.
  2. 모든 실행문 끝에는 세미콜론을 적었나요?
  3. 지금 사용한 변수를 선언했나요?
  4. 중괄호가 열렸다면, 닫혀야 합니다.
  5. '들여쓰기’를 맞추면 코드가 눈에 보입니다.
  6. 'A’와 A는 다릅니다.
  7. main 함수 안에 있는 변수는 자동으로 초기화되지 않습니다.
  8. scanf에 들어가는 인자들은 주솟값이어야 합니다. &를 붙였나요?
  9. scanf에서 공백과 줄바꿈 문자를 넣지는 않았나요?
  10. scanf/printf에서 형식 지정자를 잘 맞췄나요?
  11. 문제의 입력과 출력 부분, 조건을 다시 한 번 꼼꼼히 읽어보세요.
  12. 자료형을 확인하세요.
  13. 실수 계산을 정수 계산으로 대체할 수 있나요?
  14. 배열 인덱스를 확인하세요. 배열 크기는 늘 넉넉하게 잡는 것이 편합니다.
  15. 함수가 제대로 동작하지 않나요?

필독

코드의 맨 위(헤더파일 선언 다음)에 다음 코드를 넣으세요.

//디버그, 아래 코드를 복사해서 붙여넣으세요. #define dbg(x) printf("debug %s: %d\n",#x,x); 

이제 여러분은 printf로 디버깅을 할 수 있습니다.
코드가 어디까지 실행되는지 확인하기 위해 스스로 원하는 변수/값을 dbg() 안에 넣어 테스트 해보세요.

예시

int n, sum = 0; scanf("%d",&n); for(int i=1;i<n;i++){ 	dbg(i); 	sum += i; } printf("%d",sum); 

1부터 5까지 합을 구해야 하는데 sum 값이 자꾸만 작게 나오네요.
이때 dbg(i)를 쓴다면 i의 값이 1부터 n-1까지 나오므로 i == n인 순간이 없음을 쉽게 확인할 수 있어요.

dbg 매크로를 활용하여 자신의 코드를 살펴봅시다.

초급

코드를 처음 배우는 단계에서는 정말 잦은 컴파일 에러를 경험합니다.
이 경우 다음 실수들을 점검하는 것이 좋습니다.

대부분의 IDE에서는 컴파일 에러 이유를 보여줍니다.

하단에서 다음처럼 라인 번호와 함께 틀린 이유를 알려줍니다. 이를 먼저 참고하면 코드를 쉽게 고칠 수 있습니다.

solve.cpp: In function 'int main()': solve.cpp:4:20: error: expected ';' before '}' token     4 |     printf("World")       |                    ^       |                    ;     5 | }       | ~ 

모든 실행문 끝에는 세미콜론을 적었나요?

세미콜론을 모든 문장의 끝에 적었는지 확인해보세요.

지금 사용한 변수를 선언했나요?

C언어에서는 사용 전에 변수를 선언해야 사용할 수 있습니다. 같은 이름의 변수는 딱 한 번만 선언할 수 있다는 것도 기억하세요!

중괄호가 열렸다면, 닫혀야 합니다.

모든 중괄호는 짝이 맞아야 합니다. 혼자 열리는 중괄호도, 혼자 닫히는 중괄호도 없도록 코드를 가꿔 주세요.

'들여쓰기’를 맞추면 코드가 눈에 보입니다.

여는 중괄호가 생기면 Tab으로 들여쓰기를 해주세요. 중괄호가 닫히면 원상태로 돌아가면 됩니다. 또한 중괄호를 “{{”. "}}"처럼 한줄에 쓰지 마세요.

#include<stdio.h> int main(){ 	int a = 3, b = 3; 	if(a>1){ 		if(b>1){ 			printf("a and b are both bigger than 1!\n"); 		} 	} } 

'A’와 A는 다릅니다.

'A’는 문자를 나타내는 char형 상수이고
A는 변수 A입니다.

중급

초급 단계를 돌파했다면 이제 코드는 원만하게 실행시킬 수 있습니다. 그런데 코드가 원하는 대로 동작하지 않나요? 다음을 참고하세요.

main 함수 안에 있는 변수는 자동으로 초기화되지 않습니다.

함수 안에 있는 변수들은 기본값이 0이 아닙니다. 컴퓨터 환경에 따라 다른 값이 들어 있어요. 원하는 값이 있다면 변수를 그 값으로 초기화하세요.
함수 안에 있는 변수는 지역 변수, 함수 밖에 있는 변수는 전역변수라 부릅니다.

int x; // 전역변수, 0으로 초기화 됨. int main(){     int a = 1; //지역변수, 1로 초기화됨.     int b; //지역변수, 초기화 안됨. } 

scanf에 들어가는 인자들은 주솟값이어야 합니다. &를 붙였나요?

역시 가장 많이 하는 실수 중 하나입니다. scanf를 할 때는 입력을 받고 싶은 변수 앞에 &를 붙여서, 변수의 주소값을 넣어줘야 해요.

int main(){     int a = 1;     scanf("%d",&a); // 변수 a의 주소에 input을 넣음.     int b = 1;     scanf("%d",b); // 변수 b 값 주소에 input을 넣음. 실행이 안됨.     printf("%d %d",a,b); // 만약 이 줄이 실행이 되도, b에는 1이 그대로 들어가있음. } 

역시 printf에서는 &를 붙이면 주솟값이 출력됩니다.
printf는 scanf와 유사하지만, 입력한 그대로를 출력하는 함수입니다.

scanf에서 공백과 줄바꿈 문자를 넣지는 않았나요?

특수한 경우가 아니라면, scanf의 %d, %f, %lld를 비롯한 형식 지정자들은 자동으로 공백 및 줄바꿈을 파싱합니다. scanf에서 공백과 줄바꿈을 쓰는 것은 원하는 동작대로 되지 않을 확률이 높습니다.

scanf("%d%d",&a,&b); // YES!  printf("%d %d\n",&a,&b); // NO 

공백 및 줄바꿈으로 구분된 변수를 입력 받을 때는 형식 지정자를 그대로 사용하세요.

scanf/printf에서 형식 지정자를 잘 맞췄나요?

int 는 %d,
long long은 %lld,
float는 %f,
double은 %lf
char은 %c,
char 배열은 %s입니다.

이때 scanf에서 char 배열을 입력받을 때는 배열의 이름만을 써주면 됩니다.

char str[100]; scanf("%s",str); // YES! scanf("%s",&str); // NO 

고급

코드는 잘 실행되는데, 내가 모르는 곳에서 원하는 대로 동작하지 않을 수도 있습니다. 어떤 곳에서 그럴까요?

가장 먼저 체크리스트의 dbg 매크로를 통하여 스스로의 코드를 확인해봅시다.

문제의 입력과 출력 부분, 조건을 다시 한 번 꼼꼼히 읽어보세요.

대부분의 "틀렸습니다"는 문제를 다시 읽는 것으로 해결할 수 있습니다.

자료형을 확인하세요.

코드에서 계산 도중 int 형의 범위를 넘어가지는 않나요? long long으로 변경해야 할 수도 있습니다.
컴퓨터에서 실수형은 보장하는 정밀도가 한정되어 있어요. float로 부족하다면 double을 사용해보세요.

실수 계산을 정수 계산으로 대체할 수 있나요?

컴퓨터에서 실수형은 정확하지 않습니다. 절댓값이 큰 정수를 저장하기에 적합하지 않아요. 가령 분수를 저장할 때는 float변수에 저장하는 것이 아니라, 분수와 분모를 정수 자료형에 저장하세요.

배열 인덱스를 확인하세요. 배열 크기는 늘 넉넉하게 잡는 것이 편합니다.

배열의 음수 위치를 참고하고 있지는 않나요? 배열의 크기가 100인데 101번째 원소를 참고하고 있는 것은 아닐까요?

int a[100]; a[-1] = 99; // NO! a[100] = 1; // NO! 

함수가 제대로 동작하지 않나요?

함수의 반환 형태가 void가 아니라면, 코드가 모든 상황에서 return 해야 합니다. if문 안에서는 return하는데, 다른 상황에서는 return을 하지 않는 경우가 있는지 확인해보세요.

마치며

지금까지 C/C++ 코드에서 자주 실수하는 내용에 대해 알아보았습니다. 읽으시면서 “이런 내용도 있으면 좋겠다” 싶으신 것이 있으면 자유롭게 제안해주세요. 체크리스트를 통해 모두가 실수에서 막히지 않고, 프로그래밍을 즐길 수 있기를 바라며 이만 글을 마칩니다.
.
.
.
이 글은 [Daily] Vault에서 작성되었습니다.

728x90

'PS' 카테고리의 다른 글

USACO US Open 2009 Gold 3 - Tower of Hay  (0) 2024.02.23
백준 17399 트리의 외심 - 정당성 증명  (0) 2024.02.11
백준 단계별로 풀어보기 완.  (34) 2024.02.05
28031 Milk Sum  (0) 2023.10.26
2023년 PS 생각  (4) 2023.03.25