기본 콘텐츠로 건너뛰기

방송대 프로그래밍언어론 14강: 활성 레코드와 정적·동적 체인

0-썸네일-요약노트-프로그래밍언어론-14강

방송대 프로그래밍언어론 14강: 활성 레코드와 정적·동적 체인

같은 함수를 재귀 호출해도 각 호출의 매개변수와 복귀 주소가 섞이지 않는 이유는 활성 레코드가 호출마다 만들어지기 때문입니다. 중첩 서브프로그램의 비지역변수를 찾을 때는 정적 링크와 동적 링크가 서로 다른 지도를 제공합니다. 이 글은 호출·수행·복귀의 시간축을 따라 활성 레코드를 추적하고, 정적 체인·동적 체인·디스플레이·얕은 참조 가운데 어떤 구현이 어떤 탐색 비용을 만드는지 설명합니다.

재귀 호출 세 개를 한 저장공간에 넣으면 무엇이 사라질까

fac(3)fac(2), fac(1), fac(0)을 차례로 호출합니다. 이때 매개변수 n과 “계산을 마친 뒤 돌아갈 위치”를 하나의 고정 공간에만 기록하면 새 호출이 이전 호출의 정보를 덮어씁니다. 그러면 fac(0)이 1을 반환해도 어느 호출로 돌아가 어떤 n을 곱해야 하는지 알 수 없습니다.

int fac(int n) {
    if (n == 0)
        return 1;
    return n * fac(n - 1);
}

해결책은 실행 중인 호출마다 별도의 데이터 묶음을 만드는 것입니다. 그 묶음이 활성 레코드 인스턴스입니다. 동일한 fac 코드가 실행되더라도 n=3인 호출과 n=2인 호출은 서로 다른 인스턴스를 사용합니다.

호출 단계현재 n기억할 작업복귀 후 계산
fac(3)3fac(2)의 결과를 기다림3 × 2 = 6
fac(2)2fac(1)의 결과를 기다림2 × 1 = 2
fac(1)1fac(0)의 결과를 기다림1 × 1 = 1
fac(0)0기본 조건에서 즉시 반환1 반환

판단 핵심: 재귀의 코드는 하나지만 동시에 살아 있는 호출은 여러 개입니다. 코드와 호출별 상태를 분리하고, 각 호출의 매개변수·지역변수·복귀 주소를 별도 활성 레코드 인스턴스에서 찾아야 합니다.

서브프로그램 연결은 호출과 복귀의 두 절차를 묶는다

서브프로그램 호출과 복귀를 합쳐 서브프로그램 연결이라고 합니다. 호출 시에는 호출자의 상태를 저장하고, 인수를 전달하며, 복귀 주소를 저장한 뒤 피호출자로 분기합니다. 복귀 시에는 출력·입출력 모드의 형식인수 값을 필요한 실인수에 복사하고, 함수라면 반환값을 전달하며, 호출자의 상태를 복원한 뒤 저장해 둔 주소로 돌아갑니다.

순서호출할 때복귀할 때
제어 준비호출자 상태와 복귀 주소 저장호출자 상태 복원
데이터 이동인수를 피호출자에 전달형식인수 출력과 함수 반환값 전달
제어 이동피호출자 코드로 분기복귀 주소를 따라 호출자로 이동

13강이 인수 전달의 의미와 구현 모델을 다뤘다면 14강은 그 정보와 복귀 제어를 실제 실행 저장공간에 어떻게 보관하는지 설명합니다. 인수만 옮긴다고 연결이 완성되는 것이 아닙니다. 돌아갈 주소와 호출자의 상태까지 보존해야 피호출자 수행 뒤 원래 계산을 계속할 수 있습니다.

활성 레코드 틀은 정적이고 인스턴스의 값은 동적이다

활성 레코드(activation record)는 수행 중인 서브프로그램의 데이터 부분을 저장하는 형태입니다. 호출자의 상태 정보, 매개변수, 지역변수, 함수 반환값, 복귀 주소와 영역 규칙을 위한 링크 등이 들어갈 수 있습니다.

활성 레코드 자체는 “어떤 필드를 어떤 순서로 둘 것인가”라는 틀이므로 컴파일할 때 정적으로 결정할 수 있습니다. 활성 레코드 인스턴스는 실제 호출에서 n=3, 복귀 주소=어느 명령 뒤와 같은 구체적인 값이 채워진 형태이므로 실행 중 동적으로 결정됩니다.

