본문 바로가기
CS/프로그래밍언어론

방송통신대학교 프로그래밍 언어론 요약 정리 및 연습 문제

by Renechoi 2023. 12. 5.

1. 프로그래밍 언어 소개

  1.  프로그램이란 컴퓨터가 수행할 명령어를 순서대로 나열해 둔 것이며, 프로그래밍 언어는 프로그램 작성에 사용되는 언어이다. 프로그래밍 언어는 컴퓨터가 수행할 수 있고 사람이 읽을 수 있는 형태로 계산을 나타내는 표기체계이다.
  2.  프로그래밍 언어는 말이 아닌 글 형태로 사용되고, 엄밀한 규칙에 따라 정의되며, 주로 기계에 명령을 전달하는 단방향 언어이다.
  3.  언어는 우리의 사고 능력과 밀접한 관련이 있으며 프로그래밍은 우리에게 체계적으로 생각하는 방법을 가르쳐 준다.
  4.  프로그래밍 언어의 기본적인 기능은 작성력과 가독성, 실행 가능성으로 요약할 수 있다.
  5.  프로그래밍 언어는 추상화, 모듈화를 지원한다.
  6.  프로그래밍 언어는 기계적, 구조적, 가변적이라는 특성을 지닌다.
  7.  프로그래밍 언어는 추상화 수준에 따라 저급언어부터 고급언어까지 다양한 스펙트럼으로 존재하는데, 고급언어란 기계에 독립적인 언어를 뜻한다.
  8.  프로그래밍 언어는 데이터, 연산, 명령어, 서브프로그램, 타입, 모듈 등으로 구성된다.
  9.  프로그래밍 언어는 구문론과 의미론을 통해 정의할 수 있다.
  10.  프로그래밍 언어를 선택할 때는 자신의 사전지식을 고려해야 하며 실제로 사용해 볼 수 있는 언어, 프로그램을 관리하기 쉬운 언어, 자신의 업무와 관련 있는 언어, 자신이 아는 언어와 유사한 언어를 선택하는 것이 바람직하다.
  11.  프로그래밍을 배우기 위해서는 ‘눈보다 손’으로 학습해야 하고, 그림을 통해 생각하면 더 편리하며, 간단한 프로그램부터 시작하여 복잡한 프로그램으로 점진적으로 변경하는 것이 좋다.
  12.  프로그래밍 언어론을 배우는 이유는 새로운 언어를 쉽게 배우기 위해서, 또 내가 사용하는 언어를 더 잘 이해하기 위해서, 나아가 궁극적으로 현명한 언어 설계자가 되기 위해서이다.

2. 프로그래밍 언어의 발전 및 동작원리

  1. 저장 프로그램 방식의 에드박이 등장하면서 프로그램이라는 개념이 등장하게 되었다.
  2. 1950년대 초기 프로그래밍 언어로 Fortran은 수식 계산, 변수, 대입문, 함수, 제어문의 초기 형태를, Algol은 제어 구조 개념을, LISP는 함수형 언어 개념을 소개하였다.
  3. 1960년대 발표된 Cobol은 레코드를 통한 자료 구조 개념을 제시하였다. BASIC은 교육용 언어로서 큰 인기를 끌었으며 Simula는 객체지향 개념을 처음 소개하였다.
  4. 1970년대 가장 영향력이 높은 프로그래밍 언어는 C이다. Pascal은 구조화 프로그래밍의 교육용 언어로 자리잡았고, 그 외 다양한 패러다임의 언어가 등장하였다.
  5. 1980년대에는 객체지향 개념이 더욱 견고해지고 다양한 언어 표준이 이루어졌다.
  6. 1990년대에는 Java와 JavaScript, Python을 필두로 하여 프로그래밍 언어의 대중화가 시작되었다.
  7. 인터프리터는 고급언어 프로그램으로 작성된 문장을 하나씩 읽어서 수행한다. 컴파일러는 고급언어 프로그램을 기계어로 미리 번역한다. 하이브리드 구현은 고급언어 프로그램을 중간 코드 형태로 컴파일하고 이 중간 코드를 가상기계 상에서 해석한다.
  8. 프로그래밍 언어의 요구사항을 효과적으로 지원하기 위해 따라야 하는 프로그래밍 언어 설계 원칙으로는 규칙성, 추상화 지원, 복잡도 지원 등을 들 수 있다.
  9. 프로그래밍 언어의 평가 기준 중 대표적인 것으로 작성력, 가독성, 신뢰성, 직교성, 일관성, 확장성, 효율성, 유연성, 이식성 등을 들 수 있다.
  10. 프로그래밍 언어를 선택할 때는 언어 사용 커뮤니티가 활발하고 호의적인지, 언어의 특정 응용 분야가 있는지, 새로운 프로그래밍 패러다임을 지원하는지 등을 고려해야 한다.

