06. Control Flow - (1)

Jimin Lim·2021년 11월 2일
0

Programming Language

목록 보기
4/9
post-thumbnail

Control Flow

  1. Sequencing: 절차지향언어에서는 기본적으로 순차적으로 코드 실행
  2. Selection(alternation) : 조건문: 특정 런타임 컨디션에 의존함, 가장 자주 볼 수 있는 구조의 조건문은 if 와 case(switch) 문임
  3. Iteration : 반복문: 반복적으로 특정 부분의 코드가 실행됨 예로는 for/do, while, repeat문이 있음
  4. Procedural abstaction: control construct의 잠재적으로 복잡한 콜랙션을 단일 단위로 처리할 수 있는 방식으로 캡슐화하며 일반적으로 매개변수화의 대상이 된다. 예로는 함수, 클래스 등
  5. Recursion: 직접적 혹은 간접적으로 스스로에 의해 정의된 표현으로 복잡한 모델의 경우 식의 인스턴스를 부분적으로 판단하는 것과 관련된 정보를 스택위에 저장하는 것이 필요로 함

Exception handling and speculation

  • Exception Handling: 예외 사항 처리
  • Speculation: 원래 실행해야하는 것이 아닌데 CPU가 캐쉬 이용해서 미리 처리 → 실제 일어나야하지 않는 것을 실행 → undo, rollback

Concurrency & Nondeterminacy

  • Concurreny: 병행해서 처리, 여러 개 CPU
    • Paralle 병렬 처리: Single CPU 나눠서 씀
  • Non determinacy: 정해지지 않음
    • 실행 순서가 정확하게 정해지지 않음 → 어떤 순서로 실행되더라도 같은 값

6.1 Expression Evaluation

  • Expression: 표현식
    • 결과에 값이 생김 ( "abc", 32.7 (literal constant: 상수), const int a =3 (named variable: 변수 이름))
    • operator or function
  • Operator: 2+3, C++ → Operator + ()
  • Operand: 2,3
  • 대부분 절차 지향은, 함수 콜은 함수 이름 괄호, 콤마로 분리된 인자의 리스트
  • 연산자를 함수로 취급할 수도 → a+b (operator + (a,b)) : syntax sugar
  • 연산자 오버로딩
    • +2, -1, *p, &p, a++ : unary operators
  • Lisp: prefix notation
  • ML-family: 괄호 사용
  • R: infix - 새로운 연산자를 생성해줌
  • Smalltalk 은 모든 함수들을 위해 infix notation을 사용함(both built-in and user-defined)
  • Postfix notation

6.1.1 Precedence and Associativity

우선순위

  • 괄호가 없을때 특정 연산자가 먼저 계산
    • C 언어는 연산자가 많음 →, . 포함
    • Pacal: 간단
  • 산술 → 비교 → 논리 순서

결합 순서

  • Associativity rules
    • 432 = (4)^9 오 → 왼
  • 표현식
    • a = b = a+c : 오 →왼
  • Haskell: 사용자가 정할 수 있음
    • infixr 8 ^ (오 → 왼)
    • 0 ~9 레벨 지정

6.1.2 Assignments

  • functional 순수한 함수형 언어(연산 → 함수 → 함수 : 인자로 연결, 변수 조차 없음)의 경우 - Haskell Miranda
    • 값 어디다가 저장? f(2+3, 3*7+4) → 전달하고 끝남, 다른데에 사용할거면 애초에 변수에 저장 a=2+3
    • 그때 이외에 사용하지 않음
    • 항상 일정한 값이 나와야 함
    • ex) Hasekll, Miranda
  • Imperative(계속해서 값 변경): side-effect → 전체 값 바뀜, 다음 계산에 영향을 미침 - Python, C#, Ruby
    • expression: 값을 만들어냄
    • statements: side effect를 위해 존재 ⇒ 3;
    • 다른 결과 반환 side effect의 결과
    • 대다수 섞여 있음