구분결정 시점내용비유가 아닌 실제 차이
활성 레코드 틀정적필드 종류와 배치같은 서브프로그램 호출들이 공유하는 저장 형식
활성 레코드 인스턴스동적이번 호출의 구체적인 값호출할 때마다 별도로 생성될 수 있는 실행 상태

오개념 교정: “활성 레코드가 동적으로 생성되므로 그 구조도 실행할 때마다 새로 설계된다”는 생각은 틀립니다. 틀은 미리 정해지고, 그 틀에 채워지는 값과 인스턴스의 생성 시점이 동적입니다.

정적 할당은 재귀를 막고 스택 할당은 호출을 겹쳐 보관한다

강의의 Fortran 77 구현은 활성 레코드를 정적으로 할당합니다. 서브프로그램마다 하나의 저장공간을 고정해 두면 코드와 데이터 부분을 복잡하게 구별하지 않아도 되지만 재귀 호출은 허용할 수 없습니다. 같은 서브프로그램을 다시 호출하면 이전 호출의 지역변수·매개변수·복귀 주소를 덮어써 호출 정보를 잃기 때문입니다.

Algol 형태 언어는 활성 레코드를 스택에 동적으로 할당합니다. 호출할 때 새 인스턴스를 쌓고 복귀할 때 제거하므로 동시에 살아 있는 재귀 호출을 보존할 수 있습니다. 활성 레코드의 형태는 공통 원리를 따르지만 서브프로그램마다 필요한 지역변수와 매개변수가 달라 크기는 다를 수 있습니다.

활성 레코드의 필드는 프레임 포인터와 변위의 조합으로 참조합니다. 프레임 포인터는 현재 활성 레코드의 기준 지점이고, 지역변위(local offset)는 그 기준에서 원하는 지역 데이터가 얼마나 떨어져 있는지를 나타냅니다.

구현할당동시 활성 인스턴스재귀와의 관계
Fortran 77 사례서브프로그램별 정적 공간같은 서브프로그램에 하나재귀 시 이전 정보를 덮어쓰므로 허용하지 않음
Algol 형태 사례실행 스택에 동적 할당호출 깊이만큼 존재 가능각 호출 상태를 분리해 재귀 지원

활성 레코드의 두 링크는 서로 다른 부모를 가리킨다

동적 링크는 현재 서브프로그램을 실제로 호출한 호출자의 프레임 포인터를 가리킵니다. 정적 링크는 소스 코드의 중첩 구조에서 현재 서브프로그램을 감싸는 정적 부모의 가장 최근 활성 레코드를 가리킵니다. 호출자와 정적 부모가 같을 수도 있지만, 형제 영역을 거쳐 호출하면 달라질 수 있습니다.

링크가리키는 대상반영하는 관계주요 용도
동적 링크호출자의 프레임실제 호출 순서호출자 상태 복원, 동적 영역의 이름 탐색
정적 링크정적 부모의 최근 프레임소스 코드의 중첩 구조정적 영역의 비지역변수 탐색

활성 레코드 스택에서 인접한 동적 링크를 잇는 경로가 동적 체인입니다. 정적 링크들을 연결하면 정적 체인이 됩니다. 동적 체인은 실행 시점의 호출 목록을 따르고, 정적 체인은 프로그램에 적힌 영역의 부모 관계를 따릅니다.

강의의 C 구현은 서브프로그램 중첩을 허용하지 않으므로 정적 링크가 필요 없습니다. 그러나 재귀 호출은 가능하므로 호출마다 매개변수·동적 링크·복귀 주소·반환값을 가진 활성 레코드 인스턴스는 필요합니다. “정적 링크가 없으면 활성 레코드도 없다”는 결론은 두 역할을 혼동한 것입니다.

정적 체인은 코드의 중첩 깊이로 비지역변수를 찾는다

정적 영역 규칙에서는 참조할 비지역변수가 소스 코드의 어느 바깥 영역에 선언되었는지를 기준으로 정적 체인을 따라갑니다. 변수 위치는 (체인변위, 지역변위)의 쌍으로 표현할 수 있습니다.