3. 프로그래밍 언어 패러다임

  1. 프로그램을 작성하는 전형적인 방식을 프로그래밍 패러다임이라고 부른다.
  2. 명령형 프로그래밍 패러다임에서 프로그램은 특정 작업을 수행하기 위해 명령어가 나열된 것이다. 컴퓨터 하드웨어의 속성을 그대로 반영한 형태의 패러다임이다.
  3. 절차형 프로그래밍 패러다임은 문제를 해결하기 위한 절차를 서브루틴 단위의 절차로 구현하는 방식의 패러다임으로, 프로그램을 절차의 집합으로 간주한다.
  4. 함수형 프로그래밍 패러다임에서는 데이터를 값으로 간주하고, 주어진 데이터로부터 새로운 값을 생성하는 함수에 초점을 맞추어 프로그램을 작성한다.
  5. 논리 프로그래밍 패러다임에서는 문제의 조건을 논리식으로 표현하고 이 식을 바탕으로 어떤 사실을 입증해 나가는 방식으로 프로그램을 수행한다. 논리 프로그래밍 패러다임은 선언적 프로그래밍 패러다임의 일종이다.
  6. 객체지향 프로그래밍 패러다임은 데이터와 관련 연산을 합쳐 객체로 모형화하고, 객체 사이의 상호작용을 통해 프로그램을 수행하는 프로그래밍 패러다임이다.
  7. 프로그래밍 패러다임의 변화 배경으로는 응용 도메인의 변화, 프로그램 구성 방식의 변화, 계산 모델의 변화 등을 들 수 있다.
  8. 하나의 프로그래밍 언어가 한 패러다임만 지원하는 것은 아니다.
  9. 구조화 프로그래밍은 goto 논란으로부터 촉발되었는데 goto 없이 프로그램을 작성하는 패러다임이다.
  10. 다양한 프로그래밍 패러다임은 서로 배타적이라기보다 상호 보완적인 것으로 보는 것이 바람직하다.

4. 구문론과 의미론

  1. 프로그래밍 언어는 문장을 정확하게 이해할 수 있도록 명확한 구문과 그 의미가 정의되어야 한다. 이를 프로그래밍 언어의 형식적 정의라 하며 이는 다시 구문론과 의미론으로 나눌 수 있다.
  2. 구문론은 프로그램의 표면적인 구조를 정의하는 것으로, 프로그램 작성 시 어떤 형태로 작성해야 하는지를 기술한다.
  3. 의미론은 프로그램의 내용적인 효과를 정의하는 것으로, 프로그램 실행 시 어떤 일이 일어나는지 그 의미를 기술한다.
  4. 프로그래밍 언어에서 구문은 문맥 자유 문법으로 표현된다. 문맥 자유 문법이란 문맥에 영향을 받지 않는 문법을 의미한다.
  5. 문맥 자유 문법을 표현하는 방법으로 BNF, EBNF, 구문 도표가 있다.
  6. 프로그래밍 언어에서 의미는 자연어로 표현되는 경우가 많지만, 엄밀한 표현을 위한 형식 의미론도 존재한다.
  7. 형식 의미론에서 다루는 표현 방법으로는 속성 문법, 기능적 의미론, 표기적 의미론, 공리적 의미론이 있다.

5. 구문 분석

  1. 프로그램의 분석은 크게 어휘 분석과 구문 분석으로 나눌 수 있다.
  2. 어휘 분석을 통해 프로그램에서 사용된 단어인 토큰을 구별해 낸다. 토큰의 종류에는 연산자, 구분자, 식별자, 예약어 등이 있다.
  3. 식별자는 변수나 함수 등의 이름을 나타내는 토큰이다.
  4. 예약어는 프로그래밍 언어 자체에 정의되어 포함된 토큰으로 사용자 재정의가 불가능하다.
  5. 유도는 구문 규칙을 이용하여 주어진 프로그램을 만들어 내는 과정으로, 유도가 가능하다면 주어진 프로그램은 문법적 오류가 없다.
  6. 파스 트리는 유도를 트리 형태로 나타낸 것으로, 루트 노드는 시작 비단말 기호, 단말 노드는 단말 기호가 된다. 단말 노드를 왼쪽부터 오른쪽으로 차례로 나열하면 주어진 프로그램이 된다.
  7. 주어진 표현에 대한 파스트리가 존재하면 구문에 부합하는 표현이지만, 파스 트리가 존재하지 않으면 오류가 있는 표현이다.
  8. 모호한 문법은 동일한 표현에 대해 서로 다른 파스 트리가 만들어지는 문법으로, 하나의 프로그램이 서로 다른 결과를 도출할 수 있는 위험을 내포하고 있다.
  9. 모호한 문법은 문법을 명확하게 변경하여 모호성을 제거해야 한다.

