고수준 프로그래밍 언어(high-level programming language)
- 사람이 이해하기 쉬운 언어와 비슷한 형태의 프로그래밍 언어를 의미한다. 고수준 언어는 컴퓨터 하드웨어와 상대적으로 멀리 떨어져 있으며, 대부분의 사람들에게 친숙하고 이해하기 쉬운 개념들로 구성되어 있다.
고수준 프로그래밍 언어의 몇 가지 주요 특징은 다음과 같다:
- 추상화: 고수준 언어는 낮은 수준의 세부 사항을 숨기고, 개발자가 주로 문제 해결에 집중할 수 있도록 한다. 이러한 추상화는 개발자가 프로그램의 전반적인 로직에 더 많은 시간을 할애할 수 있게 해주며, 코드를 작성하고 디버그하는 과정을 간소화한다.
- 이식성: 고수준 언어로 작성된 프로그램은 일반적으로 여러 플랫폼에서 실행될 수 있다. 이는 고수준 언어의 프로그램이 특정 하드웨어나 운영 체제에 의존하지 않도록 설계되었기 때문이다.
- 생산성 향상: 고수준 언어는 개발자가 더 빨리 코드를 작성하고 수정할 수 있도록 설계되었다. 이는 언어의 추상화 수준이 높아져, 더 복잡한 작업을 명령문 한 줄로 수행할 수 있게 되기 때문이다.
- 유지 관리: 고수준 언어로 작성된 코드는 일반적으로 더 이해하기 쉽고, 수정하거나 디버그하기 편리하다. 이는 코드가 사람이 이해하기 쉬운 형식으로 작성되었기 때문이다.
고수준 프로그래밍 언어의 예로는 Python, Java, C++, JavaScript 등이 있다. 이러한 언어들은 다양한 영역에서 활용되며, 웹 개발, 데이터 분석, 인공 지능, 게임 개발 등 다양한 분야에서 사용된다.
컴파일러
- 고수준 프로그래밍 언어로 작성된 소스 코드를 컴퓨터가 이해할 수 있는 저수준 언어(일반적으로 기계어 또는 바이트 코드)로 변환하는 소프트웨어 도구이다. 이 변환 과정을 "컴파일"이라고 한다.
컴파일러는 일반적으로 다음과 같은 두 단계로 작동한다:
- 전처리 및 구문 분석 단계: 이 단계에서 컴파일러는 소스 코드를 읽고, 구문을 분석하여 추상 구문 트리(Abstract Syntax Tree, AST)라는 내부 표현을 생성한다. AST는 소스 코드의 구조와 의미를 반영하며, 이 단계에서 문법 오류가 발견되면 컴파일러는 오류 메시지를 출력한다.
- 코드 생성 및 최적화 단계: 컴파일러는 AST를 기계어나 바이트 코드와 같은 저수준 코드로 변환한다. 이 과정에서 컴파일러는 다양한 최적화를 수행하여 생성된 코드가 가능한 효율적으로 실행될 수 있도록 한다.
컴파일러의 주요 장점 중 하나는 소스 코드를 한 번 컴파일하면, 결과로 생성된 실행 파일은 별도의 컴파일 과정 없이 바로 실행할 수 있다는 것이다. 이는 인터프리터와 대조적인 점으로, 인터프리터는 소스 코드를 라인별로 해석하고 실행하기 때문에 실행 시마다 해석 과정이 필요하다.
또한, 컴파일러는 코드 최적화를 통해 프로그램의 실행 속도를 높이는 데 중요한 역할을 한다. 하지만 반대편으로는 컴파일 과정이 인터프리터에 비해 시간이 더 걸릴 수 있다.
컴파일러의 예로는 C의 GCC, Java의 javac, Python의 PyPy 등이 있다.
고수준 언어와 어셈블리 언어의 차이점
모두 프로그래밍 언어이지만, 그들의 추상화 수준, 사용 용이성, 이식성 등 여러 측면에서 중요한 차이점이 있다.
- 추상화 수준: 고수준 언어는 많은 수준의 추상화를 제공한. 이는 개발자가 프로그래밍 할 때 더 복잡한 작업을 단순한 명령문으로 수행할 수 있게 해준다. 반면에 어셈블리 언어는 저수준 언어로, 하드웨어에 가까운 명령을 사용한다. 이는 더 세밀한 제어를 가능하게 하지만, 동시에 코드를 작성하고 이해하는 것을 더 복잡하게 만든다.
- 사용 용이성: 고수준 언어는 일반적으로 코드를 작성하고 이해하는 것이 더 쉽다. 이는 고수준 언어가 일반적으로 사람이 이해하기 쉬운 형식과 문법을 사용하기 때문이다. 반면에 어셈블리 언어는 특정 CPU 아키텍처에 대한 깊은 이해를 요구하며, 문법이 사람이 이해하기 어렵다.
- 이식성: 고수준 언어로 작성된 프로그램은 일반적으로 여러 플랫폼에서 실행될 수 있다. 이는 고수준 언어가 특정 하드웨어나 운영 체제에 의존하지 않도록 설계되었기 때문이다. 반면에 어셈블리 언어로 작성된 프로그램은 특정 CPU 아키텍처에 맞게 작성되므로, 다른 아키텍처에서는 실행되지 않을 수 있다.
- 효율성: 어셈블리 언어는 저수준에서 동작하기 때문에, 필요한 경우 최적화를 위해 사용될 수 있다. 하지만, 이는 프로그래머가 하드웨어에 대한 매우 깊은 이해를 가져야 한다는 것을 의미한다. 반면에 고수준 언어는 자동화된 메모리 관리, 오류 검사 등의 기능을 제공함으로써 프로그래머의 작업을 단순화하지만, 이러한 편의성은 때때로 성능에 부정적인 영향을 미칠 수 있다.
요약하면, 고수준 언어는 개발자의 편의성과 코드의 이식성에 중점을 두고 있으며, 어셈블리 언어는 효율성과 세밀한 제어에 중점을 두고 있다. 그러나 최신 고수준 언어의 컴파일러는 상당히 효율적인 기계 코드를 생성할 수 있으므로, 대부분의 경우에는 어셈블리 언어를 직접 사용할 필요는 없다.
고수준 프로그래밍 언어는 어셈블리 언어에 비해 여러 가지 중요한 이점을 가지고 있다:
- 사용 편의성: 고수준 언어의 문법은 일반적으로 사람이 이해하기 쉽다. 이는 코드를 작성하고 이해하는 것을 더욱 쉽게 해주며, 프로그래밍 초보자가 학습하기에도 더 적합하다.
- 시간 효율성: 고수준 언어는 코드를 빠르게 작성하고 수정하는 데 유용하다. 복잡한 작업을 몇 줄의 코드로 수행할 수 있기 때문에 개발 시간이 크게 단축된다.
- 이식성: 고수준 언어로 작성된 프로그램은 여러 플랫폼에서 실행될 수 있다. 즉, 한 번 작성하면 다양한 컴퓨터 아키텍처에서 실행할 수 있다. 반면에, 어셈블리 언어로 작성된 코드는 특정 하드웨어에 대해 작성되므로 이식성이 낮다.
- 오류 발견 및 디버깅 용이성: 고수준 언어는 문제 발생 시 오류 메시지를 제공하거나 디버깅 도구를 사용하여 문제를 쉽게 찾고 수정할 수 있다. 어셈블리 언어에서는 이러한 프로세스가 훨씬 더 복잡하고 어려울 수 있다.
- 추상화: 고수준 언어는 메모리 관리, 가비지 컬렉션, 보안 기능 등과 같은 중요한 작업을 자동으로 처리한다. 이는 개발자가 복잡한 세부 사항에 신경 쓸 필요 없이 문제 해결에 집중할 수 있게 해준다.
- 풍부한 라이브러리 및 프레임워크: 고수준 언어는 웹 개발, 데이터베이스 접근, 그래픽 처리, 기계 학습 등과 같은 많은 작업을 위한 라이브러리와 프레임워크를 제공한다. 이는 개발자가 코드를 빠르게 작성하고, 기존의 테스트된 코드를 재사용할 수 있게 해준다.
이런 이점들 때문에, 대부분의 현대 소프트웨어 개발은 고수준 언어를 사용하여 진행된다. 그러나 어셈블리 언어는 특정 작업에서 최고의 성능을 필요로 할 때, 혹은 하드웨어에 매우 가까운 수준에서 작동해야 할 때 여전히 중요할 수 있다.
프로그래밍 언어는 기본적으로 컴퓨터에게 명령을 내리기 위한 도구이며, 언어마다 공통적인 요소와 독특한 특징이 있다.
프로그래밍 언어 간의 일반적인 유사점은 다음과 같다:
- 기본적인 구성 요소: 대부분의 프로그래밍 언어는 변수, 연산자, 조건문, 반복문, 함수 등과 같은 기본적인 구성 요소를 갖고 있다. 이러한 요소들은 데이터를 조작하고, 로직을 제어하며, 코드를 재사용 가능한 단위로 구조화하는 데 사용된다.
- 명령적 프로그래밍: 대부분의 언어는 명령형 프로그래밍 패러다임을 따른다. 즉, 프로그램은 일련의 명령으로 구성되며, 이 명령은 순서대로 실행된다.
- 타입 시스템: 대부분의 프로그래밍 언어는 타입 시스템을 가지고 있다. 이는 프로그래머가 데이터의 종류를 지정하고, 프로그램이 예상대로 동작하도록 돕는다.
프로그래밍 언어 간의 주요 차이점은 다음과 같다:
- 문법: 프로그래밍 언어마다 자체의 고유한 문법을 가지고 있다. 이는 언어를 배우고 사용하는 데 중요한 역할을 하며, 개발자의 선호도와 작업의 특성에 따라 선택하는 언어가 달라질 수 있다.
- 프로그래밍 패러다임: 언어는 명령형, 객체 지향, 함수형, 논리형 등 다양한 프로그래밍 패러다임을 지원할 수 있다. 이러한 패러다임은 언어가 문제를 해결하는 방식을 크게 영향을 미친다.
- 성능과 용도: 언어마다 성능과 용도에 있어 차이가 있다. 예를 들어, C++와 같은 언어는 시스템 프로그래밍이나 게임 개발에서 선호되며, Python은 데이터 과학과 웹 개발에서 널리 사용된다.
- 타입 체크: 일부 언어는 컴파일 시간에 타입을 검사하는 반면(예: Java, C++), 다른 언어는 런타임에 타입을 검사한다(예: Python, JavaScript).
- 메모리 관리: 일부 언어(예: C, C++)는 개발자가 메모리를 직접 관리해야 하는 반면, 다른 언어(예: Java, Python)는 가비지 컬렉션 등의 자동 메모리 관리 기능을 제공한다.
이와 같은 유사점과 차이점을 이해하면, 어떤 언어가 특정 작업에 가장 적합한지 결정하는 데 도움이 될 수 있다.
특정 프로세서 아키텍처에 독립적인 고수준 프로그래밍 언어의 개발이다. 고수준 언어를 쓰면 사람이 표현하는 방식에 가까운 용어로 계산 과정을 작성할 수 있다.
고수준 언어로 작성된 코드는 번역기 프로그램을 통해 대상 프로세서의 어셈블리 언어로 된 명령어로 변환한 다음, 어셈블러에 의해 비트로 변환되어 메모리에 로드되고 실행된다.
번역기 프로그램은 보통 컴파일러라고 불리는데, 그다지 통찰력이나 직관이 느껴지지 않는 역사적 용어이다.
일반적인 고수준 언어에서는 두 수 X와 Y를 더하고 결과를 Z에 저장하는 계산이 다음과 같이 표현한다.
Z=X+Y
X와 Y라는 메모리 위치에서 값ㅇ르 가져와서, 두 값을 더하고, Z라는 메모리 위치에 결과를 저장한다.
연산자 ‘=’는 같다가 아니라 대체한다 or 저장한다라는 뜻이다.
모형 컴퓨터용 컴파일러는 이 코드를 세 개의 명령어로 변환하겠지만, 또 다른 컴퓨터용 컴파일러는 두 개의 명령어로 변환할 수도 있을 것이다.
다음으로, 각 어셈블러는 각자의 어셈블리 언어 명령어를 실제 명령어의 비트 패턴으로 변환하는 일 뿐만 아니라 변수 X, Y, Z를 저장할 메모리 이치를 확보하는 일을 담당한다. 비트패턴은 각각의 컴퓨터의 대해 거의 완전히 다르게 변환된다.
실제로 컴파일러가 내부적으로 하나의 ‘프런트 엔드’와 몇 개의 ‘백엔드’로 나뉠 가능성이 있다.
프런트 엔드는 고수준 프로그래밍 언어로 작성된 프로그램을 처리해서 어떤 중간 형태로 만들고, 각 백엔드 엔드는 공통된 중간 표현을 특정 아키텍처에 맞는 어셈블리 언어로 변환한다. 이 구조는 완전히 독립적인 여러 개의 컴파일러를 이용하는 것보다 단순하다.
고수준 언어는 어셈블리 언어에 비해 큰 이점을 갖는다.
- 사람들이 생각하는 방식에 더 가까워 배우고 사용하기 더 쉽다.
- 고수준 언어에서는 프로그램을 효율적으로 짜기 위해 특정 프로세서의 명령어 레퍼토리를 알아야 할 필요가 없다. 따라서 더 많은 이들이 더 빨리 프로그래밍을 할 수 있게 해준다.
또한 고수준 언어로 작성된 프로그램은 특정 아키텍처에 종속되지 않는다. 그래서 같은 프로그램이 여러 아키텍처상에서 실행될 수 있다. 보통은 코드를 변경할 필요도 없으며, 위 그림처럼 다른 컴파일러로 컴파일하기만 하면된다.
컴파일 단계는 몇 가지 명백한 에러를 미리 점검하게 해준다. 철자 오류, 괄호 불일치 같은 구문 오류, 정의되지 않은 변수에 대한 연산 같은 것들이 포함됨
어셈블리 언어 프로그램에서 구문 오류 이외의 에러는 검출하기 어렵다. 어셈블러는 명령어의 실행 순서까지는 상관하지 않아서 논리적인 흐름이나 전후 관계를 파악하지 못하기 때문이다. (고수준 언어에서도 구문상 올바르다고 판단되는 프로그램이 여전히 컴파일러가 검출할 수 없는 에러로 가득할 수도 있다.)
프로그래밍 언어 간의 유사점과 차이점을 살펴볼 수 있도록 가장 중요한 고수준 프로그래밍 언어 여섯 가지로 작성된 동일 기능을 볼 수 있다.
컴파일러
- 고수준 언어를 어셈블리 언어로 변환하는 번역기 프로그램(책 설명)
컴파일러 VS 인터프리터
컴파일러 | 인터프리터 | |
정의 | 고수준 언어로 작성된 프로그램 전체를 목적 프로그램으로 번역한 후, 링킹작업을 통해 컴퓨터에서 실행 가능한 실행 프로그램을 생성 | 고수준 언어로 작성된 프로그램을 한 줄 단위로 받아들여 번역하고, 번역과 동시에 프로그램을 한 줄 단위로 즉시 실행 |
장점 | 반복 처리가 많을 경우, 번역과 실행 과정을 거쳐야 하기 때문에 번역 시간이 오래 걸리지만, 한 번 번역한 후에는 다시 번역하지 않으므로 실행 속도가 빠르다 | 번역 시, 그때그때 필요한 실행 코드를 생성하므로 사용하는 메모리가 적어 별도의 기억 공간이 적게 필요. 줄 단위로 번역 실행되므로 시분할 시스템에 유용, |
단점 | 컴파일 시 전체 프로그램 코드가 생성되므로 사용하는 메모리가 많아짐 → 별도의 많은 기억 공간 필요 | 반복 처리가 많은 경우, 번역 속도는 빠르지만 프로그램 실행 시 매번 번역해야 하므로 실행 속도는 느림 |
언어 | C, C++, Java, COBOL, FORTRAN | R, Rython, Ruby |
실행 속도 | 빠름 | 느림 |
번역 속도 | 느림 | 빠름 |
'CS > 1일 1로그 100일 완성 IT 지식' 카테고리의 다른 글
28로그 - 구글 같은 서비스는 어떻게 개발할까? (0) | 2023.06.29 |
---|---|
27로그 - 작문과 비슷한 프로그래밍 (0) | 2023.06.29 |
25로그 - 다른 프로그램을 처리하기 위한 프로그램 (0) | 2023.06.29 |
24로그 - 알고리즘은 이상, 프로그래밍은 현실 (0) | 2023.06.16 |
22로그 - 10개 도시를 최단거리로 여행하는 법 (0) | 2023.06.15 |