티스토리 뷰

프로그래밍 언어론 - 식과 제어문

표현식(Expression)

  • 계산 표현의 기본 수단
  • 연산자, 피연산자, 괄호, 함수 호출 등으로 구성
    연산자(Operator)
  • 피연산자가 하나인 단항 연산자
  • 피연산자가 2개인 이항 연산자
  • C 기반 언어 삼항 연산자: (i%2) ? “홀수” : “짝수”
  • 대부분의 프로그래밍 언어에서 이항 연산자는 피연산자 사이에 위치합니다: x + y
  • LISP에서 연산자는 피연산자 앞에 위치합니다: (+ x y)

연산자 표기 방법

  • 중위 표기법(infix notation) :
    • 연산자가 피연산자들 사이에 위치하는 표기법
  • 전위 표기법(prefix notation)
    • 연산자가 피연산자들보다 앞에 위치하는 표기법
    • 예) 함수 호출 표기 : add(1, mul(2, 3))
  • 후위 표기법(prefix notation)
    • 연산자가 피연산자들보다 뒤에 위치하는 표기법

연산자 평가 순서

여러 개의 연산자로 이루어진 식에서는 연산자 평가 순서가 중요

  • 우선 순위, 결합 규칙, 그리고 괄호에 의해 결정

연산자의 우선순위

결합 규칙

연산자 우선순위가 같을 때 연산이 기본적으로 어디로 실행 되는가에 대해 말한다

  • 좌 결합 규칙 : 왼쪽에서부터 오른쪽으로 평가
  • 우 결합 규칙 : 오른쪽에서부터 왼쪽으로 평가


괄호 사용은 우선 순위와 결합 규칙에 관계없이 괄호 안의 연산이 먼저 평가 된다

  • 장점 : 모든 연산자의 평가 순서를 괄호로 표현하면, 우선순위나 결합 규칙을 기억할 필요가 없음
  • 단점 : 식의 작성을 지루하게 하고, 판독성을 떨어뜨림

피연산자의 평가 순서

아래의 코드는 연산 순서가 정해져 있지 않는 코드이다.

#include <stdio.h>

int x = 10;

int func(void) {
    x = 20;
    return 30;
}

int main(void) {
    printf("%d\n", x + func());
    return 0;
}

무엇을 먼저 계산하느냐에 따라 결과 값이 달라진다

이는 함수의 부작용으로 해결 할 수 있다.

  • 피연산자의 평가 순서에 따라 다른 결과가 나오는 문제를 해결하기 위한 방법
  • 함수에서 부작용을 일으키지 못하도록 하는 것
  • 피연산자의 평가 순서를 정해놓는 것
    • Java의 경우 피연산자들의 평가 순서를 왼쪽에서 오른쪽으로 지정해두고 있다.
public class Operand {
    static int x = 10;
    
    public static int func() {
        x = 20;
        return 30;
    }
    
    public static void main(String[] args) {
        System.out.println(x + func());
    }
}

단락 회로 평가

모든 피연산자와 연산자를 평가하지 않고도 식의 결과가 결정 되는 것을 의미한다

즉, 특정 경우 피연산자의 값에 따라 평가가 끝날 수 있습니다

  • 예시
    • true or x ➔ x의 값에 관계없이 true
    • false and x ➔ x의 값에 관계없이 false

단락 회로 평가를 지원하지 않는 경우의 예제

int data[5];   // Declaration of an integer array named 'data' with a size of 5 elements
int index = 0; // Initialization of the variable 'index' to 0

while (index <= 4 && data[index] != key) {
    index++;  // Incrementing the value of 'index' by 1
}

이미 index가 5가 되어 거짓임에도 연산이 계속 진행이 되어 배열의 첨자 범위를 이탈한다. 즉 오류가 발생한다

부작용을 포함하는 식의 경우의 예제
단락회로 평가를 조심해서 사용해야 한다.

  • 예제 코드 : (x > y) || (x++ % 2)
    두 번째 식은 x<=y인 경우에만 평가되므로 x 값 역시 x<=y인 경우에만 증가한다

각 언어별 단락회로 지원 사항

  • Pascal의 and, or은 단락회로 평가를 지원하지 않음
  • C, C++, Java의 &&, ||는 단락회로 평가를 지원
  • Ada는 단락회로 평가를 지원하는 연산자와 지원하지 않는 연산자를 구분

단락회로 평가를 하는 and then을 이용한 Ada의 예시 코드

while (index <= lastindex) and then (data(index) /= key) loop
	index = index + 1;
end loop;

중복 연산자

하나의 기호가 두 가지 이상의 목적으로 사용되는 연산자를 말한다

10 + 20;
1.2 + 3.14;
“Hello” + “world”

C++와 Ada처럼 프로그래머가 중복 연산자를 직접 정의해서 사용하기도 한다

  • 분수 곱셈을 하는 함수를 작성하고 함수의 이름을 *라 지정, 분수 곱셈 시 *를 사용할 수 있음

부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>

728x90

'Computer Science > 프로그래밍 언어론' 카테고리의 다른 글

정규 언어, 정규 문법, 유한 오토마타의 동치 관계  (0) 2023.05.28
NFA와 DFA  (0) 2023.05.28
오토마타  (0) 2023.05.23
프로그래밍 언어론 - 데이터 타입  (0) 2023.05.23
EBNF  (0) 2023.05.22