정적깊이(static depth)는 자신을 감싸는 정적 영역의 개수입니다. main이 0, main 안의 Sub1이 1, Sub1 안의 Sub2가 2라면 Sub2에서 Sub1의 변수를 참조할 체인변위는 2-1=1입니다. main의 변수를 참조하려면 2-0=2입니다. 목표 활성 레코드를 찾은 뒤 지역변위로 그 프레임 안의 실제 위치를 고릅니다.

Main (정적깊이 0): x
└─ Outer (정적깊이 1): y
   └─ Inner (정적깊이 2): z

Inner에서 z 참조: (0, z의 지역변위)
Inner에서 y 참조: (1, y의 지역변위)
Inner에서 x 참조: (2, x의 지역변위)

직접 구성한 이 예에서 체인변위가 0이면 현재 프레임, 1이면 정적 부모, 2이면 그 부모의 프레임으로 이동합니다. 체인변위가 클수록 정적 링크를 더 많이 따라가므로 비지역변수 참조 비용이 커집니다.

정적 체인 계산: 현재 영역의 정적깊이에서 변수가 선언된 영역의 정적깊이를 뺀 값이 체인변위입니다. 그런 다음 목표 프레임 안에서 지역변위를 적용합니다.

정적 부모 밖의 이름은 활성 상태여도 정적으로 보이지 않는다

강의의 Pascal 예에서 Main 안에 Sub1과 Sub3가 나란히 정의되고, D는 Sub1의 지역변수입니다. Sub3의 본체에서 D를 참조하려 하면 오류가 됩니다. 실행 중 우연히 Sub1의 활성 레코드가 스택에 존재할 가능성과 관계없이, Sub1은 Sub3의 정적 부모가 아니므로 Sub3의 정적 체인에서 D를 찾을 수 없습니다.

이 사례는 “스택에 살아 있는 변수라면 정적 영역 규칙에서도 모두 참조 가능하다”는 오개념을 교정합니다. 정적 영역 규칙은 호출 순서가 아니라 소스 코드의 중첩 관계로 가시성을 결정합니다. 활성 여부는 저장공간의 존재를 말하고, 가시성은 이름을 합법적으로 찾을 수 있는지를 말합니다.

호출 시 정적 링크는 정적 부모의 가장 최근 활성 레코드를 가리키도록 설정합니다. 그 프레임을 찾는 한 방법은 동적 링크를 계속 거슬러 올라가는 것이지만 비효율적입니다. 호출자와 피호출자의 정적깊이 차이를 이용하면 필요한 탐색 범위를 줄일 수 있습니다.

동적 체인은 실제 호출 순서를 따라 가장 가까운 이름을 찾는다

동적 영역 규칙에서는 비지역변수를 찾을 때 현재 활성 레코드에서 시작해 동적 링크를 거슬러 올라갑니다. 가장 먼저 만난 같은 이름의 변수를 선택하므로 호출 순서가 달라지면 참조 대상도 달라질 수 있습니다. 이 탐색을 깊은 참조(deep access)라고 합니다.

강의의 예를 실행 순서대로 추적해 보겠습니다. sub1이 sub2를, sub2가 sub3을 호출합니다. sub1에는 a=11과 c=13, sub2에는 b=22와 c=23, sub3에는 b=32와 d=34가 있습니다. sub3에서 a = b + c를 수행합니다.

  1. b는 현재 sub3 프레임에서 바로 찾아 32를 사용합니다.
  2. c는 sub3에 없으므로 동적 링크를 따라 sub2로 올라가 23을 찾습니다.
  3. a는 sub3과 sub2에 없으므로 다시 sub1로 올라가 그곳의 a를 찾습니다.
  4. 32+23=55를 계산해 sub1의 a에 저장합니다.

최종적으로 sub1의 a가 55가 됩니다. sub1에도 c=13이 있지만 더 가까운 sub2에서 c=23을 먼저 찾았으므로 사용되지 않습니다. 이것이 “호출 경로에서 가장 가까운 활성 선언”을 고르는 동적 탐색의 핵심입니다.

동적 체인을 이용한 이름 탐색은 활성 레코드에 변수 이름을 저장하고 일치 여부를 확인해야 하므로 비효율적입니다. 체인 자체는 호출 복귀에도 필요하지만, 이름 탐색 비용을 줄이기 위한 별도 구현이 등장하는 이유입니다.

디스플레이는 정적 조상의 프레임 포인터를 색인으로 고른다