References and values

Value Model of variables

  • 표면적으로 assignment는 직관적
  • 절차지향 언어에서 semantic 안에서 미묘하게 다른 점 존재

  • 공간에 값 복사
  • C언어의 변수는 값을 위한 지정된 컨테이너이다(named container)
    • l-value: 공간 (location)
      • 모든 표현식이 가능한건 아님 2+3 =a; → error, 주소값 없음
    • r-value: 변수의 값
    • (f(a) + 3)->b[c] = 2; : 복잡하게 표현 가능
      • 주소값 (ptr) → 구조체의 b의 변수에 c
    • f(a); void func(int k){};
      • k = a
    • C++ 에서 포인터 대신 g(a).b[c] = 2; 참조 가능
      • 구조체 자체를 넘김 필드에 b라는 배열

Reference model of variables

  • L value, R value 사이를 명확하게 해야함
    • 상황에 따라 reference, container 결정됨
  • Algol 68, Clu, Lisp/Scheme, ML, Smalltalk
  • 변수가 단순하게 값을 저장하는 named cotainer가 아님

  • Pascal → named container, Clu → named reference
  • 2라는 숫자가 어느 메모리를 차지하는데, b는 2의 주소를 담아라
    • c := b; l value 따름 b가 참조하는 곳을 c도 참조하게 해줘
    • a := b+c; r value 따름
    • 기본적으로 모두 l value임, 상황에 따라 dereferenced(r- value를 사용해야 할 것 같은 상황에 해당 value 얻어냄) 해야함 → Implicit, automatic/ (explicit: C 언어 → * , ML → !)
//2를 가리키고 있다가 4를 가리킴
b:=2
b:=4
//값 자체를 바꿈 -> 이렇게 가정
  1. 값 자체를 변경할 수 있다 → linked list 라고 가정
  2. 같은 값을 가지고 있는 다른 오브젝트가 있을 수 있다
    • b →2// c→2 라면 b→4, c→2 면 c에 영향 미치지 않음
  3. 같은 오브젝트를 가지고 있는지 구별 필요, (다른 오브젝트인데 우연히 같은 값인지 구별 필요)
    • 3의 경우 c는 영향 미침
  • r-value가 예상되는 컨텍스트에서 나타나는 경우 dereferenced 작업해야 참조되는 값을 얻어야 함.
  • 자바
    • value model: built in types (기본형)
    • reference model: user-defined, class types
  • C#, Eiffel 프로그래머가 고름
    • reference: class
    • value: struct

Boxing

  • 클래스 타입의 파라미터 인자를 기대하고 있는 메소드에 빌트인 타입을 전달할 수 없음
  • ArrayList: Object 타입 요소 가지도록 함

  • Wrap: built-in types→클래스
    • int - Integer, float - Float 클래스로 변환
    • 31 → new (Integer(31))
    • int → Integer → int 필요

  • 자동으로 boxing, unboxing 해줌 (자바 1.5)
    • boxing: int → Integer (기본 → 클래스)
    • unboxing: Integer → int (클래스 → 기본)
  • (java 1.5)Generics를 사용하면 마지막 줄의 (Integer)조차 없애줌
    ArrayList<Integer> list = new ArrayList<>();
    list.add(3); //컴파일러가 int, Integer만 넣을 수 있도록 해줌
    • 실질적으로 boxing 필요 (new Integer(3))
    • (Integer) list.get(0); 필요없어짐 → 컴파일러가 박싱, 언박싱 코드를 저장해줌
      • get자체가 Object 반환해줌
    • 마치 제네릭스를 사용하는 것처럼 사용할 수 있게 해줌
    • C#: 찐 제네릭스 → ArrayList 사용가능함

