정적타입과 동적타입

정적타입과 동적타입은 프로그래밍 언어에서 자료의 형태를 말합니다.

 

타입에 따라 변수의 저장공간이 컴파일시에 확정되거나 런타임에서 확정됩니다.

 

컴파일 언어와 스크립트 방식으로 프로그래밍 언어의 종류를 나누는 기준이 되기도 합니다.

 

먼저 동적타입을 보겠습니다.

 

1. 동적타입

 

아래는 파이썬의 함수입니다.

def add(a, b):
    return x + y

파이썬은 동적타입 언어입니다. 이 함수를 보면 매개변수와 반환값에 대한 정의가 없습니다.

 

정수형인지, 소수형인지, 문자형인지 아니면 클래스 타입인지 알수가 없습니다.

 

이것은 타입(type)이 컴파일시에 결정되지 않고 실행시간에 결정되기 때문입니다.

 

문법적으로는 유연하게 사용할 수 있겠죠.

 

숫자뿐만아니라 형변환을 하면 문자와 숫자도 더할 수 있습니다.

 

이러한 사용법은 정적 언어에서는 사용할 수 없는 방법입니다.

 

def add(a, b):
    return a + b

print(add(1, 2))
print(add(True, 3))
print(add(1, 1.5))
print(add("number-", str(1)))
3
4
2.5
number-1

 

동적타입 언어에서는 런타임에서 함수를 호출하기 전까지 무슨 자료형이 들어갈지 알 수 없습니다.

 

그 때 가서야 값이 결정되기 때문입니다. 한 줄의 코드를 쓰고 한 줄의 실행을 하는 스크립트 언어의 특성에 잘 맞는 부분인데요, 타입을 미리 알 수 없으니까 아무래도 오류에 취약하고 최적화가 안되니까 성능이 떨어지는 부분이 있습니다.

 

반면 컴파일 방식의 정적타입은 컴파일시 자료형이 결정됩니다.

 

아래는 C언어의 함수입니다. 파이썬과 다른 점은 매개변수와 반환형이 int 로 정적이라는 것입니다.

int add(int a, int b)
{
    return a + b;
}

이 함수는 정수형과 소수형을 더하거나 문자열과 더할 수 없습니다.

 

그러한 시도는 컴파일 단계에서 차단됩니다.

 

컴파일 단계에서 가능한 범위를 확 줄여버리니 당연히 런타임 오류도 없습니다.

 

사용의 유연성은 동적타입이 좋은데 왜 정적인 타입을 사용할까요?

 

- 컴파일 단계에서 모든 가능성이 미리 확인되기 때문에 코드는 최적화 되고 메모리를 최소화하여 사용할 수 있습니다.

 

더 작고 더 빠르죠.

 

요즘 시대에 컴퓨터 성능이 좋아졌다고 하지만 여전히 정적 타입 언어인 C, C++, 자바 등의 성능이 스크립트 언어의 동적타입보다 뛰어납니다.

 

C#같은 일부 프로그래밍 언어에서 동적할당 기능을 후에 추가하기도 했지만 스크립트 언어와는 근본적인 구조가 다르죠.

메모리 관리방식

정적타입의 변수는 스택 메모리를 기본으로 사용하고 동적할당을 통해 힙메모리를 사용합니다.

 

동적타입 변수는 처음부터 힙 메모리를 사용합니다.

 

변수이름

print(locals())
{'__name__': '__main__', '__doc__': None, '__package__': None, 
'__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0118AF58>, 
'__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 
'__cached__': None, 'add': <function add at 0x01197778>, 'a': 10, 'b': 10}

 

동적타입 언어에서는 변수의 이름들이 메모리에 함께 저장됩니다.

 

런타임에서 생성되기 때문이죠.

 

정적 타입에서는 디버깅 목적으로 생성하지 않는 한 변수의 이름은 메모리에 저장되지 않습니다.

 

변수의 이름은 소스코드에서 프로그래머가 사용하는 것이고 런타임에서는 주소를 사용합니다.

 

이것은 컴퓨터가 변수를 구분하는데 굳이 문자열을 사용할 필요가 없기 때문입니다. 

 

변수가 있는 주소로 바로 가서 값을 가져오는데 문자열 이름은 불필요합니다.

 

컴파일러는 지역변수, 전역변수와 같은 정적 변수들을 관리할 테이블을 가지고 있습니다.

 

테이블이 한번 정해지면 변동이 없기 때문에 정적입니다.(static)

 

동적인 언어에서는 런타임에서 매번 메모리의 위치도 달라지고 또 언제 변수가 새로 생성되거나 소멸할지 모르기 때문에 동적입니다(dynamic)

 

이런 경우에는 코드를 실행하는 인터프리터가 그냥 변수의 이름을 저장해서 사용합니다.

공유하기

facebook twitter kakaoTalk kakaostory naver band