6. 프로그래밍 언어의 구현

  1. 프로그래밍 언어를 구현하기 위해서는 먼저 언어를 정의해야 하며, 이는 프로그램의 형태를 정의하는 구문론과 프로그램의 수행 의미를 정의하는 의미론으로 정의할 수 있다.
  2. 프로그래밍 언어 구현은 함수 모델로 해석할 수 있다.
  3. 전통적인 프로그래밍 언어는 기계의 단순한 명령어를 확대하는 형태로 구현한다. 그러나 새로운 패러다임의 프로그래밍 언어는 구현 모델을 추상기계로 만들고 이를 징검다리로 삼는 형태로 구현한다.
  4. 추상기계와 가상기계의 차이는 해당 기계의 구체적인 구현물이 있는지 여부이다.
  5. 컴파일러의 구현 단계는 크게 분석 단계와 생성 단계로 나눌 수 있다. 프로그래밍 언어에 의존적인 분석 단계를 전단부, 목적 기계에 의존적인 생성 단계를 후단부라고 부른다.
  6. 인터프리터를 구현할 때도 컴파일러의 전단부에 해당하는 분석 단계는 그대로 거친다. 하지만 전단부에서 생성된 중간 표현을 목적 코드로 바꾸는 대신 중간 표현을 순회하며 프로그램을 실행한다.
  7. 구문 트리와 중간 표현 외에 프로그래밍 언어 구현에 필요한 자료 구조로는 심볼 테이블과 환경을 들 수 있다.
  8. 언어 구현 시에는 프로그램이 실행되는 환경인 실행 환경도 고려해야 한다.
  9. 어휘 분석기는 어휘의 토큰과 속성을 분석하며, 구문 분석기는 토큰을 이용하여 구문 트리를 구성한다. 구문 트리는 파스 트리와 추상 구문 트리의 두 가지 형태가 있다.

7. 변수와 바인딩

  1. 변수란 데이터를 저장하거나 나중에 사용할 수 있도록 메모리를 추상화한 것이다.
  2. 변수의 속성에는 변수명, 타입, 주소, 값이 있다. 변수의 값은 수행시간 동안 바뀔 수 있다.
  3. 바인딩이란 언어 구성 요소의 속성이 구체적으로 결정되는 것을 의미한다.
  4. 바인딩 시각이란 언어 구성 요소의 속성이 결정되는 시점을 의미한다. 바인딩 시각은 크게 정적 바인딩과 동적 바인딩으로 구분된다.
  5. 변수의 바인딩은 변수의 속성이 구체적으로 결정되는 것을 의미한다. 즉, 변수명 바인딩, 타입 바인딩, 주소 방인딩, 값 바인딩이 해당된다.
  6. 변수의 변수명 바인딩 방법과 타입 바인딩 방법에는 명시적 선언과 묵시적 선언이 있다.
  7. 변수의 정적 타입 바인딩은 컴파일 시점에 구문 분석을 통해 타입을 판단하고, 동적 타입 바인딩은 수행 시점에 대입할 값에 맞추어 타입을 판단하기에 계속 변할 수 있다.
  8. 변수의 수명은 변수가 메모리를 할당받고 있는 기간이다.
  9. 변수의 주소 바인딩 방법에는 자동 할당과 수동 할당이 있다.
  10. 변수의 정적 주소 바인딩은 로드 시점에 정적 세그먼트의 주소를 바인딩하고, 동적 주소 바인딩은 수행 시점에 동적 세그먼트의 주소를 바인딩한다.
  11. 정적 주소 바인딩을 하는 변수를 정적 변수, 동적 주소 바인딩을 하는 변수를 동적 변수라고 한다. 동적 변수는 스택 동적 변수와 힙 동적 변수로 나누어진다.

8. 변수의 영역

  1. 변수의 영역이란 프로그램에서 변수를 사용할 수 있는 범위를 의미한다.
  2. 블록은 영역을 구분해 주는 단위로, 프로그램 문장들의 묶음이면서 그 안에서 변수 선언이 가능하다.
  3. 지역변수는 블록 안에서 선언된 변수이고, 비지역변수는 블록 밖에서 선언되었지만 블록 안에서 사용될 수 있는 변수이다.
  4. 참조 환경은 한 위치에서 사용할 수 있는 모든 변수의 모음으로, 해당위치의 모든 지역변수와 모든 비지역변수로 구성된다.
  5. 영역 규칙은 변수의 참조 위치를 결정하는 방법이다. 특히 현재 블록에서 선언되지 않은 자유변수에 대해 어디에서 선언된 비지역변수인지 혹은 오류인지 확인한다.
  6. 정적 영역 규칙은 블록들의 정적 내포 관계를 이용하여 변수의 참조 위치를 찾는 방법으로, 컴파일 시점에 결정할 수 있다. 동적 영역 규칙은 블록들의 동적 내포 관계를 이용하며, 수행 시점에 결정할 수 있다.
  7. 영역 구멍은 비지역변수가 같은 이름의 지역변수 때문에 보이지 않는 영역을 의미한다.
  8. 정적 영역 규칙은 동적 영역 규칙에 비해 안정적이고 수행 속도가 빨라서 대부분의 언어에서 사용한다.
  9. 전역변수는 어떤 블록에도 포함되지 않는 곳에서 선언된 변수로 영역은 프로그램 전체가 된다.
  10. 이름 공간은 관련성이 높은 변수와 함수를 하나의 묶음으로 관리하는 영역으로, 변수명처럼 영역 자체의 이름을 갖는다. C++는 이름 공간을 지원한다.

