본문 바로가기
컴퓨터 일반

8. 프로그래밍 언어

by 쬑께께 2026. 1. 25.

프로그래밍 언어의 개요

1. 프로그래밍 언어의 의의

- 프로그래밍 언어: 컴퓨터 시스템을 동작시키는 프로그램을 작성하기 위한 언어

- 인간과 컴퓨텃 사이의 의사소통 위한 방법, 만들어진 언어를 컴퓨터 프로그래밍 언어라 함

- 초기의 프로그래밍 언어: 기계가 쉽게 해독하여 명령 실행할 수 있는 기계중심 언어 -> 사람이 쉽게 작성할 수 있는 사람 중심의 언어(고급 언어)

 

2. 프로그래밍언어의 정의

- 프로그램: 논리적⋅산술적, 신속하게 처리해야 할 기능들을 프로그램 언어로 구현한 명령어와 관련 데이터의 집합체

- 프로그래밍 언어: 사람이 컴퓨터에 작업절차를 알려주는 데 사용되는 기호체계, 컴퓨터에 작업을 지시할 수 있는 추상 모형을 구현하는 도구

- 기계가 읽을 수 있고, 사람이 읽을 수 있는 형식으로 계산을 서술하기 위한 표기체계

 

프로그래밍 언어의 분류

- 사용목적에 의한 분류

범용 언어 - 응용 분야가 제한되지 않음
- BSSIC, Pascal, C언어, C++
과학응용 분야 - 간단한 데이터구조, 효울성 강조
- FORTHRAN, ALGOL60
사무응용 분야 - 상세한 보고서 생성 간으, 십진수 산술 연산 표현
- COBOL
인공지능 분야 - 수치계산보다는 기호체계 사용, 융통성 가옺
- LISP, Prolog
시스템 프로그래밍 - 운영체제와 컴퓨터시스템에 속한 모든 프로그래밍 지원도구
- 실행 효율성 및 저급 수준의 처리 필요
- PLS, BLISS, ALGOL, C언어
스크립트 언어 - 파일 관리나 필터링 등이 수행을 위해 사용되기 시작함
- 스크립트라 불리는 명령들의 리스트를 한 개의 파일에 작성
- Perl, ASP, PHP, JSP, JavaScript 

- 저급언어와 고급언어

저급언어 - 기계어, 어셈블리어
고급언어 컴파일 언어: FORTHRAN, COBOL, ALGOL, PL/I, PASCAL, C, ADA 등
인터프리터 언어: BASIC, APL, SNOBOL, LISP 등

 

프로그래밍 언어에서의 추상화

1. 추상화(Abstraction)

- 속성들의 일부분만을 가지고 주어진 지겅ㅂ이나 객체들을 필요한 정도로 묘사할 수 있는 방법을 지원하는 것

- 필수적인 속성만으로 주어진 것을 묘사하므로 나머지 속성들은 추상화되거나 숨겨지거나 삭제됨

- 추상화의 범주

자료 추상화 - 문자열, 수, 탐색 트리와 같은 계산의 주제가 되는 자료의 특성을 추상화
제어 추상화
(알고리즘 추상화)
- 실행 순서의 수정을 위한 제어의 특성을 추상화
- ex) 반복문, 조건문, 프로시저 호출 등
추상화에 포함된
정보의 양에 따른 분류
기본적 추상화
(basic abstraction)
- 가장 지역적인 기계정보에 대한 추상화
구조적 추상화
(structured abstraction)
- 보다 전역적인 정보인 프로그램의 구조에 대한 추상화
단위 추상화
(unit abstraction)
- 단위 프로그램 전체에 대한 정보의 추상화
자료 추상화 기본적 추상화 - 컴퓨터 내부 자료 표현 추상화
구조적 추상화 - 관련된 자료의 결합을 추상화
단위 추상화 - 자료의 생성과 사용에 대한 정보를 한 장소에 모아 두고, 자료의 세부ㅏㅅ항에 대한 접근을 제한하는 도구
제어 추상화 기본적 추상화 - 몇 개의 기계 명령어를 모아 이해하기 쉬운 추상 구분으로 만든 것
구조적 추상화 - (검사 값에 따라) 분할된 명령어 그룹 수행
단위 추상화 - 프로시저의 집합을 추상화(관련된 프로시저 그룹 추상화)