디스플레이(display)는 정적 체인을 반복해서 거슬러 올라가는 부담을 줄이는 방법입니다. 현재 수행 중인 블록과 그 모든 정적 조상의 활성 레코드를 가리키는 포인터를 별도의 스택에 관리합니다.

디스플레이에서 변수는 (디스플레이변위, 지역변위)로 참조합니다. 디스플레이변위는 원하는 프레임 포인터가 저장된 색인이고, 변수가 선언된 서브프로그램의 정적깊이와 같습니다. 현재 수행 중인 서브프로그램의 정적깊이가 p이면 디스플레이에는 0부터 p까지 p+1개의 항목이 있습니다.

현재 정적깊이 p = 3
D[0] → 깊이 0의 활성 레코드
D[1] → 깊이 1의 활성 레코드
D[2] → 깊이 2의 활성 레코드
D[3] → 현재 깊이 3의 활성 레코드

정적 체인은 체인변위만큼 링크를 순서대로 따라가지만, 디스플레이는 D의 색인으로 목표 프레임 포인터를 바로 선택합니다. 그 뒤 지역변위를 적용하는 단계는 같습니다. 멀리 떨어진 비지역변수일수록 이 직접 선택의 이점이 커집니다.

디스플레이 호출은 덮어쓸 항목을 백업하고 복귀 때 복원한다

피호출자의 정적깊이가 q라면 호출할 때 기존 D[q]를 피호출자의 활성 레코드 안에 백업하고, 새로 생성된 피호출자 프레임의 포인터를 D[q]에 저장합니다. 복귀할 때는 활성 레코드에 백업했던 이전 D[q]를 되돌립니다.

  1. 호출 전: D[q]는 같은 깊이에서 이전에 활성화된 프레임을 가리킵니다.
  2. 호출: 이전 D[q]를 새 활성 레코드에 백업합니다.
  3. 수행: D[q]가 새 피호출자 프레임을 가리킵니다.
  4. 복귀: 백업값으로 D[q]를 복원해 호출 전 정적 환경을 되살립니다.

백업 없이 D[q]를 덮어쓰기만 하면 피호출자가 끝난 뒤 이전에 활성 상태였던 같은 깊이의 프레임을 찾을 수 없습니다. 디스플레이가 비지역변수 참조를 빠르게 만드는 대신 호출과 복귀에 관리 작업을 추가하는 지점입니다.

비교 항목정적 체인디스플레이
지역변수 참조현재 프레임 사용현재 프레임 사용
가까운 비지역변수링크가 한 단계면 비슷한 비용색인으로 선택
먼 비지역변수여러 링크를 따라가 비용 증가직접 색인하므로 유리
호출정적깊이 차가 작으면 유리정적깊이 차가 크면 유리
복귀상수 시간, 약간 빠름상수 시간이지만 백업 복구 필요

얕은 참조는 체인 탐색 대신 이름별 현재 값을 관리한다

동적 체인을 따라 이름을 찾는 깊은 참조의 비효율을 줄이기 위해 얕은 참조(shallow access)를 사용할 수 있습니다. 얕은 참조는 지역변수와 비지역변수를 탐색 단계에서 구별하지 않고, 참조 가능한 모든 변수 정보를 하나의 관리 구조에서 찾습니다. 강의에서는 변수 스택과 중앙 테이블을 제시합니다.

변수 스택

변수 이름마다 별도의 스택을 둡니다. 각 스택에는 그 이름을 선언한 현재 활성 레코드의 포인터가 쌓입니다. 새 지역변수가 같은 이름을 선언하면 해당 이름의 스택 맨 위가 새 프레임을 가리키고, 복귀하면 꺼내어 이전 선언이 다시 보이게 합니다.

중앙 테이블

각 변수 이름의 활성 여부와 현재 값을 하나의 표에 저장합니다. 이미 활성화된 같은 이름을 새 선언이 가리려 하면 이전 항목을 은닉 스택에 백업합니다. 복귀할 때 백업한 항목을 복원합니다.

방법주 관리 단위이름이 가려질 때공통 목적
변수 스택이름마다 별도 포인터 스택새 프레임 포인터를 같은 이름 스택에 push동적 체인 전체를 매번 훑지 않음
중앙 테이블이름·활성 플래그·값의 단일 표이전 활성 항목을 은닉 스택에 백업현재 사용 가능한 이름을 한곳에서 찾음