9. 타입

  1. 타입은 데이터 집합과 연산 집합의 결합이다. 데이터 집합은 처리 대상이 되는 데이터들의 집합이고, 연산 집합은 해당 데이터에 적용 가능한 연산의 집합이다.
  2. 프로그램 내 모든 연산 및 함수에 대해 적용 전후의 타입이 연산 및 함수의 정의와 일치한다면 그 프로그램은 타입 안전하다고 한다.
  3. 강타입 언어는 프로그램에 존재하는 모든 타입 오류를 검출해 내고, 약타입 언어는 일부 타입 오류를 허용한다. 무타입 언어는 타입 선언문이 없고 어떤 대상의 타입이 계속 바뀔 수 있다.
  4. 타입의 정의에 사용자가 개입할 수 있는지 여부에 따라 원시타입과 사용자정의타입으로 분류한다.
  5. 데이터 요소의 형태에 따라 단순타입과 복합타입으로 분류한다. 단순타입에는 정수형, 실수형, 문자형, 논리형, 열거형이 있다.
  6. 정수형은 정수 데이터를 다루는 타입으로, 데이터 집합에 포함되는 정수의 범위에 따라 다양한 타입이 존재한다. 연산 집합에는 사칙연산, 나머지 연산, 비트 연산, 관계 연산 등이 포함된다.
  7. 실수형은 실수 데이터를 다루는 타입으로, 데이터 집합에 포함되는 실수의 범위는 지수부와 가수부의 범위에 따라 달라진다. 연산 집합에는 사칙연산, 관계 연산 등이 포함된다.
  8. 문자형은 하나의 문자 데이터를 다루는 타입으로, 데이터 집합에 포함되는 문자의 범위는 ASCII 코드, 유니코드 등에 따라 달라진다. 연산 집합에는 관계 연산 등이 포함된다.
  9. 논리형은 참과 거짓의 두 논리 데이터를 다루는 타입으로, 연산 집합에는 논리 연산이 포함된다.
  10. 열거형은 순서 관계가 있는 이름들을 데이터로 다루는 타입으로 사용자정의타입이다. 데이터 집합에는 사용자가 지정한 이름들이, 연산 집합에는 관계 연산 등이 포함된다.

10. 복합타입

  1. 배열은 동질형 데이터의 모음으로 구성된 타입으로, 원소는 첨자로 구별한다. 차원은 배열에 사용되는 첨자의 개수이다.
  2. 배열은 첨자를 통해 원소의 주소를 쉽게 찾아야 한다. 2차원 이상의 배열은 저장 순서에 따라 행우선 저장 방법과 열우선 저장 방법이 있다.
  3. 문자열형은 문자열 데이터를 다루는 타입으로, 데이터 집합은 모든 문자열이 모인 집합이다. 연산 집합에는 언어에 따라 대입 연산, 연결 연산 등이 포함된다.
  4. 연관배열은 동질형 데이터의 순서 없는 모음으로 구성된 타입으로, 원소는 키로 구별한다. 데이터 집합은 모든 키 타입 데이터와 원소 타입 데이터의 쌍을 포함한다. 연산 집합에는 개별 원소에 대한 연산들이 포함된다.
  5. 구조체는 다양한 타입의 데이터의 모음으로 구성된 타입으로, 원소는 이름으로 구별한다. 데이터 집합은 원소의 개수와 각 원소의 타입에 따라 다양하게 존재한다. 연산 집합에는 초기화, 대입 연산 등이 포함된다.
  6. 공용체는 저장공간을 공유하는 데이터의 모음으로 구성된 타입으로, 한 원소의 값이 바뀌면 다른 원소들의 값도 영향을 받는다. 원소는 이름으로 구별하며, 데이터 집합은 각 원소의 타입에 따라 다양하게 존재한다. 연산 집합은 개별 원소 타입의 연산 집합을 따른다.
  7. 포인터형은 특정 데이터가 저장되는 주소 자체를 데이터로 다루는 타입으로, 특정 데이터의 타입은 사용자가 지정한다. 데이터 집합은 가용한 범위의 주소를 포함하며, 연산 집합에는 대입 연산, 덧셈, 뺄셈 연산 등이 포함된다.
  8. 참조형은 사용자가 지정하는 타입의 데이터가 저장된 주소 자체를 자신의 주소로 사용하는 타입이다. 데이터 집합과 연산 집합은 지정한 타입을 따른다.