* 추상화

  자료 제어
기본 변수 배정문, GOTO문
구조 배열, (구조체) 레코드 선택문, 반복문, 복합문, 부프로그램
단위 클래스

 

 

프로그래밍 언어 전형: 계산정형(Compulational Paradigms)

1. 명령형 언어(imperative L.) = 절차적 언어(procedural L.)

- 전통적인 프로그래밍 언어로 폰 노이만 구조에 기초하여 문제 해결을 위한 절차 기술

- 명령의 순차적 실행

- 기억 장소로 표시하는 변수의 사용

- 변수의 값을 변경하기 위한 배정문의 사용

 

2. 함수형 언어(functional L.) = 적용형 언어(applicative L.)

- 함수의 평가와 함수 적용을 기본으로 함

- 함수의 평가 및 호출 방법을 제공

- 지역변수, 반복문, 배정문이 없음

- 반복적인 연산은 재귀적 함수 이론에 의해 기술됨

- ex) LISP, Schema, Common LISP, ML 등

 

3. 논리형 언어(logical L.) = 선언적 언어(declarative L.)

- 모델의 계산을 위해 기호논리와 집합론을 이요해 술어논리에 기초

- 기호 논리학에 근거

 

4. 객체지향 언어(object - oriented L.)

- 객체에 기반을 둔 언어

- 객체(상태를 의미하는 기억장소)와 연산(상태 변경 가능)의 집합

- 객체: 클래스로 그룹화

- 클래스 선언: C나 Pascal 에서 구조형 자료를 선언하는 방법으로 선언

- 클래스 인스턴스: 선언된 객체의 한 상태

- 객체지향의 방법을 처음 소개한 언어: simula 67

- 순수 객체지향 언어에 가까운 언어: Simula, Smalltalk

- 최근 많이 사용되는 언어: C++, JAVA, Eiffel, Ada95 등

 

세대별 언어

제 2세대 언어 (1960년대)

FORTRAN - FORTRANⅠ의 기능에 주프로그램과 부프로그램 사이에 자료전달이 가능하게 CALL, COMMON, FUNCTION, RETURN 등의 명령을 추가시켜 만든 FORTRAN Ⅱ 발표
- 1960년대에 들어와 FORTRAN Ⅲ, FORTRAN Ⅳ로 발전 -> 과학계산용 언어로 확고한 위치 굳힘
- 1970년대에 다양한 기능 갖춘  FORTRAN 77나옴
COBOL - 사무처리용 언어로 개발된 프로그래밍 언어
ALGOL - ALGOL 58은 보다 발전된 형태로 1960년에 ALGOL 60으로 발표됨
- ALGOL 60은 언어의 발달사에 큰 영향을 끼친 언어
- 최초의 블록구조 언어 -> 구조적 프로그래밍에 도움을 줌
- 언어 구문의 형식을 정의하는 기법인 BNF(Backus Naur Form) 표기법을 최초로 사용 -> ALGOL 구문을 정의
- 언어의 구조가 통일성 있게 명확함
SNOBOL - String(문자열)을 손쉽게 처리하기 위해 개발
- 문자열 연산 위해 여러가지 함수와 스트링, 배열, 테이블 등의 자료형 제공
PL/1 - 이미 개발되어 사용 중인 PORTRAN, COBOL, ALGOL 등의 언어를 연구하여 각 언어의 장점을 모두 포함시켜 만든 언어 -> 프로그래밍 언어로서 큰 각광 받을 것으로 전망되었으나, 기대만큼 활용되지 못함
- 다양한 기능을 갖고 있으나 지나칠 정도로 선택이 많고, 컴파일러의 구성이 다양한 기능만큼 복잡하고 방대하기 때문
APL - 수학 계산 및 자료처리를 목적으로 개발된 언어 -> 이후 스칼라, 벡터, 행열 등의 연산에 알맞도록 개선됨
- 자료처리 시 배열을 기본 원소로 하기 때문에 전문적인 배열처리가 가능하며, 배열의 크기를 실행시간에 가변적으로 처리할 수 있음

 