과거 민감 서브프로그램은 종료 뒤에도 일부 상태를 보존한다

일반적인 활성 레코드는 서브프로그램이 복귀하면 제거되고 지역 상태도 사라집니다. 과거 민감(history-sensitive) 서브프로그램은 이전 호출 내용을 기억하도록 상태 정보 일부를 보존합니다.

전역변수를 이용하면 호출 사이의 값을 남길 수 있지만 다른 코드에서도 접근할 수 있어 정보 은닉이 보장되지 않습니다. 정적 지역변수를 이용하면 서브프로그램 내부에 상태를 감춘 채 호출 사이에 값을 유지할 수 있습니다.

직접 구성한 학습 상황으로 “호출될 때마다 1씩 증가한 횟수를 반환하는 함수”를 생각해 봅시다. 횟수를 일반 지역변수로 두면 호출마다 초기화되어 항상 같은 결과가 나옵니다. 정적 지역변수로 두면 이전 호출의 값을 이어받아 1, 2, 3처럼 변화합니다. 핵심은 활성 레코드 전체를 영원히 보존한다는 뜻이 아니라, 필요한 상태 일부의 수명이 한 호출을 넘어선다는 점입니다.

코루틴은 중단 위치와 활성 레코드를 보존해 번갈아 수행된다

코루틴(coroutine)은 여러 진입 위치를 스스로 관리하는 서브프로그램입니다. 수행을 중단한 위치를 기억했다가 다음에 그 지점에서 재개(resume)되므로 활성 레코드가 삭제되지 않고 유지되어야 합니다.

일반 호출은 호출자가 피호출자보다 제어상 우위에 있는 비대칭 구조입니다. 코루틴은 서로 대등한 관계에서 제어를 주고받는 대칭적 제어 모델입니다. 여러 코루틴이 번갈아 수행되므로 한 순간에 실제로 하나씩 실행되더라도 유사병행성을 표현할 수 있습니다.

강의는 생산자-소비자와 카드 게임 같은 시뮬레이션을 활용 사례로 듭니다. 생산자가 항목 하나를 만든 뒤 중단하고 소비자가 그 항목을 처리한 뒤 다시 생산자를 재개한다면, 각 코루틴은 자신의 지역 상태와 다음 실행 위치를 기억해야 합니다.

구분 핵심: 과거 민감 서브프로그램은 호출 사이에 상태 일부를 기억하는 데 초점이 있고, 코루틴은 상태뿐 아니라 과거 중단 위치까지 기억해 여러 진입 지점에서 재개됩니다.

구현 문제는 프레임 생성·이름 탐색·수명 보존으로 푼다

서브프로그램 구현 문제를 만났을 때 다음 순서로 분석하면 용어를 섞지 않을 수 있습니다.

  1. 프레임 생성: 활성 레코드가 정적으로 하나만 할당되는지, 호출마다 스택에 생성되는지 확인합니다.
  2. 호출 관계: 동적 링크가 가리키는 실제 호출자와 정적 링크가 가리키는 소스 코드의 부모를 각각 표시합니다.
  3. 이름 탐색: 정적 영역이면 정적깊이 차, 동적 영역이면 동적 체인의 가장 가까운 선언을 사용합니다.
  4. 탐색 가속: 정적 체인을 디스플레이로, 동적 체인의 깊은 참조를 변수 스택이나 중앙 테이블로 바꾸었는지 확인합니다.
  5. 복귀와 수명: 프레임이 제거되는지, 일부 상태가 남는지, 중단 위치까지 보존되는지 판정합니다.

자가 점검으로 “정적깊이 3인 블록이 깊이 1의 변수를 참조한다면 체인변위는 얼마인가?”, “같은 상황에서 디스플레이의 어느 항목을 보는가?”를 답해 보세요. 정적 체인은 3-1=2개의 링크를 이동하고, 디스플레이는 선언 영역의 깊이와 같은 D[1]을 선택합니다. 두 방식이 같은 목표 프레임에 도달하지만 경로가 다릅니다.