11. 수식

  1. 수식이란 피연산자와 연산자로 구성되어 하나의 값을 나타내는 표현이다.
  2. 수식은 값을 나타내는 표현이며 문장은 처리를 나타내는 표현이다.
  3. 산술 연산자에는 사칙 연산자 외에도 언어에 따라 나머지 연산자, 부호 연산자 등이 포함된다.
  4. 피연산자의 개수에 따라 단항 연산자와 이항 연산자가 있고, 언어에 따라 삼항 연산자도 있다.
  5. 하나의 수식에 여러 연산자가 사용되는 경우 정해진 우선순위에 따라 연산을 수행한다. 같은 우선순위의 연산자들이 섞여 있는 경우에는 결합방향에 맞춰 연산을 수행한다.
  6. 결합방향에는 좌결합과 우결합이 있다. 같은 우선순위의 연산자들 중 좌결합은 가장 왼쪽 연산자부터, 우결합은 가장 오른쪽 연산자부터 연산을 수행하는 방법이다.
  7. 타입 변환은 주어진 타입의 값을 다른 타입의 값으로 변환하는 것으로, 묵시적 타입 변환과 명시적 타입 변환이 있다.
  8. 관계 연산자는 2개의 피연산자를 서로 비교하여 둘 사이의 관계가 관계 연산자와 일치하는지 여부를 확인한다. 관계 연산의 결과 값은 참 또는 거짓이다.
  9. 논리 연산자에는 논리곱 연산자, 논리합 연산자, 부정 연산자 등이 포함된다. 논리 연산의 피연산자와 결과 값은 참 또는 거짓이다.
  10. 논리 연산의 경우 단락 평가를 통해 모든 논리 연산을 수행하지 않고도 수식의 값을 얻을 수 있다.

12. 문장

  1. 문장이란 처리를 나타내는 표현으로, 선언문과 실행문으로 구분할 수 있다.
  2. 선언문은 변수나 서브프로그램을 이용할 수 있도록 준비를 해 준다.
  3. 실행문은 실제적으로 변수도 이용하고 서브프로그램도 이용하며 데이터를 처리한다. 실행문에는 변수의 값을 변경하는 대입문과 프로그램의 수행 흐름을 제어하는 제어문이 있다.
  4. C, C++, Java에서 대입문은 변수에 대입된 값을 나타내는 수식에 쌍반점을 찍어 만든 문장이다.
  5. C++는 조건 연산자를 이용하여 값이 대입될 변수를 선택할 수도 있다.
  6. C, C++, Java는 다양한 복합 대입 연산자를 지원한다. 또한 단항 대입 연산자도 있다.
  7. 대입문에서의 묵시적 타입 변환은 대입할 값의 타입을 변수의 타입으로 변환한다. 단, Java는 확대변환인 경우만 묵시적 타입 변환이 일어나고, 축소변환이 필요한 경우는 명시적 타입 변환을 이용해야만 오류가 발생하지 않는다.
  8. 조건문은 조건에 따라 서로 다른 처리를 하도록 제어하는 문장이다.
  9. 반복문은 원하는 문장을 반복해서 수행하도록 제어하는 문장이다.
  10. while문은 반복문장이 한 번도 수행되지 않을 수도 있지만, do-while문은 반복문장이 적어도 한 번은 수행하게 된다.

13. 서브프로그램 개요

  1. 서브프로그램은 독자적인 입력과 출력을 갖춘 프로그램 조각으로 모듈화 프로그래밍을 지원하기 위해 기본적으로 필요한 기능이다.
  2. 서브프로그램으로 들어가는 입구는 일반적으로 하나인 반면 출구는 여러 곳이 될 수 있다.
  3. 서브프로그램은 반환값의 유무에 따라 프로시저와 함수로 분류할 수 있다. 프로그래밍 언어 개발 초기에는 반복적으로 사용되는 명령어 묶음을 서브루틴이라고 불렀다.
  4. 서브프로그램의 매개변수 개수, 순서, 타입을 매개변수 프로파일이라고 부르며 시그니처라고도 한다.
  5. 서브프로그램의 매개변수 프로파일과 함수 반환 타입을 합쳐 서브프로그램 프로토콜이라고 부른다. 정적 타입 언어의 경우 서브프로그램의 호출 전에 서브프로그램 프로토콜이 선언되어 있어야 한다.
  6. 외부로부터 전달될 정보를 받기 위해 서브프로그램 정의 부분에서 선언한 변수를 매개변수라 하고, 서브프로그램 호출 시 매개변수로 전달될 의도로 사용된 수식을 인수라고 한다. 매개변수를 형식인수(형식매개변수), 인수를 실인수(실매개변수)라고도 한다.
  7. 인수 전달의 의미적 모델로는 입력, 출력, 입출력 모드 세 가지가 있고, 개념적 모델로는 값 전달, 참조 전달이 있다. 구현 모델로는 값 전달, 결과 전달, 값-결과 전달, 참조 전달, 이름 전달이 있다.
  8. 입출력 모드 인수를 지원하기 위한 참조 전달은 별칭 문제를 발생시킬 수 있는데, 값-결과 전달을 이용하면 별칭 문제가 해결된다.
  9. 여러 용도로 가능할 수 있는 서브프로그램을 범용 서브프로그램이라고 하며 이는 다형 서브프로그램과 다목적 서브프로그램으로 구성된다.
  10. 모듈화 및 협업을 위해서는 분리 컴파일이나 독립 컴파일 기능이 필요하다.