제 3세대 언어(1970년대)

- 새로운 이론, 새로운 언어 개발보다는 복잡한 대형 프로그램을 처리할 수 있는 도구를 개발하는데 중점을 둔 시기

- 모듈화, 블록구조를 지원하는 프로그래밍 언어가 개발된 시기

PASCAL - ALGOL W의 후속 언어
- 범용 및 교육용으로 체계적인 프로그래밍에 대한 개념을 가르치고, 효율적이고 안정된 소프트웨어 구현 위해 개발된 언어
C 언어 - UNIX에 운용조직에 사용하기 위해 개발된 시스템 프로그래밍 언어
- 기종에 관계없이 텍스트 처리, 수치해석, 데이터베이스 개발 등에 사용할 수 있는 범용적인 프로그래밍 언어
Ada - 미 국방성 지원 아래 개발된 언어
- 시스템 프로그래밍, 수학문제처리, 실시간처리, 병렬처리 등에 응용할 수 있는 기능 가지고 있음
CLU - 추상화 기법을 사용
- 일관성 있는 접근 방식
- 자료 추상화, 제어 추상화 방식 제공
ML(Meta Langguage) - 언어는 간결하나 확장성에 의해 대행 프로그램의 개발이 가능함
Prolog - 선언적인 논리언어
- 논리 프로그래밍 언어를 대표하는 주요 언어
- 인공지능 분야, DB 설계, S/W 공학, 자연어 처리 등에 널리 사용
C++ - C 언어의 기능을 확장해 만든 객체 지향 프로그래밍 언어
Python
= 멀티패러다임 언어
- 객체지향 인터프리터 스크립트 언어
- 바이트코드는 기계에 독립적 -> 다른 하드웨어나 소프트웨어 플랫폼에서 재컴파일 없이 수행됨
- 매우 간단한 문법 사용 -> 사용하기 쉬움, 배우기 쉬움
- 강력한 기능 가지고 있어 빠른 프로토타입 개발 가능

 

 

언어처리기

1. 번역과정

- 기계어 제외한 모든 언어는 기계가 직접 이해할 수 있도록 기계어로 바꿔주는 번역 과정 필요

- 주어진 고급 프로그래밍 언어로 작성된 프로그램을 실제 주어진 컴퓨터의 기계어로 번역하여 동등한 의미의 기계어 프로그램을 만들어 실행시키는 방법

- 언어번역기: 어떤 원시언어(저급언어, 고급언어)로 작성된 프로그램을 입력으로 읽어들여 목적언어로 된 동일한 프로그램을 출력해주는 언어처리기

- 프로그래밍 번역기 종류

컴파일러 - 컴파일 언어로 작성된 원시프로그램을 준기계어로 번역 -> 목적프로그램을 출력
- 원시언어 = 고급언어, 목적언어 = 실제 기계언어에 가까운 저급언어
- 기계어로 번역된 목적프로그램은 컴퓨터가 해독할 수는 있지만 주기억장치 내에서 직접 실행할 수 없음 -> 목적프로그램은 실행 가능한 형태의 프로그램으로 바꾸는 작업이 필요 <= 이 작업을 해주는 프로그램: 연계편집프로그램 또는 링커
= 링커에 의해 만들어진 실행 가능한 프로그램: 로드프로그램
- COBOL, C언어, C++, Fortran, Ada, PL/I, Algol
- 원시프로그램  -(컴파일러)->  목적프로그램(기계어 형태)  -(링커)->  로드프로그램(실행 가능한 형태)
인터프리터 - 고급언어를 기계어로 하는 컴퓨터를 하드웨어로 구성하는 대신, 이 고급언어를 기계에서 실행되도록 소프트웨어로 시뮬레이션하여 구성하는 방법
- 원시프로그램을 구성하는 각 명령을 기계어로 변형하여 즉시 실행시키는 것으로 별도의 목적프로그램을 생성하지는 X
= 원시프로그램 내에 반복 실행되는 부분도 실행 시마다 기계어로 번역해야 함 -> 컴파일 언어보다 더 많은 실행 시간 필요로 함
- 프로그램 길이가 짧고 단순할 때 많이 사용됨
- BASIC, APL, LISP, SNOBOL
- 원시프로그램(BASIC)  -기계어로 번역(인터프리터)->  프로그램 실행
크로스
컴파일러
- 어떤 컴파일 언어로 작성된 원시프로그램을 현재 자신이 수행되는 기계와는 다른 기계의 목적 프로그램으로 번역하는 컴파일러
사전 처리기
(Preprocessor)
- 특정 고급언어로 작성된 프로그램을 다른 고급언어로 번역해서 출력하는 번역기
* 원시 언어와 목적 언어가 모두 고급언어의 번역기
- C언어의 전처리 과정이 여기에 속함
- 고급언어 원시프로그램  -사전처리기->  다른 고급언어 원시프로그램  -컴파일러->  목적프로그램
매크로
프로세서
- 어셈블리 원시 프로그램에 매크로 명령이 있으면 해당 매크로 명령에 대응하는 원래의 명령을 매크로 위치에 대치시키는 기능을 가진 소프트웨어

 