Orthogonality (일관성)

  • 공통적인 디자인 목표는 다양한 기능들이 일관성있도록 만드는 것이 목표
    • a를 배우면 같은 맥락의 b도 같게 동작
  • 언어의 기능이 어떠한 조합으로 만들더라도 사용할 수 있어야 함
  • Algol 68: 초창기 언어 중 하나
    • Orthogonality가 중요한 설계 목표
  • 다른 많은 언어 안에서 statement라고 부를 수 있는 문맥 속의 임의의 표현식
    • if문이 표현식 안에서도 사용할 수 있음
    • 표현식(expression), statement 차이가 없음

      1. 문장을 표현식처럼 씀 (a=(b<c)? d : e); → statement
      2. 블럭을 표현식에 넣음
      3. 함수: 표현식
      4. statement
  1. a = (b<c)? d:e; : 표현식

  2. 문장

    → 표현식 ↔ 문장

    • C언어는 표현식, statement 구분함
    • ; 붙는 순간 statement
    • (명령 언어) side effect → 2+3을 해놓고 저장을 해야 의미가 있는데, 이것을 가능하게 함 → 근데 가능은 함
  3. expression statement: 함수호출 → 표현식 ; → statement → 끝

    • 표현식에 statement;
    • 삼항 연산자 → statement와 expression 표현
    • ? (selection) ,(sequencing)
      • for (int i=0 , j=0)
    • algol 60 → 할당
      • :=
    • C
      • =

  1. 같으면 true
  2. b를 a에 넣었다가 0이 아니면 true
    • C언어의 자동 형 변환으로 인해서 문제 발생
    • java, C#는 2번의 경우 에러 발생 (Boolean context에 정수 타입 들어가는 것을 문법적으로 허용하지 않음)

Lack of Orthogonality in C

  • 구조체에서 변수를 선언하는 것은 가능, 함수 선언은 불가능
    • 구조체에 정수를 넣은건 되는데 정수자체는 안됨 등등
  • 자바는 Object 는 저장 가능하나 class는 불가
  • 대부분의 언어는 정수, 소수의 간단한 타입들만 배열의 인덱스 표시 허용
  • 대부분 언어들은 switch, case문의 경우 정수와 같이 간단한 타입만 가능
  • 어떠한 변수든 간에 assignment (=)의 왼쪽에 어떠한 변수가 와도 됨
    • 배열은 안됨
    • a[3], b[3] a=b 불가

Combination Assignment Operator

  • 자신에 자신을 넣음
  • +=, -=, *=
  • a = a+1 한다면 찾고 또 찾아야 함 (redundant address calculation)
    • 서로 다른 a에 할당될 수도 (side effect 문제)

  • 배열, 인덱스 생성 함수 전달

  • 다른 결과 값을 출력할 수 있음
  • i =4 전달 // A[9] = A[8] +1 (side effect로 인해) → 복합 대입 연산자 사용
  • 실행 속도 자체도 빠름, 같은 어드레스 주소 보장, side effect 문제 피함
A[--i] = b;
*p++ = *q++;
  • i —; A[i] = b

  • *p = *q; p++; q++

  • , : 순차적으로 진행 → 마지막이 반환

  • p주소값을 t에 저장 p의 다음 주소 이동, p의 원래 주소로 이동

    • (p의 old주소)= (q의 old주소)
  • ++, — 쓰지마래..

    • prefix: syntacic sugar
    • postfix: syntactic sugar

Multiway Assignment ( Clu, ML, Perl, Python, Ruby)

  • orthogonality 하지 않은 것을 제거 해줌
  • 함수 인자는 여러 개 → 반환 값은 하나 (C++, java 등등)

6.1.3 Initialization

  • Imperative 언어에서 변수를 선언하면서 초기화를 항상 하는 것은 아님
  • 함수 내부의 static의 경우 초기값이 있는 것이 필요 → a에 대한 값이 계속 유지됨 → y선언시 전역 메모리에 우선 할당될 수 있어서 초기 값을 할당하는 비용을 줄일 수 있음
  • 초기화를 하지 않은 상태에서 변수를 사용하면 에러 발생 커짐

