프로그래밍 언어 - 이름, 바인딩, 영역
💫 이름, 바인딩, 영역
🫧 서론
- 명령형 언어
- (현대 컴퓨터) = 폰 노이만 컴퓨터에 대한 추상화
- 메모리에 데이터/Instruction을 넣고, 하나씩 꺼내고 Decode하고 실행시키는
- 데이터의 저장과 데이터 가공을 위한 연산으로 구성
- 메모리 셀에 대한 언어적 추상화 → 변수, 배열 등
- 변수의 특성
- 타입, 주소, 값
- Scope 영역과 Lifetime 존속기간
순수
함수형 언어에서의 변수- 값이 한 번 변수에 배정되면 값의 변경을 허용하지 않음
- 하지만 많은 함수형 언어에서는 명령형 언어처럼 값의 변경을 허용
🫧 Name 이름, Identifier 식별자
@ U 중간고사 출제 : 식별자, 예약어, 키워드를 설명하시오. 키워드가 예약어가 아니라면 언어에 어떤 영향을 주는지, 예약어의 수가 많으면 언어에 어떤 영향을 주는지 설명하시오.
이름은 변수의 속성 중 하나 → Variable Name 변수명
이름은 Subprogram 부프로그램, Formal Parameters 형식 인자, 다른 프로그램 구성 요소와도 관련이 있음
이름 Name = 식별자 Identifier
설계 주요 이슈 → 이름은 Case Sensitive 한가? → 언어의 Special Words 특별한 용어는 Reserved Word 예약어인가 Keyword 키워드인가?
- 이름
- 프로그램에서 개체를 식별하기 위해 사용되는 문자열
- 프로그래밍 언어마다 식별에 참여하는 길이는 다름
- C99 : Linker가 External Name의 31자까지만 허용 ← 31자 이후는 비교 안함
- Java, C# : 제한 X
- C++ : 구현자에 따라 다름
@ 왜 변수명을 숫자로 시작하면 안되나?
@ Lexical Analysis 단계에서, 숫자로 시작하는 토큰을 만나면, 숫자인지 변수인지 알기 위해, 숫자 뒤에 있는 문자 존재 여부를 확인하는 Backtracking 과정이 필요
@ → 컴파일러 구현의 편의성, 퍼포먼스 향상을 위해
@ TODO: IDE 문법 검사, 인텔리센스 원리?
- 일반적인 프로그래밍 언어에서의 이름 작성 규칙
- 구성 : Alphabet, Number, Underbar(Underscore) _
- 첫글자 숫자 X
- 다른 예 : PHP, Ruby
- 일반적으로 대소문자 구분 Case Sensitive
- 다양한 표기법
- Camel Notation, Pascal Notation, Snake Notation, …
- 구성 : Alphabet, Number, Underbar(Underscore) _
@ 현학적인
Special Word 특수어
→ 프로그래밍 언어에서 수행할 행동들을 명칭화
→ I.E. if, else, for, while, …
Reserved Word 예약어
→ 프로그래밍 언어에서 특별한 의미로 해석하도록 선정 됨
→ Identifier 식별자로 사용될 수 없는 단어
→ 특수어는 예약어로 분류 (대부분 언어)
Keyword 키워드
→ 어떤 문맥에서만 특별하게 사용되는 단어
키워드와 예약어는 동일
일정정의 예약어 정의함 (대부분 언어)
→ C : 44, Java : 46, Python : 35, …
→ Python 키워드 확인 : import keyword, len(keyword,kwlist)
예약어 비례 작성력 나빠짐
→ Cobol : 300 여개의 예약어
💫 변수
프로그램 변수는 컴퓨터 메모릴 셀이나 셀들의 모임에 대한 추상화
→ 컴파일러는 번역시에 변수를 주소로 변환
변수의 특성
→ Name, Type, Address, Value, Scope & Lifetime
변수 이름
→ 대부분
의 변수는 이름을 가진다
변수의 주소
→ 변수와 연관된 기계 메모리 주소
→ 동일한 변수가 다른 시점에 다른 주소와 연관되는 것이 가능, I.E. 스택 변수 → 저장된 호출 시기에 따라 주소 다름
→ L-Value라 불림 : 배정문의 좌측의 위치
→ 여러 개의 변수가 동일한 주소를 가지는 것이 가능 → 별칭
→ 공용체, 포인터, 참조 변수
→ 별칭은 가독성을 떨어뜨리는 요소가 되기도
타입
→ 변수가 저장할 수 있는 값들의 범위와 연산들의 집합을 결정
→ Java의 Int 타입 -21억~ 21억, 산술연산 가능 ~
값
→ 값은 그 변수에 연관된 메모리 셀이나 셀들의 내용 → 추상적인 메모리 셀
→ R-Value라고 불림 : 변수가 배정문의 우측의 위치
L-value vs R-value
int x = 5;
x = x + 1;
영역
→ 변수가 사용될(접근될) 수 있는 범위
존속 기간
→ 변수가 할당되어서 삭제될 때까지의 시간
🫧 바인딩
속성과 개체간의 연관
→ 변수와 타입, 변수와 값, 변수와 주소, 기호와 연산 등
@ 사진 7_0000
- 바인딩 시간 (Binding Time)
- 속성과 개체간의 연관이 일어나는 시점
- 언어 설계 시간 (Language design time)
- 곱셈 기호 * (곱, 포인터, …)
- 언어 구현 시간 (Language implementing time)
- C int Size
- 컴파일 시간 (Compile time)
- C, Java 변수와 타입
- 링크 시간 (Link time)
- 적제 시간 (Loading time)
- 전역 변수와 그의 주소
- 실행 시간 (Run time)
- 지역 변수와 그의 주소
i.e.
int count = 0; count = count + 5;
count Type : Compile TIme 바인딩
count 값의 범위 : Design Time 설계 시간 바인딩
+의 의미 : Compile Time (에 피연산자의 타입 결정되었을 때 바인딩)
Literal 5의 표현 : Design Time 설계 시간 바인딩
count 값 : Run Time 실행 시간 바인딩
실매개변수와 형식매개변수 간의 바인딩이 어떻게 일어나는가를 이해하는 것이 중요
🫧 정적 바인딩, 동적 바인딩
정적 바인딩
→ 실행 시간 이전에 바인딩이 일어나고 실행 전체에 걸쳐서 변하지 않는 경우
동적 바인딩
→ 실행 시간 중에 바인딩이 일어나거나 실행 과정에서 바인딩이 변경될 수 있는 경우
HW 바인딩은 고려하지 않음
→ Virtual Memory와 (Real?) 실메모리 사이의 바인딩
🫧 타입 바인딩
변수는 참조전에 타입이 바인딩 되어있어야 함
고려사항
→ 변수의 타입이 어떻게 명세되고 언제 바인딩 되는가?
- 정적 타입 바인딩
- 컴파일 시에 변수의 타입이 결정 됨
- 명시적 선언
- 변수 이름들을 나열하고 이들이 어떤 타입인지를 명세하여 바인딩
- 컴파일러 방식에서 사용
- int count, sum;
- 명시적 선언
- 묵시적 선언
- 디폴트 규칙을 통해서 변수에 타입을 바인딩
- 약간의 편리성을 주나 오류를 탐지하는 것을 방해하여 신뢰성에 유해
- 컴파일러 방식이나 인터프리터 방식에서 사용
- 타입 추론
- 문맥을 이용하여 타입 결정, 프로그램 단위 내에서 타입은 정적 바인딩
- C#에서의 var
- var sum = 0; // run-time 에 type이 결정되는 것이 아니라
- var str = “Hello world”; // compile-time에 type이 결정됨, javascript의 var와 다름
- 컴파일 시에 변수의 타입이 결정 됨
- 동적 타입 바인딩
- 변수의 타입이 실행시간에 변함
- 변수의 타입이 명세되지도 않고 철자로부터도 유추되지 않음
- 1990년대 중반 이전의 프로그래밍 언어는 정적 타입 바인딩이 유행, 하지만 그 이후 동적 바인딩 언어가 유행 → Python, Ruby, JavaScript, PHP 등
- 주로 순수 인터프리터 언어에서 채택
- 예
- Python, JavaScript
- list = [1, 2, 3, 4, 5]
- list = 5
- C#
- dynamic any;
- Python, JavaScript
- 순수 객체지향 언어에서 모든 데이터는 객체이며, 임의의 변수는 임의의 객체를 참조할 수 있음 → 모든 변수는 참조 타입
- Java는 특정 타입의 값을 제한되게 참조하도록 설계
- 장점
- 프로그램에 유연성 제공
- 단점
- 프로그램의 신뢰성 저하
- 컴파일 시점에 타입오류를 검출하지 못 함 → 잘못된 배정문이 실행될 수 있음
- 타입 검사가 실행시간에 발생하므로 비용이 많이 든다
- 변수와 연관되는 실행시간 서술자(descriptor)를 가져야하고 변수마다 다양한 기억 공간을 요구하므로 이를 실행시간에 관리해야 함
- 정적 타입 바인딩 언어보다 매우 느리다
- 정적 타입 언어는 모든 변수의 타입을 컴파일 타임에 알 수 있으므로 그에 최적화된 실행 코드의 생성이 가능 → 동적 타입 언어는 실행시간에 알 수 있음
- 프로그램의 신뢰성 저하
@ U 중간고사 범위
💫 기억공간 바인딩과 존속기간
@ U 기말고사 출제 : 변수의 기억 공간 바인딩이 무엇인지 설명하고, 정적 변수, 스택-동적 변수, 명시적 힙-동적 변수, 암묵적 힙-동적 변수를 각각 바인딩 관점에서 설명하시오.
- 동적 타입 바인딩
Code 영역, 코드 명령어들
Data 영역, 전역 변수, Static 정적 변수
→ 프로그램 시작 ~ 끝
Stack 영역, 함수가 호출 될 때 마다, 각 함수의 매개변수, 지역변수, 호출/돌아갈 위치
→ 함수 시작 ~ 끝
ip 레지스터가 Code 영역의 Main 함수 가리킴
- 명시적 힙-동적 변수
UnManaged/Managed Heap
올바른 사용의 어려움
Memory Leaking
→ 일반 프로그램은 끄면 그만이지만, 항시 켜져있는 서버에서 발생한다면
Dangling Pointer
- 암묵적 힙-동적 변수
🫧 개요
변수의 기억공간 바인딩은 명령형 프로그래밍 언어의 근본적 특징
- 기억 장소 할당(Allocation)
- 변수에 바인딩되는 메모리 셀을 가용 메모리 풀로부터 가져옴
- 기억 장소 회수(Deallocation)
- 변수로부터 바인딩이 해제된 메모리 셀을 다시 가용 메모리 풀로 반환
- 변수의 존속기간(Lifetime) - 시간적인 개념
- 변수가 특정 메모리 위치에 바인딩 되어 있는 기간
- 존속 기간에 따른 4가지 경우
- 정적(Static) 변수, 스택-동적 변수, 명시적 힙-동적 변수, 묵시적 힙-동적 변수
- 정적 Static 변수
- 실행전에 메모리에 바인딩되어서 프로그램이 실행 종료할 때까지 동일한 메모리 셀에 바인딩 되어 있는 변수
- 전역 변수나 정적 지역 변수에 해당
- 객체 지향 언어에서의 static 지정자는 클래스 변수를 생성
- 객체가 생성되기 전에 정적으로 해당 변수를 생성
- 장점
- 효율성
- 프로그램 전역 혹은 특정 지역에서의 직접적 접근이 가능
- (미미한 수준 이지만) 정적 변수의 할당과 회수를 위한 실행-시간 부담이 없음
- 효율성
- 단점
- 유연성 감소
- 정적 변수만을 가지는 프로그래밍 언어는 재귀적 호출을 지원할 수 없음
- 유연성 감소
- 실행전에 메모리에 바인딩되어서 프로그램이 실행 종료할 때까지 동일한 메모리 셀에 바인딩 되어 있는 변수
- 스택-동적 변수
- 해당 변수의 선언문이 실행될 때 기억공간에 바인딩 되며 타입은 정적으로 바인딩 됨 → 기억 공간만 동적 바인딩 되고 나머지 속성은 정적 바인딩
- C, C++의 함수 내 지역변수, 형식매개 변수 등
- Java, C++의 메소드 내 지역변수, 형식매개 변수 등등
- 스택-동적 변수는 실행시간에 스택에 할당
- 장점
- 각 부프로그램 마다 자신의 기억 공간을 가짐 (스택에 쌓이는)
- 재귀 부프로그램의 작성에 활용
- 단점
- (미미하지만) 할당과 회수에 따른 실행-시간 부담
- (미미하지만, 무시할정도) 간접 주소지정 방식으로 접근하므로 정적 변수보다는 느림
- 부프로그램이 과거 데이터의 접근에 제약 @ foo에 제어가 들어가 있을 때, 이전 (main) 요소에 대해서는 접근이 불가능하다
- 해당 변수의 선언문이 실행될 때 기억공간에 바인딩 되며 타입은 정적으로 바인딩 됨 → 기억 공간만 동적 바인딩 되고 나머지 속성은 정적 바인딩
@ C/CPP, auto
@ 사진 7_0001
- 명시적 힙-동적 변수
- 프로그래머가 명시적으로 실행시간 명령어에 의해서 할당되고 회수되는
이름없는
메모리 셀- 힙에 할당되고 회수되며, 포인터나 참조변수를 이용하여 참조할 수 있음
- 접근에 사용하는 포인터나 참조변수는 다른 스칼라 변수처럼 생성
- 힙에 할당되고 회수되며, 포인터나 참조변수를 이용하여 참조할 수 있음
- 명시적 힙-동적 변수의 생성 및 회수 방법
- C: 힙 메모리 할당을 위한 시스템 콜을 사용 - malloc(), alloc(), free() 등
- C++: 힙 메모리 할당을 위한 연산자를 사용 - new, delete
- Java, C#: 힙 메모리 할당을 위한 연산자 new, 회수는 Garbage collector가 암묵적으로 회수
- 명시적 힙-동적 변수의 활용처
- 리스트나 트리와 같이 실행시간에 동적으로 크기가 변하는 자료구조 구축
- 단점
- 포인터와 참조 변수의 올바른 사용의 어려움 (leaking, stray? point)
- 참조비용, 기억 공간 관리 구현의 복잡성 등
- 프로그래머가 명시적으로 실행시간 명령어에 의해서 할당되고 회수되는
- 암묵적 힙-동적 변수
- 값이 배정될 때 힙 기억 장소에 바인딩
- 값이 배정될 때마다 변수의 모든 속성이 바인딩 됨
- 예: JavaScript, Python 등
- highs = [74, 84, 86, 90, 71];
- 장점
- 최고의 유연성과 일반화(generic) 프로그램 작성에 유리
- 단점
- 실행시간에 속성을 관리해야함으로 인해 비용이 많이 듬
- 컴파일러에 의한 오류 탐지 능력 상실 → 프로그램의 신뢰성 상실
HD global_var1, global_var2, count → data영역
런타임
Text 영역, Readonly == 쓰기 작업 금지 된
global_var1, global_var2, count → data영역 (어떤 부분은 readonly → 상수 변수들, Static 프로그램이 실행되면서 꺼질때까지)
Stack (함수가 Call될때, i.e. Main, Main에 대한 스택 리턴 어드레스, i, j, + foo에대한스택i, j, temp, pi) Heap - unmanaged heap, (Malloc)
OS HW
i.e. java JVM (class load (code + data 영역), stack, haep - managed heap) oS HW
Garbage Manager - 참조 count
💫 영역 Scope
@ U 기말고사 출제 : 정적 영역과 동적 영역을 각각 설명하고, 이들의 장단점을 비교 설명하시오.
- 변수의 영역(Scope) - 공간적인 개념
- 변수가 참조 가능한, 가시적인(Visible) 문장들의 범위
- 변수가 어떤 문장에서 참조가 가능하면, 변수는 그 문장에서 가시적이다.
- 영역 규칙(Scope rules)
- 이름을 어느 변수와 연관을 짓게 할 것인가를 결정하는 규칙
- 지역(local) 변수 vs 비지역(nonlocal) 변수
- 지역 변수: 프로그램 단위(예 함수)나 블록내에 선언된 변수
- 비지역 변수: 프로그램 단위나 블록내에 선언되어 있지는 않지만 해당 영역에서 가시적인 변수
- 전역 변수는 비지역 변수의 한 예
- 정적 영역 Static Scope
- 변수의 영역이 변수의 선언/정의 위치 그리고 부프로그램들의 상호 간의 공간적 배치 관계에 의하여 결정
- 변수의 영역이 실행(Runtime)전에 결정할 수 있음
- 사람 혹은 컴파일러가 소스 코드의 분석을 통해 프로그램에 포함된 모든 변수의 타입을 결정 가능
- ALGOL 60에서 도입된 후 많은 언어에서 도입
- 두가지 형태의 정적 영역 언어가 존재
- 부프로그램(혹은 함수)이 중첩 가능한 경우와 중첩이 안되는 경우
- 부프로그램(혹은 함수)는 정적 영역을 생성
- 부프로그램 중첩이 가능한 언어
- 중첩된 부프로그램을 통해 중첩된 정적 영역의 생성이 가능
- JavaScript, Python 등
- 부프로그램 중첩이 가능하지 않은 언어
- 부프로그램의 중첩은 허용치 않으나 중첩된 클래스 정의나 블록에 의해서 중첩된 정적 영역 생성 가능
- C기반 언어들
- 부프로그램(혹은 함수)이 중첩 가능한 경우와 중첩이 안되는 경우
- 부프로그램의 중첩이 허용되는 언어의 경우 (JS, Python 등)
- 가정:
- 모든 영역들은 프로그램 단위들과 연관
- 모든 nonlocal 변수에 대한 참조는 다른 프로그램 단위에 있음
- 해당 nonlocal 변수에 대한 접근은 영역 규칙(Scope Rule)에 의해서만 가능
- 영역 규칙
- 해석(Resolution)할 변수를 참조되는 부프로그램(함수) 영역에서 선언을 찾음
- 발견 된 경우: 해당 영역의 지역 변수로서 해석 (OK)
- 발견이 안된 경우: 정적 부모(static parent)의 영역에서 탐색
- 정적 조상(static ancestor)를 따라 가며 발견이 된 경우 해당 영역의 변수로 해석 (OK)
- 만약 최상위 프로그램 단위까지에서도 발견이 안되면 변수 미선언 에러 발생
- 지역 변수가 외부 (전역) 변수에 우선 함
- 해석(Resolution)할 변수를 참조되는 부프로그램(함수) 영역에서 선언을 찾음
- 가정:
i.e. JS, var/function Hoisting
i.e. Python, Scope Resolution Rule - LEGB Local Enclosed Global Built-in, 다 찾아도 없으면 Name Error
💫 블록 Block
- Block
- 많은 언어에서 실행 코드 중간에 새로운 정적 영역의 정의를 허용
- 블록이라 불리는 부분적 코드들이 자신의 지역 변수를 갖는 것을 허용
- 변수의 참조 가능한 영역을 최소화 하는 효과
- ALGOL60에서 도입되었으며 많은 언어(C기반 언어)에서 채택
- 블록(Block)내의 변수들은 스택 동적으로 작동
- 해당 블록에 진입할 때 메모리에 확보되었다가 빠져나올 때 회수 됨
- C기반 언어의 복합문(중괄호에 싸인 코드들)내에서 선언문을 갖는 것을 허용함
- 블록에 의해 생성된 영역은 부프로그램(함수)에 의해 생성된 영역과 동일하게 취급
- C/C++ 언어에서는 중첩된 함수를 허용하지 않음
- 블록이라 불리는 부분적 코드들이 자신의 지역 변수를 갖는 것을 허용
- C기반 언어에서는 중첩된 함수를 허용하지 않음, 하지만 블록을 통해서 중첩을 허용
- 블록은 복합문(중괄호에 싸인 코드)를 생성하기위해 사용
- C기반 언어의 복합문(중괄호에 싸인 코드들)내에서 선언문을 갖는 것을 허용함
- 블록에 의해 생성된 영역은 부프로그램(함수)에 의해 생성된 영역과 동일하게 취급
- Scope Resolution Rule은 Local > 부모 Scope > 선조 Scope > Global
- 지역 변수명와 상위영역의 변수명이 충돌할 경우 지역변수 우선
- 전역의 변수를 참조하고 싶은 경우 C는 extern을 사용 C++는 :: 연산자 사용
- Java/C#에서는 중첩 블록을 허용 하지만 중첩된 블록에서의 변수명이 상위 영역에서의 변수명과 충돌을 허용하지 않음
- 이름의 재사용이 오류를 유발시킬 수 있음으로 이러한 경우를 배제
- JavaScript와 Python은 블록의 개념은 제공하나 블록 Scope은 없음
- 함수 Scope만 제공
- 선언 순서
- 변수의 선언 위치는 변수의 영역에 영향을 미침
- C89: 함수에 포함된 모든 변수 선언은 중첩된 블록에 속한 선언을 제외하고는 그 함수의 시작부분에 와야만 한다.
- C99, C++, Java, JavaScript, C#, Python등은 변수 선언이 프로그램 단위에서 문장이 나타날 수 있는 곳이면 어디든지 나타나는 것을 허용
- 일반적으로(C99, C++, Java), 모든 지역 변수의 영역은 선언문으로부터 그 선언문이 나타나는 블록의 끝까지를 형성
- C#은 블록 어디에 선언이 되든 그 블록 전체가 영역
- 주의: 변수를 사용하기 전에 해당 변수는 선언이 되어 있어야 함
- JavaScript에서 var로 선언된 변수는 어디에 선언되어 있든 hoisting 됨 (let은 안됨)
- JavaScript에서 변수의 선언 없이 변수를 사용하는 것이 가능, 이 경우 변수의 값은 undefined가 됨
- C, C++, Java, C#의 제어문 내 초기화 변수는 해당 제어문 내에서만 의미를 가짐
🫧 전역 영역
- 전역 변수
- 파일에 속한 함수 외부에 위치한 변수
- 함수 정의들로 구성된 프로그램 구조를 허용하는 언어에서, 변수 정의들이 함수 외부에 올 수 있음
- C, C++, PHP, JavaScript, Python 등
- 함수 정의들로 구성된 프로그램 구조를 허용하는 언어에서, 변수 정의들이 함수 외부에 올 수 있음
- 전역 변수는 이후에 오는 함수들내에서 가시적임
- 전역 변수는 함수들에 가시적이며 프로그램 전체에 가시적일 수 있다. 이는 오류의 원천이 될 수 있음
- 전역 변수는 필요악이다. (Global variable is necessary evil.)
- 특히 C는 전역 공간을 관리하는 이름공간(namespace)이 없음
- 파일에 속한 함수 외부에 위치한 변수
- C/C++언어에서의 전역 변수의 선언과 정의
- 선언: 타입 및 다른 속성들을 명세하나 기억공간의 할당을 하지 않음
- 정의: 속성들을 명세하고 기억공간을 할당 함
- 선언은 여러번 할 수 있지만 정의는 한번만 가능
- 예: extern int var1;
- 전역에 위치하면 var1이 다른 파일에 존재함을 의미
- 지역에 위치하면 var1이 전역에 존재함을 의미 (다른 파일의 전역이어도 상관없음)
- C에서 전역과 지역변수의 이름이 같은 경우 지역 우선이며 전역 변수의 이름은 은폐됨
- C++에서는 ::연산자를 이용하여 전역 변수를 접근 가능
- PHP의 전역 변수
- PHP 전역변수의 영역은 선언한 위치로부터 파일의 끝까지 임
- PHP 전역변수는 함수내에서 기본적으로 비가시적이나 명시적으로 가시적이게 할 수 있음
- 전역변수와 동일한 지역변수가 존재하면 변수이름을을 첨자로하여$GLOBAL배열을 이용하여 접근가능
- 전역변수와 동일한 지역변수가 존재하지 않으면 global 선언문을 이용하여 접근가능
- JavaScript의 전역 변수
- JS의 전역변수는 동일한 이름을 가진 지역 변수가 있는 경우 해당 지역에서는 지역 변수만 접근이 가능하고 전역 변수를 접근할 수 있는 방법은 없음
- Python의 전역 변수
- 전역변수와 동일한 이름을 가진 지역변수가 존재하면 전역 변수는 은폐됨
- Python의 전역변수는 함수 내에서 기본적으로 읽기는 가능 하지만 쓰기를 위해서는 global 선언을 해주어야 함
- 그렇지 않을 경우 에러 발생
- 전역 영역의 평가
- 장점
- 많은 상황에서 잘 동작하는 비지역 변수를 접근하는 방법을 제공
- 단점
- 변수와 부프로그램에 대한 접근을 필요 이상으로 많이 허용
- 프로그램의 수정 혹은 버전업 과정에서 전역 변수의 사용을 부추길 수 있음
- 초기의 설계를 쉽게 폐기시키고 전역변수로 문제를 해결하려고 함
- 해결책으로서 캡슐화가 제안 됨
- 장점
🫧 동적 영역
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// C#이 동적은 아니지만 예를 들어본다면
int x = 3;
void Main() => Sub1();
void Sub1()
{
int x = 7;
Sub2();
}
void Sub2()
{
int y = x;
Console.WriteLine(y); // 7
}
부프로그램의 호출 순서에 따라서 변수의 영역이 결정
- 문제점
- 부프로그램 내의 지역 변수가 다른 실행 중인 부프로그램에 가시적이다.
- 지역 변수를 보호할 방법이 없음
- 정적 영역보다 동적 영역이 신뢰성이 떨어짐
- 비지역 변수에대한 참조를 정적으로 타입 검사를 할 수 없음
- 프로그램의 판독을 어렵게 함
- 프로그램 작성 시에 부프로그램의 호출 순서를 알 수 없음
- 동적 영역에서의 비지역 변수에 대한 접근은 정적 영역에서의 비지역 변수에 대한 접근보다 느리다.
- 부프로그램 내의 지역 변수가 다른 실행 중인 부프로그램에 가시적이다.
- 장점
- 부프로그램을 호출 시에 매개변수 전달을 할 필요가 없음
- 호출 하는 함수(Caller)의 변수들은 호출 되는 함수(Callee)에서 묵시적으로 가시적임
- 부프로그램을 호출 시에 매개변수 전달을 할 필요가 없음
- 동적 영역은 정적 영역 만큼 사용되지 않음
- 장점 보다 문제점이 더 많기 때문
@ 잘안씀
💫 영역 vs 존속기간
@ U 기말고사 출제 : 변수의 영역과 존속 시간을 각각 설명하고 이들이 서로 어떻게 다른지를 보이는 예를 제시하고 설명하시오.
때때로 같아 보이기도 하지만 다름!
영역은 공간적, 존속기간은 시간적 개념
i.e. 함수 안 static 변수
~ 정적 영역에서 Scope 밖 변수? 대신 포인터를 쓰면 가능
💫 참조 환경
어떤 문장에서의 참조 환경은 그 문장에서 가시적인 모든 이름들의 집합
- 정적-영역 언어에서의 참조 환경
- 그 지역 영역에 선언된 변수들과 그 조상 영역에 속한 가시적인 모든 변수들로 구성
- 문장이 컴파일 될 때 참조 환경이 구축되어 있어야 함
💫 이름 상수
딱 한 번만 값에 바인딩 되는 변수
가독성과 신뢰성을 향상
i.e. 3.1415 → PI
프로그램을 매개 변수화 하는데 아주 유용
- C
- const (C) or #define (Preprocessor)
- const가 타입 Checking/Debugging 시 유리
- C/C++/Java에서 이름 상수에 대한 동적 바인딩을 허용
- 하지만 한번만 허용
- C#: const 정적 바인딩, readonly 동적 바인딩 허용
- Python은 이름 상수 허용 문법 없음
- 단지 이름 규약으로 해