핵심 개념 정리

  • 서브프로그램 연결은 호출자 상태·인수·복귀 주소를 준비해 피호출자로 이동하고, 출력·반환값과 상태를 복원해 호출자로 돌아오는 과정입니다.
  • 활성 레코드 틀은 정적으로 결정되지만, 호출별 구체적인 값을 담은 인스턴스는 실행 중 생성됩니다.
  • 정적 할당은 같은 서브프로그램의 재귀 호출 정보를 겹쳐 보관하지 못하지만, 스택의 동적 할당은 호출마다 프레임을 분리합니다.
  • 동적 링크는 실제 호출자를, 정적 링크는 소스 코드상 정적 부모의 최근 프레임을 가리킵니다.
  • 정적 체인은 (체인변위, 지역변위)로, 디스플레이는 (디스플레이변위, 지역변위)로 비지역변수를 찾습니다.
  • 동적 영역의 깊은 참조는 호출 체인을 탐색하고, 얕은 참조는 변수 스택이나 중앙 테이블에서 현재 보이는 이름을 관리합니다.
  • 과거 민감 서브프로그램은 호출 사이의 상태 일부를, 코루틴은 상태와 중단 위치를 보존합니다.

실행 장면을 그릴 때 먼저 호출마다 활성 레코드를 하나씩 쌓고, 각 프레임에서 동적 링크와 정적 링크의 화살표를 다른 색이라고 생각하며 분리하세요. 변수 참조가 나오면 영역 규칙을 먼저 결정하고, 정적 체인은 깊이 차만큼 이동하며 동적 체인은 이름을 찾을 때까지 실제 호출자를 거슬러 갑니다. 디스플레이나 얕은 참조가 등장하면 “링크 탐색을 어떤 색인·테이블 관리로 바꾸었는가”를 확인하고, 마지막으로 복귀 때 어떤 프레임과 보조 구조가 제거·복원·유지되는지 점검하면 전체 구현 흐름을 재현할 수 있습니다.

예상문제

1. 활성 레코드 인스턴스에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 활성 레코드는 코드가 아니라 수행 중 호출의 데이터와 관리 정보를 담습니다.
  • ② 오답: 복귀 주소와 호출자 상태는 서브프로그램 연결을 위해 필요한 핵심 정보입니다.
  • ③ 오답: 필드 배치 규칙은 활성 레코드 틀이며, 인스턴스는 그 틀에 실제 값이 채워진 것입니다.
  • ④ 정답: 호출마다 동적으로 달라지는 구체적인 실행 상태를 정확히 설명합니다.

2. 동적 링크와 정적 링크의 연결 대상으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 현재 호출자와 정적 부모는 중첩·호출 관계에 따라 여러 프레임이 될 수 있습니다.
  • ② 정답: 실제 실행 경로와 소스 코드의 중첩 경로를 각각 보존하는 두 링크의 역할입니다.
  • ③ 오답: 동적·정적 관계를 뒤섞었고 반환값은 링크의 목표가 아닙니다.
  • ④ 오답: 두 링크는 필드 종류가 아니라 다른 활성 레코드의 프레임 포인터를 가리킵니다.

3. 정적깊이 4인 영역에서 정적깊이 1인 영역에 선언된 변수를 참조할 때 체인변위는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 선언 영역의 깊이 자체를 답으로 선택했으며 현재 깊이와의 차이를 계산하지 않았습니다.
  • ② 오답: 정적 부모 두 단계만 이동하면 깊이 2에 도달해 목표 깊이 1이 아닙니다.
  • ③ 정답: 현재 깊이 4에서 선언 깊이 1을 빼면 체인변위는 3입니다.
  • ④ 오답: 두 깊이를 더한 값으로, 정적 링크 이동 횟수를 나타내지 않습니다.

4. “실행 스택에 Sub1의 D가 남아 있으면 형제 영역인 Sub3에서도 정적 영역 규칙으로 D를 참조할 수 있다”는 주장에 대한 교정은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 저장공간의 존재가 아니라 소스 코드의 정적 중첩 관계가 이름의 가시성을 결정합니다.
  • ② 오답: 변수 타입은 정적 영역의 가시성 경계를 없애지 않습니다.
  • ③ 오답: 동적 링크는 호출 관계이며 정적 영역의 합법적인 참조 범위를 새로 만들지 않습니다.
  • ④ 오답: 복귀 주소는 제어 복원 정보이고 정적 부모 관계를 결정하지 않습니다.