대부분 언어는 초기값을 지정하는 방법 제공함 (built-in type)

  • 완성적이고, 일관적인(orthogonal) 접근 방법은?
  • aggregate(구조체, 배열)에도 해당
  • 초기화는 전역, static(정적) 변수에만 (컴파일시) 초기화되어야 한다.
    • data 영역
  • stack, heap 의 경우는 그럴 필요 없음

초기화하지 않았을 때 문제점

  1. 포인터에 의해서 레퍼런스되는 것을 deallocation
    • newp : 허상 포인터 (dangling pointer)
  2. variant record 수정 (c - union)
  • 가장 큰 변수의 공간만 만들어두고 하나만 쓰도록 함
    • 공유해서 쓰도록 함
  • type: tag
    • 4바이트만 쓰다가 (초기화되지 않은)8바이트 다쓰게 됨
  • 사용자가 임의적으로 초기화하지 않으면 default value 지정하기도 함
    • C: (statically allocated) 전역 변수, static(data 영역) 0으로 지정 or 0에 준한
    • 자바, C#(statically allocated): 클래스 안의 멤버 변수에 대해서 0에 준하는 값
    • 대부분 스크립트: 초기화

Dynamic Checks

  • 디폴트 값으로 초기화 값을 지정해주는 대신에 초기화되지 않은 값을 사용하면 semantic error 발생하기도
  • 장점: 런타임에서 catch 가능
    1. IEEE 기반의 컴파일러에서 부동 소수점 계산시 초기화가 되어 있지 않을 경우 NaN(Not a Number) value임을 알려줌
    2. NaN value 사용 시 하드웨어에서 이를 감지하고 semantic error message 발생
  • 단점: 시간도 많이 걸림. 단 하드웨어 지원이 적절치 않은 경우, 비용이 증가하고 오버헤드가 발생할 수 있음, 런타임에서 손해
  • 대부분 모든 초기화되지 않은 변수를 찾아내는 것이 손해 → 초기화 시키는 것이 좋음

Definite Assignment

  • 함수의 지역 변수들을 위해 definite assignment 사용
    • 초기화되지 않은 값을 사용하는 것에 대해 보완
  • conservative rule(보수적인 룰) 동작
  • 모든 변수에 값을 미리 할당

  • java의 경우 지역 변수는 초기화 시키지 않았음 (클래스 멤버 아님)
  • 초기화 안됐을 수도 있다고 에러
  • j 가 0보다 작을 수도 있는 경우 있음

Constructors

  • 동적으로 할당되는 변수들을 초기화해줌
  • C++: 초기화(생성자 호출), assignment 구별
    • initial 값이 생성자의 인자로 전달
    • coercion (자동 형변환) 이 부재할 경우 → assignment 연산자(함수) 가 없다 → bit-wise copy (그대로 붙임)
    • 정의 추상 데이터 타입을 위해서 특히 중요함
class A {
	public A(int a){
		g_a = a;
	}
	void operator = (int a){
		g_a = a;
	}
	private: 
		int g_a;
}

A a(3); //생성자 호출
A a = 3; //변수를 만들고 3을 넣는다 -> 생성자 호출

A a; //default 생성자 호출
a=3 //operator 호출 -> 없으면 bit wise copy ex) A = a; A b = a;
//생성자 호출, 대입은 다른일이 일어남
  • java, C# 구분하지 않음
    • A a = new A(b);
    • a = b;
      • java(reference model: assignment 할 때 값을 복사하는 것은 아님) → 주소 값 복사
      • c++ 내용을 복사하는 경우도 있음
        • A = a; A b = a; : 복사함
        • A a = new A; A b=a; 주소값 복사 (java, c#)
      • c#: value(struct), reference(class) 모델 선택 가능
profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

0개의 댓글