Skip to content

Latest commit

 

History

History
127 lines (96 loc) · 6.15 KB

File metadata and controls

127 lines (96 loc) · 6.15 KB

프로그램 관련 에러 종류

C++ 프로그램을 생성하기 위해서는 소스파일을 작성한 후 컴파일 및 링크 과정을 통해 실행할 수 있는 프로그램을 만든다. C++ 소스 파일이 C++ 언어 문법에 어긋나게 작성된 경우 에러가 발생하거나 복 수의 목적 파일(object file)을 묶어서 하나의 실행 파일을 만드는 과정에 에러가 발생할 수 있다. 실행 중에 소스 파일이 구문적으로 에러는 없으나 프로그램이 실행 중에 프로그래머의 의도와 다른 논리 에러가 발생하거나 메모리 등 컴퓨팅 자원 부족이나 사용자의 잘못된 입력 등 여러 원인으로 프로그램이 비정상적으로 실행이 종료하는 경우가 있다. 이는 프로그램이 문법적으로 작성이 잘못된 것이 아니라 프로그램의 외적인 요인으로 발생하는 것으로 이러한 에러를 올바르게 처리하지 못해 오류로 이어진다면 이는 프로그래머의 잘못이기 때문에 예외 상황을 적절하게 대처하는 프로그램을 작성하는 것이 필요하다.

Compile errors (컴파일 에러)

컴퓨터 프로그램에서 컴파일 에러는 구문 에러(syntax error)라고도 하며 작성된 프로그램 코드가 프로그램 언어의 문법에 위배되는 경우에 발생한다.

Link errors (링크 에러)

소스파일의 컴파일 결과인 목적파일(object file)과 소스파일에서 사용하는 함수에 대한 목적파일을 묶어서 실행파일을 만드는 과정에서 함수의 목적 파일이 없거나 목적파일과의 링크를 지정하지 않은 경우에 발생한다. 아래의 코드는 컴파일하면 컴파일 에러가 발생하지 않지만 링크 에러가 발생하는 코드이다.

#include <iostream>

int mysum(int a, int b);

int main(int argc, char const *argv[])
{
	mysum(10, 20);
	return 0;
}

앞의 코드를 MacOS X에서 컴파일러와 링커를 이용하여 실행 파일을 생성하는 과정에서 다음과 같은 에러가 발생한다.

Logic errors (논리 에러)

논리 에러는 프로그램이 실행되는 과정에 발생하는 에러로 프로그램이 실행 중 비정상적으로 종료되지 않으나 프로그램이 프로그래머의 의도한대로 실행되지 않는 프로그램의 버그로 프로그래머가 코드를 작성하면서 실수를 한 것이나 문법적인 에러가 없어 컴파일 단계에서 에러 메시지가 출력되지 않는다. 논리 에러가 있는 프로그램은 의도되지 않거나 원하지 않는 결과 또는 동작을 발생시킨다.

아래의 코드는 평균을 계산하려고 의도가 있는데 코드의 실행 결과는 a의 값에 b/2를 더한 연산이 된다. 이는 "+" 연산자와 "/" 연산자의 실행 순서를 이해하지 못해서 생긴 결과일 것이다.

double average (double a, double b) {
  return a + b / 2;      // (a + b)/2
}

아래의 코드의 의도는 a가 0인 경우에만 조건문내의 코드가 실행되도록 하는 것인데 아래의 코드를 실행하면 a가 0인 경우에도 조건문 내의 코드가 실행되지 않는 문제가 발생한다. 이는 if 조건문의 실행 조건을 확인하는 소괄호 안의 연산이 "a = 0" 으로 a에 0을 대입하는 연선으로 연산 이후의 a의 값이 0이되어 조건이 항상 거짓이 되어 a가 0인 경우에도 조건문내의 코드가 실행되지 않는다.

if (a = 0) {   //  a == 0
	....
}

Runtime errors (런타임 에러)

컴퓨터 프로그래밍에서 런타임 에러는 프로그램 실행 중에 발생하는 프로그램의 버그로 프로그램 중 0으로 나누기 에러, 동적 메모리 할당 시 메모리 부족 에러, 배열에서 범위를 벗어난 영역의 접근 에러가 예이며 컴파일 과정에서는 검출되지 않는다. 이 에러는 프로그램이 종료되거나 잘못된 결과가 나온다. 아래의 프로그램은 정수의 팩토리얼 값을 구하는 함수를 재귀 함수의 형태로 정의한 후 main함수에서 3의 팩토리얼 값을 구하는 함수를 호출한다. 이 프로그램을 실행시키면 segmentation fault가 발생하고 프로그램이 종료된다. 이는 factorial함수 내에서 factorial함수를 호출하는데 factorial함수 내에서 호출을 중단하는 조건이 없어서 함수를 계속 호출하게 된다. C++ 프로그램에서 함수를 호출할 때 마다 함수 호출과 관련한 데이터를 스택에 저장한다. 함수가 무제한 호출됨에 따라 스택의 저장공간을 모두 소진하게 되어 런타임 에러가 발생하게 된다.

#include <iostream>
using namespace std;

int factorial(int n) {
	return n * factorial(n-1);
}

int main(int argc, char const *argv[])
{
	cout << factorial(3) << endl;
	return 0;
}

C++ 언어의 예외처리 대상

모던 C++에서는 논리 에러와 런타임 에러 모두를 예외 처리 메커니즘을 통해서 처리할 수 있다.

문제

  1. 아래의 코드는 정수를 키보드로 부터 입력받아 1에서부터 입력한 정수(n)까지 정수를 곱하는 팩토리얼을 계산하려는 의도로 작성한 코드이다. 원하는 결과가 나오지 않는 원인을 확인하고 수정하라. (발생한 오류의 종류는?)
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
	int i, n, f;
	cout<< "숫자(정수)를 입력하시요: ";
	cin >> n;

	for(i = 1; i < n; i++) f *= i;
	cout << n <<"! = " << f << endl;
	return 0;
}
  1. 아래의 코드는 정수를 키보드로 부터 입력받아 1에서부터 입력한 정수(n)까지 정수를 곱하는 팩토리얼을 계산하려는 의도로 작성한 코드이다. 원하는 결과가 나오지 않는 원인을 확인하고 수정하라. (발생한 오류의 종류는?)
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
	int i, n, f = 0;
	cout<< "숫자(정수)를 입력하시요: ";
	cin >> n;

	for(i = 1; i < n; i++) f *= i;
	cout << n <<"! = " << f << endl;
	return 0;
}