5. 동적 영역 예에서 sub3의 a = b + c를 수행할 때 찾는 순서와 값으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 더 가까운 현재 프레임의 b와 호출자 sub2의 c를 건너뛰었습니다.
  • ② 정답: 현재 프레임부터 동적 링크를 따라 가장 먼저 만나는 선언을 선택한 결과입니다.
  • ③ 오답: 동적 체인은 전역부터 내려오는 것이 아니라 현재 호출에서 바깥 호출자로 올라갑니다.
  • ④ 오답: a도 동적 체인을 따라 sub1에서 찾을 수 있으므로 대입이 성립합니다.

6. 정적 체인과 디스플레이를 비교한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 변수 이름마다 스택을 두는 것은 동적 영역의 얕은 참조 방법인 변수 스택입니다.
  • ② 오답: 정적 체인은 체인변위가 커질수록 더 많은 링크를 따라가야 합니다.
  • ③ 오답: 새 프레임 포인터로 D[q]를 덮기 전에 이전 값을 백업하고 복귀 때 복원해야 합니다.
  • ④ 정답: 참조 속도와 호출·복귀 관리 비용 사이의 교환관계를 정확히 설명합니다.

7. 현재 수행 중인 서브프로그램의 정적깊이가 4라면 디스플레이 항목 수는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 깊이 0부터 4까지의 정적 조상과 현재 블록을 가리켜 p+1인 5개가 필요합니다.
  • ② 오답: 정적깊이 값만 세고 깊이 0 항목을 빠뜨렸습니다.
  • ③ 오답: 현재 블록과 일부 조상 프레임을 누락해 모든 정적 조상에 접근할 수 없습니다.
  • ④ 오답: 디스플레이 항목 수는 현재 정적깊이 p로 p+1개라고 결정할 수 있습니다.

8. 동적 체인의 이름 탐색 비용을 줄이면서 변수 이름마다 현재 활성 프레임 포인터를 쌓으려 한다. 적합한 방법은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 정적 체인은 정적 링크로 정적 조상을 탐색하며 이름별 스택을 만들지 않습니다.
  • ② 오답: 디스플레이는 정적깊이별 활성 프레임 포인터를 관리합니다.
  • ③ 정답: 이름마다 별도 스택을 두고 현재 보이는 선언의 활성 레코드 포인터를 맨 위에 둡니다.
  • ④ 오답: 하나의 고정 레코드는 중첩 호출과 이름 가림의 현재 상태를 겹쳐 보관하지 못합니다.

9. 과거 민감 서브프로그램과 코루틴의 차이를 올바르게 설명한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 두 방식 모두 이전 실행의 정보를 보존한다는 공통점이 있습니다.
  • ② 오답: 대등한 코루틴들이 제어를 주고받는 구조는 코루틴의 특징입니다.
  • ③ 오답: 중단 지점에서 재개하려면 코루틴의 활성 레코드가 유지되어야 합니다.
  • ④ 정답: 단순 상태 기억과 실행 위치까지 포함한 재개의 차이를 정확히 구분합니다.

10. 중첩 서브프로그램의 비지역변수 참조를 분석하는 순서로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 변수 타입은 영역 규칙을 결정하지 않으며 중첩·호출 관계가 탐색 경로를 만듭니다.
  • ② 오답: 프레임 크기만으로는 어느 바깥 프레임에 목표 변수가 있는지 알 수 없습니다.
  • ③ 정답: 정적 영역과 동적 영역의 결정적 차이를 먼저 적용하고 각 방식의 올바른 탐색 경로를 사용합니다.
  • ④ 오답: 복귀 주소의 수치 크기는 이름 탐색의 우선순위와 관계없습니다.

참고 자료와 작성 기준

이 글은 해당 차시 강의자료를 바탕으로 학습 목적에 맞게 재구성한 비공식 학습자료입니다. 재귀 호출 추적, 체인변위 계산, 동적 이름 탐색과 디스플레이 관리 해설은 학습자의 이해를 돕도록 구성하고 검토했습니다.

  • 작성·편집: 올에이클래스 학습연구팀
  • 주요 근거: 한국방송통신대학교 컴퓨터과학과, 「프로그래밍 언어론」 14강 ‘서브프로그램 구현’ 강의자료(2025)
  • 보충 자료: 외부 보충 자료를 사용하지 않았으며, 해당 차시 강의자료의 범위 안에서 재구성했습니다.
  • 편집 원칙: 올에이클래스 편집 정책
  • 최종 내용 검토: 2026-08-30

댓글