레야몬

3장: 코딩과 디버깅에 관하여 - 2 (50p ~ 65p) 본문

알고리즘/Algorithmic Problem Solving Strategies

3장: 코딩과 디버깅에 관하여 - 2 (50p ~ 65p)

Leyamon 2022. 10. 18. 20:27

자주 하는 실수

산술 오버플로

  • 계산 과정에서 변수의 표현 범위를 벗어나는 값을 사용하는 산술 오버플로

배열 범위 밖 원소에 접근

  • 배열의 범위를 벗어나는 위치의 값에 접근했을 경우 런타임 스택 등을 건드려서 런타임 에러가 날 경우 쉽게 발견할 수 있지만 int a[10], t;의 경우 a[10]에서 t의 값이 나오고 에러가 나지 않으므로 매우 찾기 어려운 버그가 될 수 있다. 따라서 배열의 범위를 정할 때 신중히 정하자.

일관되지 않은 범위 표현 방식 사용하기

  • 닫힌 구간([a, b])를 사용할 경우 공집합을 표현하는 데에 부자연스러우며, 열린 구간(a, b)를 사용할 경우 0부터 시작하려면 음수로 범위를 나타내어야 하므로 부자연스럽다. 따라서 컴퓨터에서는 반 열린 구간(half-open inteval)을 사용한다. 이는 여러 장점이 있는데 바로 공집합을 표현하기 쉽다는 것과, 두 구간이 연속한 지를 쉽게 알 수 있고 구간의 크기도 b-a로 간편하게 알 수 있다는 점이다.

Off-by-ne 오류

  • 100미터인 담장에 10미터 간격으로 울타리 기둥을 세운다. 이때 필요한 기둥의 수는 10개가 아닌 11개이다. A[i]부터 A[j]까지 수열의 합의 평균은 i-j가 아닌 i-j+1로 나누어져야 한다. 이를 헷갈리지 않기 위해선 담장의 길이가 0미터일 때, A[1]부터 A[1]까지의 평균을 구하는 것을 생각해보면 된다.

컴파일러가 잡아주지 못하는 상수 오타

  • 철자를 잘못 쓰거나, 대문자를 소문자로 쓰거나 100,000,007같이 큰 상수에서 0의 개수를 잘못하는 것, 64비트 자료형에 들어가는 계산에서 LL을 붙이지 않은 것 등을 조심해야 한다.

스택 오버플로

  • 지역 변수는 모두 스택 메모리를 사용하므로 크기가 큰 배열을 사용하면 재귀함수를 몇 번 실행하지 않았음에도 스택 오버플로우가 난다. 따라서 전역 변수를 사용하는 것이 좋다.

다차원 배열 인덱스 순서 바꿔 쓰기

  • 다차원 배열에서 인덱스 순서({x, y}와 {y, x})를 바꿔쓰는 경우를 조심해야 한다.

잘못된 비교 함수 작성

  • 아직 다룰 내용이 아니므로 pass

최소, 최대 예외 잘못 다루기

  • 예외 case가 많지만 그 중에서 최솟값, 최댓값인 상황에서 예외인 case들이 많으므로 이를 확인해주도록 하자.

연산자 우선순위 잘못 쓰기

  • if(b & 1 == 0)은 ==이 &보다 우선순위가 높다. 따라서 연산자의 우선순위들을 잘 기억해두거나, 헷갈릴 경우에는 괄호로 감싸는 것이 좋다.

너무 느린 입출력 방식 선택

  • 입력으로 받거나 출력해야 할 변수의 수가 1만 개를 넘어가면 긴장하는 것이 좋다. cin의 경우 cin.sync_with_stdio(false);를 수행하면 된다.

변수 초기화 문제

  • 많은 프로그래밍 대회에서 프로그램을 한 번만 실행하고, 한 번에 여러 개의 입력에 대한 답을 처리하라고 요구하는데, 이때 변수를 초기화하지 않을 경우 잘못된 답을 출력할 수 있다. 따라서 적절히 초기화를 하면서도 예제를 한 번 더 입력함으로써 이를 방지할 수 있다.

 

디버깅과 테스팅

디버깅에 관하여

  • 재귀 호출이나, 중복 반복문을 사용하는 복잡한 코드는 디버깅을 하기에 적당하지 않으므로 디버깅을 하지 않고 눈만으로 검증하는 연습을 해야 한다. 디버깅을 못하면 다음과 같은 과정을 밟으면 좋은 데
  • 작은 입력에 대해 제대로 실행되나 확인하는 것이다. 작은 입력에 대해서 잘못된 것을 확인하면 디버깅 하기 편하다.
  • 단정문을 쓴다 .단정문(assertion)을 쓴다. 주어진 조건이 거짓일 때 오류를 내고 프로그램을 강제 종료시키는 함수 또는 구문으로 어디서부터 프로그램이 잘못을 일으키는지를 알 수 있다. 
  • 프로그램의 계산 중간 결과를 출력하면 좋다.
  • 스택 오류인 경우에는 예외적으로 디버거를 사용해도 상관이 없다.

테스트에 관하여

  • 프로그래밍 대회 답안을 작성한 후에는 제출 전에 예제 입력을 만들어 가능한 많이 프로그램을 테스트하는 것이 좋다. 가장 작은 입력과 가장 큰 입력을 넣어봄으로써 시간 안에 실행되는지, 또는 스캐폴딩(scaffolding)을 사용하는데 스캐폴딩이라는 것은 예제와 답안을 자동으로 만들어내는 프로그램을 말한다. 이를 통해 검증할 수도 있고, 또는 작은 입력을 여러 개 수행해 보며 오류를 찾아낼 수도 있다.

 

 

 

 

진도가 느리다. 이렇게 해서는 대학 입시가 끝날 때까지 종만북을 한 cycle을 돌릴 수 없다. 솔직히 조바심이 난다. 그럼에도 어쩔 수 없다고 생각하고 천천히 해야겠지...

 

 

 

 

 

 

 

 

 

※현재 고등학교 등교 중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고 있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.

Comments