- 컴파일러 기법과 인터프리터 기법 비교

  컴파일러 기법 인터프리터 기법
공통점 고급언어로 작성된 원시프로그램을 입력으로 사용
실행방식 입력프로그램을 동일한 목적 언어로 된 프로그램으로 출력 입력프로그램을 직접 실행
특징 - 효율성을 강조한 고속 처리
- 번역 시 기억장소가 확정되는 정적 자료구조
- 목적 프로그램 생성
- 융통성을 강조한 저속 처리
- 실행 시 자료구조가 변하는 동적 자료구조
- 목적 프로그램 생성 X
처리과정 입력 프로그램의 매 문장을 한 번씩 처리 계속 반복처리
기억공간 목적코드가 메모리에 들어가야함 -> 기억 공간이 많이 필요 한 명령어만 메모리에 들어감 -> 기억 공간 적게 필요
사용언어  COBOL, C 언어, Fortran, PL/I, Algol BASIC, APL, LISP, SNOBOL

 

논리식의 계산 순서

- 단일 평가방법: 성능 떨어짐

- 단락 회로 평가(Short - circuit evaluation): 논리식에서 왼쪽에서 오른쪽으로 식의 값을 계산하는 도중, 식의 나머지 부분을 계산하지 않고도 식의 값이 결정되면 계산을 중지할 수 있음

 

구조적 프로그래밍

- 프로그래밍 내에 GOTO문을 사용함으로써 발생되는 문제점을 없애기 위해 시작됨

- GOTO문을 가능한 사용하지 않고 프로그래밍하는 것을 구조적 프로그래밍의 기본이라고 할 수 있음

- 1. GOTO문을 가능한 사용하지 않고 프로그램을 작성

- 2. 논리구조는 순차, 반복, 선택만을 사용해 프로그램을 작성

- 3. 프로그램 설계는 위에서 아래로 하향식 기법으로 하고, 처리 내용은 기능별로 분할하여 모듈 단위로 구성

- 4. 각 모듈은 하나의 입구와 출구를 가지게 하며, 모듈별로 가능한 독립적이 되도록 함

- 5. 프로그램의 외관적인 형태도 구조적이 되도록 코딩함

- GOTO문의 장단점

장점 - 완전한 범용성
- 이론적으로 거의 모든 알고리즘은 GOTO문만으로 표현 가능
단점 - 프로그램이 빈약하게 설계
- 디버깅이 어려움
- 프로그램을 이해하기 어려움
- 가독성이 낮아져 유지보수 비용이 많이 듦

 

객체 지향(Object Oriented)

- 실세계의 개체를 속성과 메서드가 결합한 형태의 객체로 표현하는 기법

- 상속성, 상향식 방식, 캡슐화, 추상데이터형을 이용

- 소프트웨어 설계 개념의 추상화, 정보은닉, 모듈성에 기초

- 구성요소