14. 서브프로그램 구현

  1. 서브프로그램 호출과 복귀를 합쳐 서브프로그램 연결이라고 부르며 이때 제어 흐름뿐 아니라 자료 흐름도 관리해야 한다. 자료 흐름을 관리하기 위해 활성 레코드를 사용한다.
  2. 활성 레코드에는 서브프로그램의 데이터뿐 아니라 호출자의 상태, 복귀 주소, 반환값, 각종 관리 데이터가 저장된다.
  3. 초기 언어에서는 정적 활성 레코드 할당 방법을 사용했으나 이는 재귀호출이 불가능하다. 현재는 대부분 동적 활성 레코드를 사용한다.
  4. 활성 레코드에는 영역 규칙을 구현하기 위해 동적 링크와 정적 링크가 주로 사용된다.
  5. 정적 링크가 연결된 정적 체인은 정적 영역 규칙을 구현하기 위해 사용되고, 동적 링크가 연결된 동적 체인은 동적 영역 규칙을 구현하기 위해 사용된다.
  6. 정적 체인을 거슬러 올라가는 부담을 줄이기 위해서 디스플레이를 활용할 수 있다.
  7. 동적 영역 규칙에서 모든 변수에 대한 정보를 한곳에서 관리하며 변수를 참조하는 방법을 얕은 참조라고 한다. 얕은 참조에는 변수 스택 방법과 중앙 테이블 방법이 있다.
  8. 과거 민감 서브프로그램이란 이전의 호출 내용을 기억하는 서브프로그램이다.
  9. 코루틴이란 여러 개의 진입 지점을 스스로 관리하는 서브프로그램을 뜻한다. 코루틴은 ‘호출된다’고 하지 않고 ‘재개된다’고 한다.

15. 객체지향과 다형성

  1. 추상화란 복잡한 대상을 간략하게 나타내는 것을 뜻하는데, 이는 프로그래밍에 필수적인 작업이다.
  2. 프로그래밍 언어에서 제공하는 추상화 종류는 크게 제어 추상화와 자료 추상화로 나눌 수 있다.
  3. 여러 요소를 하나의 단위로 묶을 수 있는 기능을 캡슐화라 하고, 구현 세부 사항을 외부에 숨기고 인터페이스만 외부에 공개하는 기능을 정보 은닉이라고 부른다.
  4. 자료 집합과 적용 가능한 연산을 함께 선언한 타입을 추상 자료형이라고 한다.
  5. 객체란 특정 상태를 유지하며 외부 요구에 반응하는 행태를 보이는 대상을 추상화시킨 것이다.
  6. 객체에 따라 호출 메소드가 결정되도록 하기 위해서는 호출 메소드의 늦은 바인딩이 필요한데, 가상함수 테이블(VTab)로 늦은 바인딩을 구현한다.
  7. 여러 타입의 데이터를 같은 이름으로 처리할 수 있는 특성을 다형성이라고 한다.
  8. 다중 상속을 지원하면 다이아몬드 상속 문제가 발생한다.
  9. 객체를 직접 생성할 수 없을 정도로 극도로 추상화된 클래스를 추상 클래스라고 한다.
  10. 추상 클래스의 개념을 확장한 것으로 인터페이스와 트레잇을 들 수 있다.

연습 문제

1. 구문론이 아닌 프로그래밍 언어의 특징은 무엇인가?

  1. 프로그램의 표면적 구조를 정의한다.
  2. 문맥 자유 문법을 사용한다.
  3. 프로그램 실행 시 어떤 일이 일어나는지를 정의한다.
  4. BNF, EBNF, 구문 도표로 표현한다.

정답: 3

해설: 구문론은 프로그램의 표면적 구조를 정의하지만, 프로그래밍 언어의 의미론은 프로그램 실행 시 어떤 일이 일어나는지를 정의한다.

2. 어휘 분석의 목적은 무엇인가?

  1. 프로그램을 문법적으로 올바른지 검사한다.
  2. 프로그램에서 사용된 단어인 토큰을 구별한다.
  3. 프로그램의 실행 효과를 정의한다.
  4. 프로그램의 실행 환경을 설정한다.

정답: 2

해설: 어휘 분석은 프로그램에서 사용된 단어인 토큰을 구별하는 과정이다.

