(5.1) 서론
Imperative PL은 폰노이만 구조의 영향을 받았다.
폰노이만 아키텍쳐 구성요소
■ CPU
ㅡ> 메모리의 값 바꾸는 연산 (배정문)
■ 메모리
ㅡ> instruction(기계어), data(변수들의 값 저장하는 공간)
프로그램이 진행된다 = 변수의 값을 바꾸면서 내려간다 (배정문)
memory cell 하나하나에 이름을 붙여놓고, variable이라고 부른다.
(5.2) Names
■ Identifier
ㅡ> name과 같은 의미로 쓰인다.
ㅡ> 프로그래머가 임의로 붙여준 이름 (변수명 함수명)
(5.2.2) Name Forms
■ Name
ㅡ> 프로그램의 entity를 식별하기 위한 이름
ㅡ> 언어마다 identifier를 쓰는 rule이 있다.
■ case sensitive
ㅡ> 대소문자 구별 (다른문자로 판단)
■ reserved word = keyword
ㅡ> 언어에서 쓰는 단어
ㅡ> Identifier가 쓸 수 없다
(5.3) Variables
■ Variable
ㅡ> 메모리 셀에 붙인 이름
■ Variable 6가지 속성
- name
- address (l-value)
- value (r-value)
- type (6장)
- lifetime
- scope
회사마다 naming 규칙이 있다.
(5.3.2) Address
배정문의 왼쪽에 나타나서 l-value라고 부른다.
Aliases
ㅡ> 별명
ㅡ> 같은 메모리 주소에 2개의 이름을 붙일 수 있다
ㅡ> 이런거 안쓰는게 좋다 (소프트웨어 공학, readability)
(p,q 그림)
■ Aliases가 발생하는 3가지 경우
- union type 사용했을 때
- pointer변수 (같은 주소, 2개의 포인터)
- 함수호출 (call-by-reference일 때, actual parameter와 formal parameter가 같은 주소 가리키게 됨)
(5.4) Binding
■ Binding
ㅡ> entity와 attribute의 결합
■ Entity
ㅡ> object : 실체가 있는 것
ㅡ> '세 살 버릇이 여든까지 간다'의 '사람'
ㅡ> 5장에서 말하는 entity는 변수
■ Attribute
ㅡ> 속성
ㅡ> '세 살 버릇이 여든까지 간다'의 '버릇'
ㅡ> 5장에서 말하는 attribute는 변수의 속성
■ Binding time
ㅡ> binding이 된 시점
ㅡ> '세 살 버릇이 여든까지 간다'의 '세 살'
(int i; 그림)
(5.4.1) Binding of Attributes to Variables
■ Static
ㅡ> 정적
ㅡ> 프로그램 시작부터 끝까지 type이 안바뀐다. (값은 바꿀 수 있음)
ㅡ> compile time때 binding
■ Dynamic
ㅡ> 동적
ㅡ> 프로그램 실행 중에 바뀐다
ㅡ> run time때 binding
■ Program life time
ㅡ> main시작 ~ 끝
(5.4.2) Type Bindings
Static Type Binding
C나 Java등 대부분의 언어
ㅡ> static type binding
ㅡ> 프로그래머가 명시적으로 타입 선언
90년대 중반까지는 대부분 static
Dynamic Type Binding
ㅡ> i란 변수에 int도 넣었다가, float도 넣었다가, char도 넣었다가 할 수 있다.
ㅡ> 변수에 대한 type선언이 의미가 없다.
ㅡ> 90년대 중반이후, web이 나타나고 script언어(javascript, python, php 등)사용 ▶ script언어는 Dynamic Type Binding과 인터프리터 사용
ㅡ> static은 컴파일러가 type에 따른 크기에 맞춰 메모리 공간을 할당하나, dynamic은 크기가 들쑥날쑥해서 pointer변수를 써야한다. ▶ 속도 느려짐 ▶ major 언어에서 안쓰는 이유
■ 2가지 단점
1. less reliable
ㅡ> static은 컴파일러가 type mismatch같은 오류를 찾는데, dynamic은 오류를 못찾음 ▶ error check (X)
ㅡ> (x=a+b; 에서 a와 x의 type이 다르면 type mismatch)
ㅡ> 제약이 심할수록 오류 잘찾음
2. 시간이 오래걸린다 (execution time cost)
ㅡ> 변수의 사이즈가 정해지지 않아서, 메모리에 고정정으로 할당해놓을 수 없음 ▶ pointer로 구현, 동적자료구조 ▶ 속도↓
ㅡ> 컴파일 방식보다는, 인터프리터 방식을 쓰는 언어들이다.
(5.4.3) Storage Bindings and Lifetime
프로그래밍이 실행되려면, 메모리에 instruction이 올라와야 한다.
program을 실행시키면, 운영체제가 파일시스템의 object 코드를 메모리에 올려준다.
변수에 대한 공간이 할당된다.
■ 변수에 대한 공간을 관리하는 방법 2가지
(그림)
1. Static
ㅡ> 프로그램 시작할 때 할당하고, 프로그램 끝날때까지 그 공간은 안바뀐다.
ㅡ> 전역변수
2. Dynamic
ㅡ> 필요에 따라 할당했다가, 사용이 끝나면 회수
ㅡ> 지역변수(함수안의 변수, 함수가 active됐을 때 할당)
Car pool
ㅡ> 여러사람이 자동차 공유해서 씀
Memory pool
ㅡ> 여러 프로그램이 공유하면서 씀 (heap)
■ 전역변수 (Global)
ㅡ> 프로그램 어디서나 사용
ㅡ> Static하게 할당
■ 지역변수 (Local)
ㅡ> 함수 안에서만 사용
ㅡ> Dynamic하게 할당
(5.4.3.2) Stack-Dynamic Variable
■ Stack Area
(그림)
- main함수가 A를 호출하면, Local 변수에 A라는 함수의 변수공간이 할당된다.
- Aㅡ>Bㅡ>C 순서로 호출되면, Stack 형태로 할당한다.
- 이 지역변수 영역을 OS에서 Stack Area라고 한다.
- Stack의 LIFO가 함수호출과 리턴 순서에 알맞다.
(5.4.3.3) Explicit Heap-Dynamic Variable
ㅡ> 실행시에 공간이 할당되기 때문에, pointer 변수로 접근
■ Heap Area
- 실행중에 만들어지는 메모리 공간
- 동적 자료구조
- C ㅡ> malloc 시스템콜 ▶ OS가 메모리 덩어리를 줌 ▶ pointer변수로밖에 관리가 안됨
- delete하면 공간 회수
- 함수호출 방법 : '함수(atual parameter)'
- system call : OS에서 제공하는 함수를 호출하는 것, 하드웨어 자원에 접근하기 위한 호출
- 하드웨어 자원 : CPU, 메모리, 입출력 장치
- Java ㅡ> S1 = new stack() ▶ S1은 포인터 변수, stack이란 인스턴스에 자료공간 동적으로 할당 ▶ Java는 사용이 끝난 공간을 프로그래머가 명시적으로 지울 수 없다. 그 공간을 Garbage라고 부른다. ▶ JVM에서 주기적으로 Garbage collection을 통해 회수한다.
■ 변수의 LifeTime
ㅡ> 메모리를 할당받고 있는 기간
ㅡ> Static : 프로그램 시작부터 끝
ㅡ> 지역변수 : 그 함수가 실행되는 기간
■ 지역변수 Static 선언
sort()란 함수가 종료돼서 지역변수 p를 회수됐을 때, 다음에 sort()를 다시호출하면 p의 값이 리셋되어있다.
그 값을 기억하고 싶으면, 지역변수를 Static으로 선언해야 한다.
(기본적으로 지역변수는 Dynamic으로 할당된다.)
Dynamic Type Binding하는데서는, 모든 자료구조가 heap dynamic처럼 관리가 된다.
ㅡ> pointer 변수로 관리
(5.5) Scope
■ visibility
프로그램 어느지점(함수)에서 어떤변수에 접근할 수 있느냐
사용 불가능한 변수쓰면 error
1. 전역 ㅡ> 어디서나 접근가능
2. 지역 ㅡ> 함수 안에서만 접근가능
■ 함수가 nesting(중첩)됐다
(global풍선 그림)
ㅡ> 함수안에 함수가 있다 (non-local 이라 부른다)
ㅡ> 자기 직계 parent의 변수에 접근할 수 있다.
■ C언어
ㅡ> nesting 없앰
ㅡ> 그래서 global, local밖에 없음
ㅡ> 대신, block을 만들 수 있다. ▶ block 안에서만 쓰는 변수 존재 ▶ nesting과의 차이는, block은 호출을 못한다는 것
■ Scope를 Static하게 정한다
프로그램 구조상에 의해 자동적으로 결정 (대부분의 언어)
Sum이란 변수를 쓴다고 치면, 컴파일러가 가까운데서부터 찾는다.
(mainㅡ>aㅡ> ..그림)
위에 호출된 C랑, 아래 호출된 C랑 scope가 같다. ▶ C함수가 어떤 과정을 통해서 불려왔건, C함수에서 쓸 수 있는 변수는 정해져 있다
■ Scope를 Dynamic하게 정한다
(일부언어)
(mainㅡ>aㅡ> ..그림)
C에서부터 sum을 찾음, 없으면 B, 없으면 A, 없으면 main
(5.5.1) Static Scope
Static Parent : 구조상의 부모
Scope Operator(스코프 연산자)
ㅡ> 접근못하는 scope에 접근하고 싶을 때
ㅡ> C++) 네임스페이스 쓸 때
ㅡ> ex) bigsub::sub
hidden이라는게 교재에 언급되어있고~
(5.5.2) Blocks
- 문장의 덩어리를 Block으로 나눈다.
- Block안에 자기만의 변수를 선언할 수 있다.
- ALGOL ㅡ> bigin ~ end
- C ㅡ> { ~ }
(5.5.3) Declaration Order
대부분의 언어에선 함수시작하면 지역변수 먼저 다 선언
일부언어에선, 위치가 자유롭다. ▶ 프로그램 중간에 변수선언 ▶ C99, C++, C#, Java,JS 등
(5.6) Scope and Lifetime
Global | Local | Non-Local | |
Lifetime | Static | Dynamic | Dynamic |
Scope | 전역 | 지역 | 지역 |
C언어 Static 선언 ㅡ> Scope는 지역변수인데 Lifetime은 프로그램 내내
Static과 Dynamic의 의미
Static | Dynamic | |
Lifetime | 프로그램 내내 할당 | 함수 살아있는 동안 할당 |
Scope | 구조에 의해 결정 | 호출 순서에 의해 결정 |
Type | 프로그래머가 타입선언, 고정 | 타입선언x, 계속 변함 |
(5.7) Referencing Enviroments
ㅡ> Scope와 관련된 얘기
내가 지금 접근할 수 있는 변수 ▶자기 것과, 조상의 것
(6-1 main abc active 그림)
(5.8) Named Constants
Constant = 상수
선언자
- const
- final (java)
- readonly
- 등등
///
casting 명시적 형변환, 강한타입검사
coersion 컴파일러가 자동으로, 약한타입검사
staic scope ㅡ> 구조에 의해 scope 결정, global, local, 부모자식
dynamic scope ㅡ> active한 함수 참조 mainㅡ>Aㅡ>Bㅡ>C, 가까운데서부터 찾는다. scope연산자쓰면 가까운거 아니어도 참조
Stack Dynamic Variables ㅡ> 함수호출 됐을때 지역변수 할당
Heap Dynamic Variable ㅡ> 동적 자료구조
'CS > 프로그래밍 언어론' 카테고리의 다른 글
[양PL] 7장 Expressions and Assignment Statements (0) | 2024.05.28 |
---|---|
[양PL] 6장 Data Type (0) | 2024.04.30 |
[양PL] 4장 Laxical and Syntax Analysis (0) | 2024.04.04 |
[양PL] 3장 Syntax와 Semantics (0) | 2024.03.28 |
[양PL] 2장 언어의 진화 (0) | 2024.03.18 |