클래스
(Class)
- 특정 객체 내에 있는 변수와 메서드를 정의하는 일종의 틀
- 객체 지향 프로그래밍에서 데이터를 추상화하는 단위
- 하나 이상의 유사한 객체들을 묶어 하나의 공통된 특성을 표현(= 클래스 내의 모든 객체들은 속성의 값만 달리할 뿐, 동일한 속성과 행위를 갖게 됨)
- 속성은 변수의 형태로, 행위는 메서드 형태로 선언
- 동일한 속성, 공통의 행위, 다른 객체 클래스에 대한 공통의 관계성, 동일한 의미를 가지는 객체들의 집합
- 모든 객체는 반드시 클래스를 통해서 정의될 수 있음
- 객체 타입으로 구현된 소프트웨어를 의미
*추상 클래스: 서브 클래스들의 공통된 특성을 하나의 슈퍼 클래스로 추출하기 위한 목적으로 생성된 클래스로 재사용 부품을 이용하여 확장할 수 있는 개념 (일반 클래스와 달리 객체를 생성할 목적이 아니며, 생성할 수 X)
객체
(Object)
- 물리적, 추상적으로 자신과 다른 것을 식별 가능한 대상
- 클래스에서 정의한 것을 토대로 메모리에 할당함
- 객체마다 각각의 상태와 식별성을 가짐
- 데이터와 그것을 사용하는 연산을 하나의 모듈로 구성한 것
- 개별 자료 구조와 프로세서로 구성됨 (데이터(속성) + 연산함수(메소드) -> 캡슐화)
- 인터페이스인 공유부분을 가지며, 상태(state)를 가지고 있음
- 하나의 실체로 그 실체가 지닌 특징과 그 실체가 할 수 있는 행동방식으로 구성됨
- 프로그램상에서 각 객체는 필요로 하는 데이터와 그 데이터 위에 수행되는 함수들을 가진 작은 소프트웨어 모듈임
메서드
(Method)
- 클래스로부터 생성된 객체를 사용하는 방법
- 객체가 메시지를 받아 실행해야 할 객체의 구체적인 연산
- 전통적 시스템의 함수 또는 프로시저에 해당하는 연산 기능
- 메시지에 의해 불리어질 수 있는 제어와 절차의 구성요소
메시지
(Message)
- 객체 간 상호 작용을하기 위한 수단(한 객체가 다른 객체의 모듈을 부르거나 외부에서 하나의 객체에 보내지는 행위의 요구)
- 객체에게 어떤 행위(연산)를 하도록 지시하는 방법
- 일반 프로그래밍 과정에서 함수 호출에 해당
- 구성 요소: 메시지를 받는 객체(수신객체), 객체가 수행할 메소드 이름(함수 이름), 메소드를 수행하는 데 필요한 인자(매개변수)
인스턴스
(Instance)
- 객체 지향 기법에서 클래스를 통해 만든 실제의 실행 객체
- 클래스에 속한 각각의 객체
- 실제로 메모리에 할당
속성
(Property)
- 한 클래스 내에 속한 객체들이 가지고 있는 데이터 값들을 단위별로 정의
- 객체가 가지고 있는 특성으로, 현재 상태(객체의 상태)를 의미
- 성질, 분류, 식별, 수량, 현재 상태 등에 대한 표현 값

 

- 객체 지향 기법