3. 프로그래밍 언어의 구현에서 추상기계와 가상기계의 차이점은 무엇인가?

  1. 추상기계는 실제 구현물이 없고 가상기계는 실제 구현물이 있다.
  2. 추상기계는 분석 단계에, 가상기계는 생성 단계에 사용된다.
  3. 추상기계는 컴파일러에 의존적이고, 가상기계는 인터프리터에 의존적이다.
  4. 추상기계는 함수 모델로 해석되고, 가상기계는 형식 의미론으로 해석된다.

정답: 1

해설: 추상기계는 구체적인 구현물이 없는 반면, 가상기계는 실제로 구현된 구체적인 구현물을 가진다.

4. 변수의 타입 바인딩 방법 중 정적 타입 바인딩의 특징은 무엇인가?

  1. 실행 시점에 타입을 결정한다.
  2. 컴파일 시점에 타입을 결정한다.
  3. 수행 시점에 계속 변할 수 있다.
  4. 사용자가 타입을 지정한다.

정답: 2

해설: 정적 타입 바인딩은 컴파일 시점에 타입이 결정되며, 이후에는 변경되지 않는다.

5. 변수의 영역에서 정적 영역 규칙의 특징은 무엇인가?

  1. 실행 시점에 결정된다.
  2. 동적 내포 관계를 이용한다.
  3. 블록들의 정적 내포 관계를 이용한다.
  4. 변수 스택 방법을 사용한다.

정답: 3

해설: 정적 영역 규칙은 블록들의 정적 내포 관계를 이용하여 변수의 참조 위치를 결정한다.

6. 타입의 분류에서 복합타입에 해당하지 않는 것은 무엇인가?**

  1. 배열
  2. 문자열형
  3. 정수형
  4. 구조체

정답: 3

해설: 복합타입은 다양한 타입의 데이터를 포함하는 타입을 의미한다. 정수형은 단순타입에 속한다.

7. 다음 중 문장과 수식의 차이점은 무엇인가?

  1. 문장은 처리를 나타내고, 수식은 값만을 나타낸다.
  2. 문장은 선언문과 실행문으로 구분되고, 수식은 피연산자와 연산자로 구분된다.
  3. 문장은 프로그램의 실행 효과를 정의하고, 수식은 구문의 구조를 정의한다.
  4. 문장은 언어의 의미를 정의하고, 수식은 언어의 형태를 정의한다.

정답: 1

해설: 문장은 프로그램의 처리를 나타내는 표현이고, 수식은 하나의 값을 나타내는 표현이다.

8. 서브프로그램 연결 시 사용되는 활성 레코드에 저장되지 않는 것은 무엇인가?

  1. 호출자의 상태
  2. 복귀 주소
  3. 서브프로그램의 데이터
  4. 프로그램의 실행 환경

정답: 4

해설: 활성 레코드에는 서브프로그램의 데이터, 호출자의 상태, 복귀 주소 등이 저장되지만, 프로그램의 실행 환경은 저장되지 않는다.

9. 객체지향 프로그래밍의 특징 중 캡슐화에 해당하지 않는 것은 무엇인가?

  1. 여러 요소를 하나의 단위로 묶는다.
  2. 구현 세부 사항을 외부에 숨긴다.
  3. 호출 메소드의 늦은 바인딩을 지원한다.
  4. 인터페이스만 외부에 공개한다.

정답: 3

해설: 캡슐화는 여러 요소를 하나의 단위로 묶고 구현 세부 사항을 숨기는 것이지만, 호출 메소드의 늦은 바인딩은 다형성과 관련된 특징이다.

10. 논리 연산자 중 부정 연산자(NOT)의 기능은 무엇인가?

  1. 두 피연산자가 모두 참일 때 참을 반환한다.
  2. 두 피연산자 중 하나라도 참이면 참을 반환한다.
  3. 참을 거짓으로, 거짓을 참으로 변환한다.
  4. 두 피연산자의 참/거짓 관계를 비교한다.

정답: 3

해설: 부정 연산자(NOT)는 참인 피연산자를 거짓으로, 거짓인 피연산자를 참으로 변환하는 기능을 한다.

11. 가비지 컬렉션의 주요 목적은 무엇인가?

  1. 메모리 할당을 최적화한다.
  2. 사용하지 않는 메모리를 자동으로 회수한다.
  3. 프로그램의 실행 속도를 향상시킨다.
  4. 메모리 누수를 방지한다.

정답: 2

해설: 가비지 컬렉션은 사용하지 않는 메모리를 자동으로 회수하여 메모리 관리를 도와준다.

12. 다형성을 구현하는 주요 방법은 무엇인가?

  1. 오버로딩
  2. 오버라이딩
  3. 캡슐화
  4. 추상화

정답: 1, 2

해설: 다형성은 하나의 인터페이스에 여러 객체가 대응될 수 있도록 하는 것으로, 오버로딩(같은 이름의 서로 다른 메소드)과 오버라이딩(상속받은 메소드의 재정의)을 통해 구현된다.

