들어가기에 앞서
디버깅(debugging)
-컴퓨터 프로그램 개발 단계 중에 발생하는 시스템의 논리적인 오류나 비정상적 연산(버그)을 찾아내고 수정하는 작업 과정
프로그래밍 언어에서 쓰이도록 고안된 문자열 오기입에서 오는 오류
문법 오류는 단순히 프로그래밍 문법대로 코딩하지 않아서 발생한다
오류가 있는 부분에 빨간색으로 표시도 되고, 컴파일러가 몇 번째 줄 어디에 오류가 있는지 알려준다.
컴파일이나 비정상 종료는 일어나지 않지만 의도치 않은 동작을 하는 오류
uint increasingNum = 1;
uint endPoint = uint.MaxValue;
while(true)
{
increasingNum *= 2;
Console.WriteLine(increasingNum);
if (increasingNum > endPoint)
{
Console.WriteLine($"{endPoint} 초과로 종료");
break;
}
}
1이라는 숫자에 2를 계속해서 곱하면서 값을 출력하고, 표현할 수 있는 정수의 최대치에 도달했을 때 출력을 종료하는 코드이다.
코드 상으로 보기에는 문제가 없어보이나 이를 실행하면 다음과 같이 결과가 나온다.
이 뒤로 0이 무한정 출력되면서 원하는 의도대로 프로그램이 작동하지 않았다.
논리 오류는 문법적으로는 맞지만, 의도와는 다른 지시사항 작성시 발생한다
컴퓨터는 인간의 의도를 모르기에 코드에는 오류 표기 없이 그대로 실행되며, 프로그래머가 직접 이 논리적 오류를 찾아서 고쳐야한다.
디버그 없이 실행을 누르면 실행창에 바로 결과가 출력되지만, 그 과정을 살피기는 어렵다.
이때 비주얼 스튜디오 창이 켜진 상태에서 F11을 누르면 코드가 한 단계씩 실행되게 할 수 있다.
비주얼 스튜디오 좌측에 바에 마우스 커서를 갖다대면, 동그라미가 생긴다.
이걸 누르면 동그라미가 빨간색으로 변하고, 디버그하고 시작하기를 누르면 표시한 구간에서 실행이 일시정지된다.
코드가 긴 상황이고, 앞의 구간의 코드는 정상 작동하여 스킵하고 문제가 있는 구간부터 체크할 때 사용한다.
단순하게 마우스 커서를 변수에 갖다대보기만 해도 현재 변수의 값이 얼마인지 확인할 수도 있다.
원하는 변수를 모아서 볼 때 조사식을 사용할 수 있다.
조사식을 추가하면 아래와 같이 하단에 표시되고, 변수를 포함한 수식의 형태로도 값을 볼 수 있다.
이와 같이 디버깅을 위한 기능을 알아봤으니, 맨 처음 논리적 오류에서 작성한 코드에 왜 문제가 발생했는지 생각해보자.
코드의 출력문을 다시 확인해보자.
코드의 출력문을 보면 2147483648로 표기된 다음 숫자가 0으로 출력되는 것을 확인할 수 있다.
왜 갑자기 2147483648 * 2에서 갑자기 0이란 결과가 도출되었을까?
우선 계산기로 2147483648을 이진수로 확인해보자.
2147483648 = 10000000000000000000000000000000(2)이다.
만약 이 숫자에서 2를 곱하면?
4294967296 = 100000000000000000000000000000000(2)
여기에서 uint가 표시할 수 있는 범위가 어디까지인지 확인해보았다.
즉, 4294967296 이라는 숫자 자체가 uint의 표현 범위를 넘어선 것이다.
저장할 수 있는 데이터의 한계가 발생하여 모든 숫자가 저장되지 못하는데,
4294967296 = 100000000000000000000000000000000(2) = 0
으로 저장되는 것이다.
이러한 현상을 오버플로우(Overflow)라고 하며,
오버플로우로 인해 데이터의 손실이 일어나 0이라는 결과가 나오게 된 것이다.
그렇다면 문제를 해결하려면 어떻게 해야 할까. 의외로 간단하게 오류를 고칠 수 있었다.
uint increasingNum = 1;
uint endPoint = uint.MaxValue;
while(true)
{
increasingNum *= 2;
Console.WriteLine(increasingNum);
// increasingNum을 long으로 강제 형변환을 하고, * 2 가 되는 구간에서 최대치를 넘으면 break 되도록 함.
if ((long)increasingNum * 2 > endPoint)
{
Console.WriteLine($"{endPoint} 초과로 종료");
break;
}
}
이를 출력하면 아래와 같이 출력된다.
컴퓨터는 부정확하다는 걸 감안해야 한다.
컴퓨터는 이진수로 데이터를 처리하다 보니 오차가 발생할 수 있고, 아래와 같은 사례로도 오차를 확인할 수 있다.
float sum = 1.1f + 0.3f // 1.1 + 0.3 = 1.4 라고 출력될 것이다.
이를 출력하면 아래와 같이 나온다.
컴퓨터가 1.1과 0.3을 정확히 표현하지 못해서 생기는, 부동소수점으로 인해 발생하는 오류이다.
이와 같이 프로그래밍을 할 때 오버플로우 같은 데이터 손실이 생기는 부분이나, 오차가 발생할 수 있다는 것을 감안해야 한다.