캡슐화(Encapsulation) - 서로 연관된 데이터와 함수를 함께 묶어 외부와 경계를 만들고 필요한 인터페이스만을 밖으로 드러내는 기법
- 객체 정의 시 서로 관련성 많은 데이터들과 이와 관련된 함수들을 정보처리에 필요한 기능을 하나로 묶는 것
- 데이터구조와 이를 조작하는 동작들은 하나의 개체인 클래스에 통합됨 -> 결합도 낮아지며, 컴포넌트 재사용 용이, 인터페이스가 단순화됨
- 변경 발생 시 오류의 파급 효과가 적음
- 사용자에게 세부 구현사항을 감추고, 필요한 사항들만 보이게 함 -> 내부 구현사항으로의 접근 방지
- 내부에 변수, 외부에는 메소드들이 변수들을 둘러쌓아 보호함 -> 변경 연산 시 부작용 감소시켜줌
상속성(Inheritance) - 상위 클래스의 속성과 메서드를 하위 클래스에서 재정의 없이 물려받아 사용하는 기법
- 새로운 클래스를 정의할 때 처음부터 모든 것을 다 정의하지 않고 기존의 클래스들의 속성을 상속받고 추가로 필요한 속성만 추가하는 방법
- 높은 수준의 개념은 낮은 수준의 개념으로 특정화됨
- 하위 계층: 상위 계층의 특수화 계층이 됨
- 상위 계층: 하위 계층의 일반화 계층이 됨
다형성(Polymorphism) - 하나의 메시지에 대해 각 객체(클래스)가 가지고 있는 고유한 방법으로 응답할 수 있는 능력
- 상속받은 여러 개의 하위 객체들이 다른 형태의 특성을 갖는 객체로 이용될 수 있는 성질
- 주로 동적 바인딩에 의해 실현됨
- 각 객체가 갖는 메소드의 이름은 중복될 수 O, 실제 메소드 호출은 매개변수에 따라 구별됨
- Ex. 오버로딩: 매개변수의 유형과 개수를 다르게 해 같은 이름의 함수를 여러 개 가지는 성질
- Ex. 오버라이딩: 상위클래스에서 정의한 일반 메서드의 구현을 하위 클래스에서 재정의
추상화(Abstraction) - 공통 성질을 추출하여 추상 클래스를 설정하는 기법
- 과정 추상화, 자료 추상화, 제어 추상화가 있음
정보 은닉
(Information Hiding)
- 코드 내부 데이터와 메서드를 숨기고 공개 인터페이스를 통해서만 접근이 가능하도록 하는 코드 보안 기술
- 필요하지 않은 정보는 접근할 수 없도록 하여 한 모듈 또는 하부 시스템이 다른 모듈의 구현에 영향을 받지 않게 설계됨
- 모듈 내부의 자료 구조와 접근 동작들에만 수정을 국한하지 않기 때문에 요구사항 등 변화에 따른 수정이 가능
- 모듈 사이의 독립성 유지에 도움을 줌

 

C언어

- C프로그램은 함수의 집합으로 구성됨

- 이식성이 높은 언어

- 예약어가 간단

- 융통성과 강력한 기능 갖고 있음

- 구조적 프로그램이 가능

 

C언어 printf( ) 예제

*V= 빈칸

1. int a = 789; char a[] = "programming"; float a = 789.17;
printf("%d\n", a); 789 printf("%s\n", a); programming printf("%f\n", a); 789.170000
printf("%5d\n", a); VV789 printf("%13s\n", a); VVprogramming printf("%11f\n", a); V789.170000
printf("%-5d\n", a); 789VV printf("%-13s\n", a); programmingVV printf("%11.1f\n", a); VVVVVV789.2
printf("%05d\n", a); 00789 printf("%10.3s\n", a); VVVVVVVpro    
printf("%+5d\n", a); +789 printf("%.3s\n", a); pro    

 

비트 연산자(Bitwise Operator)

  연산자 기능
시프트연산자
= 이동 연산자
>> 비트 값을 우측으로 이동 r = a >> 3;
<< 비트 값을 좌측으로 이동 r = a << 3;
논리 연산자
= 비트 연산자
& 비트 논리곱(AND) r = a & b;
| 비트 논리합(OR) r = ab;
^ 비트 배타적 논리합(XOR) r = a^b;
~ 반전(NOT, 1의 보수) r = ~a;

 

나열 연산자: 수식을 콤마로 구분하여 나열, 연산은 왼쪽부터 오른쪽으로 차례로 진행

- ex) y = (a = 5, b = a + 2, 3*b);  계산 시 a = 5, b =  7, c = 21, y = 21

- ex) a = (b = 5, c = ++b + 2) + 5);  계산 시 a = 15, b = 8, c = 10

 

형변환연산자[(자료형)]: 자료의 값은 그래도 두고 자료혀을 강제적으로 바꿀 때 사용

- ex) 정수형을 실수형으로, 자료형을 명시적으로 바꿀 때 사용

int a = 7, b = 5;

float c;

c = (float)a + b;  => 정수형 a를 실수형으로 바꾸어 연산 수행 

 

sizeof 연산자: 자료형, 변수, 수식의 결과 등이 차지하는 기억공간의 바이트 수를 구함

- ex) char ch = 5;

long a, b;

b = sizeof(ch) + sizeof(long);  => b의 값은 1+4 = 5