13. 프로그래밍 언어에서 동적 타입 결정의 특징은 무엇인가?

  1. 컴파일 시점에 타입을 결정한다.
  2. 실행 시점에 타입을 결정한다.
  3. 변수 선언이 필요하지 않다.
  4. 실행 시 타입 변경이 불가능하다.

정답: 2, 3

해설: 동적 타입 결정은 실행 시점에 타입이 결정되며, 이는 변수 선언 없이도 가능하다.

14. 컴파일러와 인터프리터의 주요 차이점은 무엇인가?

  1. 컴파일러는 전체 코드를 한 번에 번역한다.
  2. 인터프리터는 코드를 한 줄씩 실행한다.
  3. 컴파일러는 실행 파일을 생성한다.
  4. 인터프리터는 빠른 실행을 지원한다.

정답: 1, 2, 3

해설: 컴파일러는 전체 코드를 한 번에 번역하여 실행 파일을 생성하는 반면, 인터프리터는 코드를 한 줄씩 실행하며, 빠른 실행보다는 유연한 코드 수정이 장점이다.

15. 객체지향 프로그래밍에서 상속의 주요 목적은 무엇인가?

  1. 코드 재사용
  2. 메모리 절약
  3. 실행 속도 향상
  4. 데이터 보호

정답: 1

해설: 상속은 코드 재사용성을 높이고, 클래스 간의 관계를 명확히 하는데 주로 사용된다.

16. 런타임 오류와 컴파일 타임 오류의 차이점은 무엇인가?

  1. 런타임 오류는 프로그램 실행 중 발생한다.
  2. 컴파일 타임 오류는 컴파일 과정에서 발생한다.
  3. 런타임 오류는 주로 논리적 오류에 의해 발생한다.
  4. 컴파일 타임 오류는 구문 오류에 의해 발생한다.

정답: 1, 2, 4

해설: 런타임 오류는 프로그램 실행 중 발생하며, 컴파일 타임 오류는 컴파일 과정에서 구문 오류 등으로 발생한다.

17. 렉시컬 스코핑과 다이나믹 스코핑의 차이점은 무엇인가?

  1. 렉시컬 스코핑은 컴파일 시 결정된다.
  2. 다이나믹 스코핑은 실행 시 결정된다.
  3. 렉시컬 스코핑은 프로그램의 텍스트 구조에 의존한다.
  4. 다이나믹 스코핑은 호출 스택에 의존한다.

정답: 1, 2, 3, 4

해설: 렉시컬 스코핑은 컴파일 시 프로그램의 텍스트 구조에 따라 결정되며, 다이나믹 스코핑은 실행 시 호출 스택에 따라 결정된다.

18. 프로그래밍 언어에서 '정적 링크(Static Link)'의 용도는 무엇인가?

  1. 동적 메모리 할당을 관리한다.
  2. 서브프로그램의 지역 변수에 접근한다.
  3. 서브프로그램 간 정적 영역 규칙을 구현한다.
  4. 프로그램의 실행 환경을 설정한다.

정답: 3

해설: 정적 링크는 서브프로그램 간 정적 영역 규칙을 구현하는 데 사용된다. 이는 서브프로그램이 다른 서브프로그램의 변수에 접근할 수 있도록 하는 링크이다.

19. 인터프리터에서 '중간 표현'의 역할은 무엇인가?

  1. 소스 코드를 바이너리 코드로 변환한다.
  2. 소스 코드를 분석하고 구조화한다.
  3. 실행 시 실제 기계어로 변환한다.
  4. 프로그램 실행을 위해 소스 코드를 순회한다.

정답: 4

해설: 인터프리터에서 중간 표현은 프로그램 실행을 위해 소스 코드를 순회하는 역할을 한다. 이 과정에서 프로그램이 실행되며, 실제 기계어로의 변환은 발생하지 않는다.

20. 프로그래밍 언어에서 '디스플레이(Display)'의 목적은 무엇인가?

  1. 사용자 인터페이스를 제공한다.
  2. 정적 영역 규칙의 효율을 개선한다.
  3. 프로그램의 출력을 화면에 표시한다.
  4. 동적 영역 규칙을 관리한다.

정답: 2

해설: 디스플레이는 정적 영역 규칙의 효율을 개선하기 위해 사용된다. 이는 정적 링크를 통한 변수 접근 시, 정적 체인을 통한 탐색 과정을 최적화하는 데 도움을 준다.

21. '코루틴(Coroutine)'의 특징 중 올바른 것은?

  1. 단일 진입 지점을 가진다.
  2. 여러 진입 지점을 가진다.
  3. 항상 메인 프로그램에 종속된다.
  4. 재귀 호출이 불가능하다.

정답: 2

해설: 코루틴은 여러 진입 지점을 가지며, 이를 통해 다양한 지점에서 실행을 중단하고 재개할 수 있다. 이는 코루틴이 독립적으로 여러 작업 흐름을 관리할 수 있음을 의미한다.

반응형