티스토리 뷰



정보올림피아드에 출전하고 싶은 자녀를 둔 부모 입장에서 지역 예선 기출문제를 받아보면 어떻게 도와주어야 할지 난감한 것이 사실입니다. 2014년도까지만 해도 이건 진짜 천재들이나 풀수있겠다 싶은 문제들만 수두룩했습니다. 그런데, 2015년 기출문제를 살펴보니 이제 C언어를 기초부터 탄탄한게 준비하고 집중력있게 사고력을 키운 친구들이라면 충분히 풀수 있는 문제들도 많이 출제되었습니다. 맞는 방향이 아닌가 싶습니다. 2016년의 출제 방향이 어떻게 바뀔지 모르겠지만 C언어 하나라도 제대로 공부한 사람인지를 검증하고 사고력을 묻는 문제들이 지속적으로 출제되었으면 하는 바램입니다. 그래야 경진대회를 준비하는 과정이 의미있고, 탈락한 친구들도 C언어 하나는 확실하게 익힐 수 있으니 말입니다. 

이런 배경하에 2015년 기출 문제를 중심으로 C언어에 대한 기초부터 차례대로 다루는 글을 써볼까 합니다. 문제를 푸는 내용을 중심으로 다루지만 그 과정에서 C언어에 대한 이해를 돕는 글입니다.

16. 다음 프로그램에서 출력되는 값은 얼마인가?
    int a, i, j;
    for (i = 0; i < 10; i++)
    for (j = 0; j < 5; j++)
    a = i + j;
    printf("%d", a);
① 11 ② 12 ③ 13 ④ 14 ⑤ 15

이 문제는 C언어의 문장(Statement) 개념에 대한 정확한 이해가 필요합니다. C언어는 문장 기술이 매우 자유로운 프로그래밍 언어입니다. 한 줄에 한 문장을 기술할 필요도 없고 파이썬(Python) 언어 처럼 강제적인 들여쓰기(Indentation)를 요구하지도 않습니다. 

int a, i, j; for (i = 0; i < 10; i++)for (j = 0; j < 5; j++)a = i + j;printf("%d", a);

위의 코드처럼 문장들을 한 줄에 모두 기술해도 프로그램 빌드와 수행에는 전혀 문제가 되지 않습니다. 다만, 코드의 가독성(Readability)이 떨어지고 추후에 디버깅을 하거나 프로그램을 수정하기에도 좋지 않기 때문에 나름의 규칙을 가지고 줄을 나누고 들여쓰기를 하는 것입니다. 코드의 가독성(Readability)은 프로그램의 흐름과 내용을 쉽게 이해하고 파악할 수 있는가와 관련성이 있는 것으로 의미있는 변수명 사용, 적절한 띄어쓰기와 줄 나누기, 일관성 있는 들여쓰기와 블럭({}) 표시등으로 가독성을 높일 수 있습니다.

C언어 코드 작성 방법의 가장 기본은 모든 문장은 세미콜론(semi-colon, ;)으로 끝나고 여러개의 문장을 브레이스(brace, {})로 묶어 한 문장처럼 사용할 수 있다는 것입니다. 

for (시작 표현식; 비교 표현식; 증분표현식) 문장 

for 문의 문법에서 "문장"에 "a = i + j;" 같은 단일 문장이 올수도 있고 { }로 묶은 복합 문장이 올 수도 있습니다. 문제에서는 for (i = 0; i < 10; i++) 가 "문장"으로 "for (j = 0; j < 5; j++) a = i + j;"를 받은 것이므로 다음과 같은 코드로 바꾸어 작성할 수도 있습니다.

    for (i = 0; i < 10; i++) {
      for (j = 0; j < 5; j++) {
        a = i + j;
      }
    }

for, while, do ~ while, if ~ else 등의 문장에서 단문과 복합문은 동일한 문법 요소임을 꼭 기억해야 합니다. 본격적으로 위의 문제를 살펴보면 printf 문장은 두개의 겹쳐진 for 문이 모두 끝난 다음에 수행하므로 맨 마지막으로 수행하는 "a = i + j"를 찾으면 되는 간단한 문제입니다. for 문이 수행하는 동안 여러번 "a = i + j" 문장이 수행되지만 이전에 수행한 "a = i + j"는 의미가 없고 맨 마지막에 수행한 것만이 printf에 영향을 주는 의미가 있는 문장입니다. 

for문의 문법을 돌아보면 일단 for문을 시작할 때 "시작 표현식"을 수행합니다. "시작 표현식"에는 "i = 0" 처럼 루프 반복 여부를 검사할 변수에 초기값을 설정하는 문장을 기술하는데 "i = 0, j = 1"과 같이 콤마(,)로 여러 변수에 대한 초기화가 가능하고 아예 생략할 수도 있습니다. "for ( ; ; )" 처럼 for문 내의 모든 표현식을 생략하면 while(1)과 같은 무한 루프로 동작합니다. 

시작 표현식을 수행한 다음에는 비교 표현식을 살펴보고 표현식의 결과가 참(True)인 경우에만 루프("문장")를 수행합니다. C 언어에서는 " i < 10"과 같은 논리 비교외에도 0은 거짓(False)이고 0이 아닌 값은 모든 참으로 인식함을 기억해야 합니다. 다시 말해서 비교 표현식에 "i"만 기술하여 i의 값이 0이 아닌 동안 루프를 반복시킬수도 있습니다. 위의 문제의 경우 "i < 10"를 " i - 10"으로 해도 동일한 결과를 얻을 수 있습니다. "i < 10"가 i가 10보다 작을 동안 루프를 반복한다는 의미라면 " i - 10"는 i가 10이 아닐동안의 반복하라는 의미로 두가지 모두 변수 i가 10일때 루프를 중단하는 결과는 같다는 것입니다. 

증분 표현식은 루프를 모두 수행했거나 중간에 "continue"를 만났을 때 수행합니다. 많은 경우 증감 연산자인 ++, --를 사용하지만 +=, -= 연산자로 1인 아닌 값의 증감도 가능하고 콤마(,) 연산자로 여러 문장을 기술할 수도 있으며 산술 연산이 아닌 문장도 기술할 수 있습니다. 루프가 재시작할 때 수행하는 문장으로 이해하면 됩니다. 증분 표현식 수행 이후에는 다시 비교 표현식 확인으로 넘어갑니다.

위의 for문에서 i의 마지막 값은 9이고 j의 마지막 값은 4이므로 9 + 4 = 13입니다. 정답은 3번입니다. 이런 문제는 출제진이 준 선물이므로 잘 받아야 겠지요!


댓글
댓글쓰기 폼