맨위로가기

컴퓨터 프로그램

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

컴퓨터 프로그램은 컴퓨터에게 특정 작업을 지시하기 위해 작성된 코드 또는 그 결과물을 의미하며, 컴퓨터 하드웨어의 발전과 함께 변화해 왔다. 최초의 프로그래밍 가능한 기계 중 하나인 자카드식 문직기부터 찰스 배비지의 해석 기관, 앨런 튜링의 튜링 머신, 그리고 ENIAC과 같은 초기 컴퓨터를 거쳐 저장 프로그램 방식 컴퓨터의 등장으로 프로그램 개발 방식이 발전했다. 1970년대 VLSI 회로의 발명은 프로그래밍 환경의 변화를 가져왔으며, x86 시리즈의 마이크로프로세서 발전은 현대적인 소프트웨어 개발 환경을 구축하는 데 기여했다. 프로그램은 소스 코드와 컴파일된 결과물을 모두 포함하는 개념이며, 소프트웨어는 프로그램 외에 패키지 전체를 포괄하는 더 넓은 의미로 사용된다. 컴퓨터 프로그래밍은 명령형, 선언형, 객체 지향 프로그래밍 등 다양한 패러다임을 통해 이루어지며, 소프트웨어 공학은 품질 있는 컴퓨터 프로그램 생산을 위한 기술을 다룬다. 컴퓨터 프로그램은 응용 소프트웨어, 시스템 소프트웨어, 유틸리티 소프트웨어, 마이크로코드 프로그램 등 기능적 범주에 따라 분류되며, 각 범주는 컴퓨터 시스템의 효율적인 작동에 기여한다.

더 읽어볼만한 페이지

  • 소프트웨어 - 소프트웨어 특허
    소프트웨어 특허는 소프트웨어 관련 발명에 대한 배타적 권리를 부여하여 기술 혁신을 장려하는 데 목적이 있지만, 범위와 요건에 대한 논쟁이 있으며 국가별 인정 기준이 다르고 자유 소프트웨어 진영에서는 비판적인 입장을 취하고 있다.
  • 소프트웨어 - 소프트웨어 인텔리전스
    소프트웨어 인텔리전스는 소프트웨어 개발, 관리, 품질 향상 및 의사 결정을 지원하는 기술과 방법론으로, 코드 분석, 데이터 시각화, 결함 목록, 산업 표준 준수 평가, 소프트웨어 경제성 측정 등을 포함하여 소프트웨어의 품질과 생산성을 향상시키는 데 기여하는 분야이다.
  • 컴퓨터 프로그래밍 - 순서도
    순서도는 컴퓨터 알고리즘이나 프로세스를 시각적으로 표현하는 도구로, 흐름 공정 차트에서 기원하여 컴퓨터 프로그래밍 분야에서 알고리즘을 설명하는 데 사용되며, 다양한 종류와 소프트웨어 도구가 존재한다.
  • 컴퓨터 프로그래밍 - 의사코드
    의사코드는 컴퓨터 과학 및 수치 계산 분야에서 알고리즘을 설명하기 위해 사용되는 비표준적인 언어로, 자연어와 프로그래밍 언어의 요소를 혼합하여 알고리즘의 논리적 흐름을 이해하기 쉽게 하고 프로그래머가 실제 코드로 구현하기 전에 알고리즘을 설계하고 검토하는 데 유용하다.
컴퓨터 프로그램
개요
종류실행 가능한 소프트웨어
사용 분야컴퓨터
실행 주체컴퓨터
다른 이름소프트웨어, 응용 프로그램
상세 정보
정의특정 작업을 수행하기 위해 컴퓨터가 이해하고 실행할 수 있는 일련의 명령어 집합.
구성 요소알고리즘, 자료 구조, 프로그래밍 언어
개발 단계요구사항 분석, 설계, 구현, 테스트, 배포, 유지보수
실행 방식컴파일
인터프리트
응용 분야운영 체제
사무 자동화
그래픽 디자인
웹 개발
인공지능
관련 직업프로그래머
소프트웨어 엔지니어
데이터 과학자
역사
초기찰스 배비지의 해석기관 구상 (1830년대)
에이다 러브레이스, 최초의 프로그램 작성 (1843년)
현대ENIAC, 최초의 전자식 컴퓨터 (1946년)
포트란, 최초의 고수준 프로그래밍 언어 (1957년)
특징
기능성특정 작업을 수행하는 능력
신뢰성오류 없이 정확하게 작동하는 능력
사용성사용자가 쉽게 이해하고 사용할 수 있는 정도
효율성자원을 효율적으로 사용하는 능력
유지보수성쉽게 수정하고 개선할 수 있는 정도
이식성다른 환경에서도 실행될 수 있는 정도
종류
시스템 프로그램운영 체제, 컴파일러, 디버거 등 컴퓨터 시스템 운영에 필요한 프로그램
응용 프로그램워드 프로세서, 웹 브라우저, 게임 등 특정 작업을 수행하는 프로그램
악성 소프트웨어바이러스, 웜, 트로이 목마 등 컴퓨터 시스템에 해를 끼치는 프로그램
프로그래밍 언어
종류C
C++
Java
Python
JavaScript
C#
PHP
Go
Kotlin
Swift
Ruby
R
MATLAB
Fortran
Pascal
Lisp
Prolog
Haskell
어셈블리어
패러다임명령형 프로그래밍
객체 지향 프로그래밍
함수형 프로그래밍
선언형 프로그래밍
관련 기술
알고리즘문제를 해결하기 위한 절차
자료 구조데이터를 효율적으로 저장하고 관리하는 방법
소프트웨어 공학소프트웨어 개발 방법론
컴퓨터 과학컴퓨터 및 정보 처리 연구 분야
기타
주의사항프로그램은 저작권으로 보호받을 수 있음.

2. 역사

컴퓨터 프로그래밍의 발전은 컴퓨터 하드웨어의 발전과 밀접하게 연관되어 있다. 하드웨어 기술이 발전하는 각 단계마다 컴퓨터 프로그래밍의 과제와 방식 역시 크게 변화해 왔다.

하드웨어와 프로그램(소프트웨어)의 역할 분담이 명확해진 것은 1950년대 이후 프로그램 내장 방식(폰 노이만형) 컴퓨터가 실현되면서부터이다. 이론적으로는 튜링 머신 등이 관련되지만, 여기서는 다루지 않는다. 또한, 19세기 배비지러브레이스가 해석 기관을 위해 만든 프로그램도 역사적으로 중요하지만, 이 섹션에서는 생략한다.

초기 컴퓨터 중 일부는 수행할 계산(데이터 처리)[154] 종류에 따라 구성 요소 간의 전기 배선을 직접 연결하여 프로그래밍하는 와이어드 로직(배선 논리) 방식을 사용했다. 이 방식은 다른 계산을 하려면 배선을 바꿔야 하는 번거로움이 있었다. ENIAC이 초기에[155] 이 방식을 사용한 대표적인 예이다.

1949년 가동된 EDSAC은 프로그램 내장 방식을 "실용적으로"[157] 구현한 초기 컴퓨터 중 하나이다. 이 방식에서는 프로그램이 주 기억 장치에 저장("내장")되며, 프로세서(CPU)는 주 기억 장치에서 프로그램을 읽어와 그 지시에 따라 동작한다.

프로그램을 만드는 과정을 프로그래밍이라고 하며, 이를 수행하는 사람을 프로그래머라고 부른다. 프로그래밍에는 주로 프로그래밍 언어라는 형식 언어이자 인공 언어가 사용된다. 특정 기능을 구현하기 위해 어셈블리 언어로 기계어를 사용하거나, 직접 기계어 바이너리 코드를 작성하기도 한다. 프로그래밍 언어로 작성된 코드를 소스 코드라고 한다.

프로그래밍 언어로 작성된 소스 코드를 컴퓨터가 이해할 수 있도록 변환하거나 해석하여 실행하는 프로그램을 프로그래밍 언어 처리계라고 한다. 대표적인 처리계로는 컴파일러인터프리터가 있으며, 이 둘의 관계는 니무라 사영을 통해 형식적으로 설명될 수 있다.

프로그램은 기능에 따라 크게 두 가지로 나뉜다. 컴퓨터 자체의 작동을 제어하는 운영 체제와 같은 시스템 프로그램과, 사용자가 특정 작업을 수행하기 위해 사용하는 스프레드시트 같은 애플리케이션 프로그램이 있다.

또한, 단독으로 실행되지 않고 다른 프로그램에 의해 호출되어 특정 기능을 제공하는 프로그램 조각을 소프트웨어 라이브러리라고 한다. 여러 프로그램에서 공통적으로 사용될 수 있는 기능을 라이브러리로 만들면 프로그램 개발의 효율성을 높일 수 있다.

2. 1. 초기의 프로그래밍 가능한 머신

최초의 프로그래밍 가능한 머신은 디지털 컴퓨터의 발명을 앞선다. 1801년, 조셉 마리 자카드는 자카드식 문직기를 고안하여 일련의 천공 카드를 따라 패턴을 짰다. 꽃과 잎을 포함하는 패턴을 짠 다음 카드들을 정렬하여 반복할 수 있었다.[161]

2. 2. 해석 기관 (Analytical Engine)

러브레이스의 설명, Note G


1837년, 찰스 배비지는 자카드의 직조기에서 영감을 받아 해석 기관을 설계했다.[10] 해석 기관은 현대 컴퓨터의 기본적인 구조와 유사한 개념을 가지고 있었다.

해석 기관의 구성 요소 이름은 당시 발달했던 섬유 산업 용어에서 가져왔다. 데이터를 저장하는 메모리 역할을 하는 '저장소'(storeeng)와 데이터 처리를 담당하는 '제분소'(milleng)가 있었다. 저장소는 각 50자리의 숫자 1,000개를 저장할 수 있었으며,[11] 저장소의 숫자는 처리를 위해 제분소로 전송되었다. 해석 기관은 두 종류의 천공 카드를 사용하여 프로그래밍되도록 설계되었다. 한 종류는 수행할 연산을 지시하고, 다른 종류는 계산에 사용될 변수를 입력하는 역할을 했다.[10][12] 그러나 당시 기술적 한계로 인해 수천 개의 복잡한 톱니바퀴와 기어가 완벽하게 작동하도록 만드는 것은 어려웠고, 해석 기관은 실제로 완성되지 못했다.[13]

에이다 러브레이스는 1843년, 배비지의 해석 기관에 대한 설명을 작성했다.[14] 이 설명에는 'Note G'라는 주석이 포함되어 있었는데, 여기에는 해석 기관을 사용하여 베르누이 수를 계산하는 구체적인 단계별 절차가 상세히 기술되어 있었다. 이 Note G는 오늘날 많은 역사학자들에게 세계 최초의 컴퓨터 프로그램으로 인정받고 있다.[13]

2. 3. 튜링 머신 (Universal Turing Machine)

(내용 없음)

2. 4. 에니악 (ENIAC)

ENIAC은 초창기 컴퓨터 중 하나로, 그 프로그래밍 방식은 오늘날과 사뭇 달랐다. 1940년대의 일부 계산기처럼, 에니악은 수행하려는 계산(데이터 처리)[154]의 종류에 따라 각 구성 요소 간의 전기적 배선을 직접 연결하는 방식으로 프로그램되었다. 이를 와이어드 로직(배선 논리)에 의한 프로그래밍이라고 한다.[155]

이 방식은 제어 논리가 전기 배선으로 직접 구현되어 속도 면에서는 유리할 수 있으나, 다른 종류의 계산을 수행하려면 매번 배선을 변경해야 하는 상당한 번거로움이 따랐다. 비록 패치 패널 부분을 모듈화하여 교체하는 방법도 있었지만, 근본적인 불편함은 여전했다. 에니악이 초기에[155] 이러한 와이어드 로직 방식을 사용했다는 점은 컴퓨터의 역사에서 중요한 부분으로 자주 언급된다.

2. 5. 저장 프로그램 방식 컴퓨터 (Stored-program computers)

배선 논리 방식으로 프로그래밍되던 초기 컴퓨터는 수행하려는 계산 종류에 따라 구성 요소 간의 전기 배선을 직접 연결해야 했다. 이는 다른 계산을 수행하려면 배선을 일일이 변경해야 하는 불편함이 따랐다.[155] ENIAC과 같은 초기 컴퓨터가 이러한 방식을 사용했다.

이에 대한 대안으로 저장 프로그램 방식 컴퓨터가 등장했다. 이 방식은 명령어와 데이터를 구분 없이 동일한 주 기억 장치에 저장하는 것이 핵심이다.[21] 덕분에 컴퓨터 프로그램을 훨씬 빠르고 유연하게 변경할 수 있게 되었고, 계산 속도 또한 비약적으로 향상되었다.[22] 저장 프로그램 개념은 ENIAC 개발에 참여했던 프레스퍼 에커트와 존 모클리가 1944년 2월에 작성한 메모에서 처음으로 제안되었다.[23]

이 개념은 1944년 9월 ENIAC 프로젝트에 합류한 존 폰 노이만에 의해 더욱 구체화되었다. 폰 노이만은 1945년 6월 30일에 발표한 유명한 "EDVAC 보고서 초안"을 통해, 컴퓨터의 논리적 구조를 제시하며 저장 프로그램 방식의 이론적 토대를 마련했다.[22] 이 설계는 오늘날 폰 노이만 구조로 널리 알려져 있다.

폰 노이만 구조는 1949년에 제작된 EDVAC과 EDSAC 컴퓨터에 적용되어 현실화되었다.[24] 특히 EDSAC은 프로그램 내장 방식(저장 프로그램 방식)을 성공적으로 구현하여 실제 운영된 초기 컴퓨터 중 하나로 평가받는다.[157] 프로그램 내장 방식 컴퓨터는 주 기억 장치에 저장된 프로그램을 프로세서 (CPU)가 순차적으로 읽어 들여 실행하는 방식으로 작동한다.

2. 6. 초고밀도 집적 회로 (Very Large Scale Integration)

컴퓨터 프로그래밍의 발전은 컴퓨터 하드웨어 기술의 진보와 밀접한 관계를 맺으며 이루어졌다. 하드웨어 기술이 각 단계를 거쳐 발전함에 따라, 컴퓨터 프로그래밍의 방식과 과제 역시 크게 변화했다.

초고밀도 집적 회로(VLSI)의 다이


소프트웨어 개발 역사에서 중요한 이정표 중 하나는 1964년 초고밀도 집적 회로(VLSI) 기술의 등장이었다.[29] 제2차 세계 대전 이후 초기 컴퓨터는 진공관 기반이었으나, 1947년 점 접촉 트랜지스터와 1950년대 후반 바이폴라 접합 트랜지스터가 개발되면서 회로 기판에 개별 트랜지스터를 장착하는 방식으로 대체되었다.[29] 1960년대에 들어서는 항공 우주 산업을 중심으로 여러 전자 부품을 작은 실리콘 칩 하나에 모아놓은 집적 회로(IC)가 회로 기판을 대체하기 시작했다.[29]

페어차일드 반도체인텔의 공동 창립자인 로버트 노이스는 반도체 소자 제조 기술, 특히 전계 효과 트랜지스터(FET) 생산 기술을 개선하는 데 기여했다.[30] 이 기술 덕분에 실리콘 웨이퍼 위에 포토리소그래피와 같은 평면 공정을 이용하여 트랜지스터, 커패시터, 다이오드, 저항 등 수많은 소자를 하나의 칩에 고도로 집적하는 것이 가능해졌다.[33][34] 이렇게 만들어진 금속-산화물-반도체(MOS) 트랜지스터는 현대 집적 회로 칩의 핵심 구성 요소가 되었다.[30]

초기 집적 회로는 제조 단계에서 기능이 완전히 결정되었다. 하지만 1960년대에는 읽기 전용 메모리(ROM)의 다이오드 매트릭스에 전기 신호를 가하여 특정 연결을 끊어내는 방식으로 데이터를 프로그래밍하는 기술이 개발되었다.[29] 회로가 복잡해지면서, 이 프로그래밍 과정을 제어하기 위한 별도의 컴퓨터 프로그램이 사용되기도 했다.[29] 이 기술은 사용자가 직접 프로그래밍할 수 있는 프로그래밍 가능한 ROM(PROM)으로 발전했다. 마침내 1971년, 인텔은 컴퓨터 프로그램을 칩 자체에 내장하여 실행할 수 있는 인텔 4004를 출시하며 이를 마이크로프로세서라고 불렀다.[35] 이는 상업적으로 성공한 최초의 마이크로프로세서로 여겨진다.

인텔 8008을 사용한 초기 마이크로컴퓨터인 Sac State 8008 (1972년)


인텔 4004는 4-비트 마이크로프로세서로, 주로 Busicom 계산기에 탑재되었다. 출시 5개월 뒤, 인텔은 성능을 향상시킨 8비트 마이크로프로세서 인텔 8008을 선보였다. 새크라멘토 주립 대학교의 빌 펜츠 연구팀은 이 인텔 8008을 기반으로 최초의 마이크로컴퓨터 중 하나인 'Sac State 8008'(1972)을 제작했다.[37] 이 컴퓨터는 환자 의료 기록 저장이라는 특정 목적을 위해 개발되었으며, 하드 디스크 드라이브와 디스크 운영 체제까지 갖추고 있었다.[29] 비록 높은 제작 비용 등의 문제로 널리 보급되지는 못했지만[37], 이러한 초기 마이크로컴퓨터의 등장은 이후 인텔 8080(1974)과 같은 후속 마이크로프로세서 개발에 중요한 영향을 미쳤다.[29] 이처럼 VLSI 기술의 발전은 컴퓨터 프로그램을 하드웨어 칩에 직접 담아 처리하는 마이크로프로세서 시대를 열었으며, 소프트웨어 개발 환경에 근본적인 변화를 가져오는 계기가 되었다.

2. 7. x86 시리즈

1978년, 인텔인텔 8080인텔 8086으로 업그레이드하면서 현대적인 소프트웨어 개발 환경이 시작되었다. 인텔은 더 저렴한 인텔 8088을 제조하기 위해 인텔 8086을 단순화했다.[38] IBM개인용 컴퓨터 시장에 진출하면서 (1981) 인텔 8088을 채택했다. 소비자수요가 개인용 컴퓨터로 증가함에 따라 인텔의 마이크로프로세서 개발도 함께 가속화되었다. 이러한 개발 계통은 x86 시리즈로 알려져 있다.

x86 어셈블리 언어는 하위 호환성을 가지는 기계어 명령어 집합이다. 이전 마이크로프로세서에서 생성된 기계어 명령어는 마이크로프로세서가 업그레이드되는 동안에도 계속 지원되었다. 이를 통해 소비자는 새로운 응용 소프트웨어를 구매할 필요 없이 새로운 컴퓨터를 구매할 수 있었다. 주요 명령어 범주는 다음과 같다.

  • RAM에서 숫자 및 문자열을 설정하고 접근하기 위한 메모리 명령어.
  • 정수에 대한 기본적인 산술 연산을 수행하는 정수 산술 논리 장치 (ALU) 명령어.
  • 실수에 대한 기본적인 산술 연산을 수행하는 부동 소수점 ALU 명령어.
  • 메모리를 할당하고 함수와 인터페이스하는 데 필요한 워드를 푸시하고 팝하는 호출 스택 명령어.
  • 여러 프로세서가 데이터 배열에서 동일한 알고리즘을 수행할 수 있을 때 속도를 높이기 위한 단일 명령어 다중 데이터 (SIMD) 명령어 (1999년 도입).

2. 8. 프로그래밍 환경의 변화

초고밀도 집적 회로 (VLSI) 회로의 발전은 프로그래밍 환경에 큰 변화를 가져왔다.[29] VLSI 기술 덕분에 통합 개발 환경(IDE)은 1990년대에 이르러 컴퓨터 터미널 환경에서 그래픽 사용자 인터페이스(GUI)를 갖춘 컴퓨터 환경으로 발전할 수 있었다.

디지털 이큅먼트 코퍼레이션(DEC)의 VT100 (1978)은 널리 사용된 컴퓨터 터미널이었다.


이전의 컴퓨터 터미널 환경에서 프로그래머는 주로 명령 줄 인터페이스(CLI) 기반의 단일 셸 환경에서 작업해야 했다. 1970년대에는 텍스트 기반 사용자 인터페이스가 도입되어 전체 화면에서 소스 코드를 편집하는 것이 가능해졌지만, 여전히 제약이 있었다. 디지털 이큅먼트 코퍼레이션(DEC)의 VT100 (1978)은 이러한 시대에 널리 사용된 대표적인 컴퓨터 터미널이었다.

마이크로프로세서 기술의 발전, 특히 인텔의 x86 시리즈와 이를 채택한 IBM 개인용 컴퓨터(1981)의 등장은 GUI 환경의 확산을 가속화했다.[38] 이러한 하드웨어 발전에 힘입어, 프로그래머들은 더 직관적이고 편리한 GUI 기반의 IDE를 사용할 수 있게 되었다. 사용 가능한 기술이 어떻게 변하든, 프로그래밍의 근본적인 목표는 프로그래밍 언어를 사용하여 원하는 기능을 구현하는 것이다.

3. 프로그램과 소프트웨어

프로그램은 프로그래밍된 결과물을 뜻하고, 소프트웨어하드웨어의 반대 개념으로서의 의미이지만, 일반적으로는 같은 의미로 쓰인다. 다만, 엄밀한 의미에서는 아래와 같은 차이가 있다.


  • 프로그램: 컴파일된 결과물뿐만 아니라, 프로그래머가 작성한 소스 코드까지도 포함한다.
  • 소프트웨어: 프로그램뿐만 아니라 CD, 설명서, 제품 포장 등 패키지 전체를 뜻하기도 한다.


계산 기계 또는 정보 처리 기계에 관해 하드웨어와 프로그램(소프트웨어)의 분담이 명확해진 것은, 실제적으로는 1950년대부터 이후, 이른바 폰 노이만형 (또는 프로그램 내장 방식) 컴퓨터의 실현에 의해서이다. 이론적으로는 튜링 머신 등이 관계하지만, 그러한 이론적인 측면에서의 관점은 여기서는 생략한다. 또한 역사적으로 보면, 19세기배비지러브레이스가 해석 기관용 컴퓨터 프로그램을 만들었다고 할 수 있지만, 그것도 생략한다. 직관적인 비유로 하드웨어를 주판이라고 한다면, 그것을 "어떻게 조작할 것인가"라는 명확하고 구체적인 절차가 프로그램에 해당한다.

4. 프로그래밍

기계어 모니터 (W65C816S 마이크로프로세서)


프로그래밍은 컴퓨터가 이해할 수 있는 언어를 사용하여 특정 작업을 수행하도록 지시하는 과정을 말한다. 이러한 컴퓨터 프로그래밍 언어는 기술 발전에 따라 여러 세대에 걸쳐 발전해 왔다.

프로그래밍 언어의 진화는 1949년 EDSAC이 최초로 저장된 프로그램을 폰 노이만 구조 하에서 실행하면서 중요한 전환점을 맞이했다.[44] 이는 1세대 프로그래밍 언어의 시작으로 볼 수 있다.

  • 1세대 언어: 기계어로, 컴퓨터가 직접 이해하는 숫자 코드로 이루어져 있다.[45] 프로그래머는 복잡한 숫자 명령어를 직접 사용해야 했다.[46]
  • 2세대 언어: 어셈블리 언어는 기계어 명령어를 'ADD'와 같은 니모닉(기호)으로 대체하여 가독성을 높였다.[45][46] 어셈블러가 이를 기계어로 변환해주지만, 여전히 특정 하드웨어에 종속적이다.[46][48]
  • 3세대 언어: 컴파일러나 인터프리터를 사용하며, 특정 하드웨어로부터 독립적인 고급 프로그래밍 언어이다.[49] 포트란, 코볼, BASIC, C 등이 대표적이다.[45][50] 이 언어들은 사람이 이해하기 쉬운 문법을 제공하여 생산성을 크게 향상시켰다.
  • 4세대 언어: 프로그램의 구체적인 절차(어떻게)보다는 원하는 결과(무엇)를 명시하는 데 중점을 둔다.[45] 주로 선언형 언어들이 해당하며, 데이터베이스를 다루는 SQL 등이 대표적인 예이다.[45]

4. 0. 1. 명령형 프로그래밍 언어

명령형 언어로 작성된 컴퓨터 프로그램


명령형 언어는 알고리즘을 선언, 표현식, 그리고 구문을 사용하여 순차적으로 명시한다.[52]

  • 선언: 컴퓨터 프로그램에서 사용할 변수의 이름을 정하고 자료형을 지정한다.[53] 예를 들어, var x: 정수; 와 같이 사용한다.
  • 표현식: 특정 값을 계산하여 반환한다. 예를 들어, 2 + 2는 4를 반환한다.
  • 구문: 표현식의 결과를 변수에 할당하거나, 변수의 값에 따라 프로그램의 제어 흐름을 바꾼다. 예를 들어, x := 2 + 2; 만약 x = 4 라면 do_something(); 과 같이 사용한다.


=== FORTRAN ===

FORTRAN(1958)은 "IBM 수학 공식 번역 시스템"(eng)의 약자로, IBM에서 과학 기술 계산을 위해 개발했다. 초기 버전에는 문자열 처리 기능이 없었다.[54] FORTRAN은 선언, 표현식, 구문 외에도 다음과 같은 기능을 지원했다.

  • 배열
  • 서브루틴
  • "do" 루프


FORTRAN이 성공할 수 있었던 요인은 다음과 같다.[54]

  • 프로그래밍 및 디버깅 비용이 컴퓨터 실행 비용보다 중요해지기 시작했다.
  • IBM이라는 거대 기업의 지원을 받았다.
  • 당시 컴퓨터의 주요 응용 분야가 과학 기술 계산이었다.


하지만 IBM 외의 다른 회사에서 만든 FORTRAN 컴파일러는 IBM 컴파일러와 호환되지 않는 경우가 많았다.[54] 이러한 문제를 해결하기 위해 미국 국립 표준 협회(ANSI)는 1966년에 첫 번째 FORTRAN 표준을 제정했다. 이후 1978년에 제정된 Fortran 77 표준이 1991년까지 사용되었으며, Fortran 90 표준에서는 레코드와 배열에 대한 포인터 기능이 추가되었다.

=== BASIC ===

BASIC(1964)은 "초보자를 위한 만능 기호 지시 코드"(eng)의 약자로, 다트머스 대학교에서 모든 학생이 쉽게 배울 수 있도록 개발되었다.[8] 다른 어려운 언어를 배우지 않더라도 BASIC은 비교적 기억하기 쉬웠다.[8] 1970년대 후반 마이크로컴퓨터 시대가 열리면서 대부분의 마이크로컴퓨터에 BASIC 인터프리터가 탑재되었고, 이는 BASIC 언어의 확산에 크게 기여했다.[8]

BASIC은 대화형 세션 환경을 제공하여 사용자와 컴퓨터가 상호작용하며 프로그래밍할 수 있도록 했다.[8] BASIC 환경에서는 다음과 같은 운영 체제와 유사한 명령어를 사용할 수 있었다.

  • 'new' 명령은 빈 슬레이트를 생성했다.
  • 문은 즉시 평가되었다.
  • 행 번호로 시작하여 문을 프로그래밍할 수 있었다.
  • 'list' 명령은 프로그램을 표시했다.
  • 'run' 명령은 프로그램을 실행했다.


다음은 BASIC으로 작성된 숫자 목록의 평균을 구하는 예시 프로그램이다.[8]

10 INPUT "평균을 구할 숫자의 개수는?", A

20 FOR I = 1 TO A

30 INPUT "숫자를 입력하세요:", B

40 LET C = C + B

50 NEXT I

60 LET D = C/A

70 PRINT "평균은", D

80 END

하지만 BASIC의 문법은 단순하여 대규모 프로그램을 개발하기에는 어려움이 있었다.[8] 이후 BASIC의 여러 방언(버전)들이 등장하면서 구조적 프로그래밍과 객체 지향 프로그래밍 기능이 추가되었다. 마이크로소프트비주얼 베이직그래픽 사용자 인터페이스(GUI) 개발에 여전히 사용되고 있다.[7]

=== C ===

C 언어(1973)는 AT&T 벨 연구소에서 유닉스 운영체제를 개발하기 위해 만들어졌다. 이름은 이전에 사용되던 BCPLB 언어의 뒤를 잇는다는 의미에서 'C'로 지어졌다.[50] C 언어는 비교적 크기가 작아 컴파일러를 만들기 쉬웠고, 1980년대 하드웨어 발전에 힘입어 널리 퍼지게 되었다.[50] 또한 어셈블리 언어처럼 하드웨어를 직접 제어할 수 있는 기능을 가지면서도 고급 프로그래밍 언어의 문법을 사용하여 개발 생산성을 높였기 때문에 인기를 얻었다. C 언어의 특징적인 기능은 다음과 같다.[50]

  • 인라인 어셈블러: C 코드 내부에 어셈블리 코드를 직접 삽입할 수 있다.
  • 포인터 연산: 포인터를 이용해 메모리 주소를 직접 계산하고 조작할 수 있다.
  • 함수 포인터: 함수 자체의 메모리 주소를 포인터 변수에 저장하여 활용할 수 있다.
  • 비트 연산: 데이터를 비트(eng) 단위로 조작할 수 있다.
  • 자유로운 연산자 조합: 다양한 연산자를 복합적으로 사용하여 간결한 코드를 작성할 수 있다.


컴퓨터 메모리 맵


C 언어는 프로그래머가 데이터가 저장될 메모리 영역을 직접 제어할 수 있게 해준다. 변수가 저장되는 주요 메모리 영역은 다음과 같다.

  • 전역 및 정적 데이터 영역: 프로그램이 실행되는 동안 계속 유지되는 데이터를 저장한다. 전역 변수static 키워드로 선언된 정적 변수가 이 영역에 저장된다.[58] 이 변수들의 메모리 주소는 컴파일 시점에 결정된다. 전역 변수는 프로그램 전체에서 접근 가능하지만, 정적 변수는 선언된 함수나 블록 내에서만 접근 가능하다.[59][58] 이 영역은 기술적으로 초기화된 데이터 세그먼트와 초기화되지 않은 데이터 세그먼트(.bss)로 나뉜다.[58]
  • 호출 스택 영역: 함수가 호출될 때 사용되는 지역 변수매개변수를 저장하는 영역이다.[61] 함수 호출이 끝나면 해당 함수에서 사용된 변수들은 스택에서 제거된다. static으로 선언되지 않은 지역 변수(eng, 자동 변수)가 여기에 해당한다.[59][62][58] 스택 메모리는 자동으로 관리되며, 일반적으로 메모리 상위 주소에서 하위 주소 방향으로 자란다.[61]
  • 힙 영역: 프로그래머가 필요에 따라 직접 메모리를 할당하고 해제하는 영역이다.[58] C 언어에서는 malloc() 함수 등을 사용하여 힙 영역에 메모리 공간을 요청하고, 할당받은 공간의 주소를 포인터 변수에 저장하여 사용한다.[64] 힙 영역은 주로 크기가 크거나 프로그램 실행 중에 크기가 변하는 데이터를 저장하는 데 사용된다. 힙 메모리는 사용 후 반드시 프로그래머가 직접 해제(free() 함수 사용)해야 메모리 누수를 막을 수 있다. 운영 체제는 힙 포인터와 할당된 메모리 블록 목록을 통해 힙 영역을 관리한다.[63] 힙 영역은 일반적으로 메모리 하위 주소에서 상위 주소 방향으로 자라며, 스택 영역과 힙 영역이 서로 만나게 되면 메모리 부족 오류가 발생할 수 있다.

4. 0. 2. 선언형 프로그래밍 언어

명령형 언어는 표현식을 비지역 변수에 할당할 때 의도하지 않은 부작용이 발생할 수 있다는 비판이 있다.[73] 반면, 선언적 언어는 일반적으로 할당문과 제어 흐름을 사용하지 않고, 무엇을 계산해야 하는지에 초점을 맞춘다. 즉, 계산 방법을 상세히 명시하기보다는 원하는 결과나 목표 상태를 기술하는 방식이다. 선언적 언어의 주요 범주로는 함수형 프로그래밍 언어와 논리 언어가 있다.

=== 함수형 프로그래밍 언어 ===

함수형 언어는 람다 계산법을 기반으로 하여 잘 정의된 의미론을 갖추는 것을 목표로 한다.[74] 수학에서 함수는 특정 입력을 받아 정해진 규칙에 따라 출력을 내는 관계를 의미한다. 예를 들어, `times_10(x) = 10 * x` 라는 함수는 입력 `x`에 10을 곱한 값을 반환한다. `times_10(2)`는 20이라는 값을 반환한다.

함수형 언어 컴파일러는 계산된 값을 변수에 직접 저장하는 대신, 컴퓨터의 호출 스택에 값을 임시로 저장(push)하고, 호출한 함수로 제어를 돌려보낸다. 호출 함수는 스택에서 필요한 값을 가져와(pop) 사용한다.[75]

명령형 언어에서도 함수를 지원하므로, 프로그래머가 원칙을 지킨다면 함수형 스타일로 프로그래밍하는 것이 가능하다. 하지만 함수형 언어는 문법 자체를 통해 이러한 원칙(예: 부작용 최소화)을 강제하며, '무엇'을 계산할 것인지 명확히 드러내도록 설계되었다.[76]

함수형 프로그램은 보통 여러 개의 기본 함수(primitive function)와 이를 조합하여 최종 결과를 내는 하나의 주 함수(driver function)로 구성된다.[73] 예를 들어, 세 숫자 중 최댓값과 최솟값의 차이를 구하는 함수는 다음과 같이 작성될 수 있다.

function max( a, b ){/* code omitted */}

function min( a, b ){/* code omitted */}

function range( a, b, c ) {

:return max( a, max( b, c ) ) - min( a, min( b, c ) );

}

여기서 `max()`와 `min()`이 기본 함수이고, `range()`가 주 함수이다. `range(10, 4, 7)`을 실행하면 6이 출력된다.

함수형 언어는 새로운 언어 기능을 탐구하는 컴퓨터 과학 연구에 자주 사용되며,[77] 부작용이 적다는 특성 때문에 병렬 컴퓨팅이나 동시 컴퓨팅 환경에서 유리하다.[78] 그러나 일반적인 응용 프로그램 개발에서는 객체 지향 프로그래밍의 특징을 가진 명령형 언어가 더 선호되기도 한다.[78]

==== 리스프 (Lisp) ====

Lisp (1958)는 "LISt Processor"의 약자이다.[79] 이름처럼 리스트 처리에 특화되어 있다. 데이터 구조는 리스트 안에 또 다른 리스트를 포함하는 방식으로 표현되며, 이는 내부적으로 트리 구조를 형성한다. 이러한 구조는 재귀 함수를 사용하기에 적합하다.[80] 리스프 코드는 괄호 안에 공백으로 구분된 요소들을 나열하는 방식으로 작성된다. 예를 들어, `((A B) (HELLO WORLD) 94)`는 세 개의 요소를 가진 리스트이며, 첫 두 요소는 각각 두 개의 요소를 가진 리스트이다.

리스프는 리스트의 요소를 추출하거나 재구성하는 함수들을 제공한다.[81] 예를 들어, `head(x)`는 리스트 `x`의 첫 번째 요소를 포함하는 리스트를 반환하고, `tail(x)`는 첫 번째 요소를 제외한 나머지 요소들로 이루어진 리스트를 반환한다. `cons(a, b)`는 요소 `a`와 리스트 `b`를 결합하여 새로운 리스트를 만든다. 따라서 `cons(head(x), tail(x))`는 원래 리스트 `x`와 동일한 리스트를 반환한다.

리스프의 단점 중 하나는 함수 호출이 중첩될수록 괄호가 많아져 코드가 복잡해 보일 수 있다는 점이다.[76] 현대의 리스프 개발 환경은 괄호 짝 맞춤 기능 등을 제공하여 이를 보완한다. 또한 리스프는 할당문이나 goto 문과 같은 명령형 언어의 기능도 지원하며,[82] 변수의 자료형을 컴파일 시점이 아닌 런타임에 결정하는 동적 바인딩 방식을 사용한다.[83][84] 동적 바인딩은 유연성을 높이지만, 타입 관련 오류가 프로그램 실행 중 발생할 수 있다는 단점이 있다.[84]

신뢰성 있고 가독성 높은 리스프 프로그램을 작성하려면 체계적인 계획이 필요하다. 잘 계획된 리스프 프로그램은 동일한 기능을 하는 명령형 언어 프로그램보다 훨씬 간결할 수 있다.[76] 리스프는 특히 인공지능 분야에서 널리 사용되어 왔는데, 이는 명령형 기능 지원으로 인한 유연성 덕분이기도 하다.[78]

==== ML ====

ML (1973)[85]은 "Meta Language"의 약자이다. ML은 강력한 타입 검사 기능을 특징으로 하며, 서로 다른 타입의 데이터를 비교하거나 연산하는 것을 엄격히 제한한다.[86] 예를 들어, 정수형 입력 `n`을 받아 10을 곱한 정수형 결과를 반환하는 함수는 다음과 같이 정의될 수 있다.

fun times_10(n : int) : int = 10 * n;

ML은 리스프와 달리 괄호를 과도하게 사용하지 않는다. 위 함수를 사용하는 예시는 다음과 같다.

times_10 2

이 코드를 실행하면 결과값과 함께 타입 정보("20 : int")가 반환된다.

ML 역시 리스프처럼 리스트 처리에 강점을 가지지만, 리스프와 달리 리스트의 모든 요소가 동일한 데이터 타입을 가져야 한다.[87] 또한, ML은 변수의 데이터 타입을 컴파일 시간에 결정하는 정적 바인딩 방식을 사용한다. 정적 바인딩은 컴파일러가 변수 사용의 적절성을 미리 검사할 수 있게 하여 프로그램의 안정성을 높인다.[88]

=== 논리 프로그래밍 언어 ===

논리 프로그래밍 언어는 형식 논리학에 기반한다. 대표적인 언어로는 프롤로그(Prolog)가 있다.

==== 프롤로그 (Prolog) ====

프롤로그(Prolog, 1972)는 "PROgramming in LOGic"(논리 프로그래밍)의 약자이다. 이는 프랑스 마르세유에서 알랭 콜머로에르와 필립 루셀에 의해 개발되었다. 이는 선택적 선형 결정 절 분해의 구현으로, 로버트 코왈스키와 에든버러 대학교의 다른 연구원들이 개척했다.[89]

프롤로그 프로그램의 구성 요소는 사실(fact)과 규칙(rule)이다. 다음은 간단한 예시이다.



cat(tom). % tom은 고양이다

mouse(jerry). % jerry는 생쥐이다

animal(X) :- cat(X). % 각 고양이는 동물이다

animal(X) :- mouse(X). % 각 생쥐는 동물이다

big(X) :- cat(X). % 각 고양이는 크다

small(X) :- mouse(X). % 각 생쥐는 작다

eat(X,Y) :- mouse(X), cheese(Y). % 각 생쥐는 각 치즈를 먹는다

eat(X,Y) :- big(X), small(Y). % 각 큰 동물은 각 작은 동물을 먹는다



모든 사실과 규칙이 입력된 후, 질문을 할 수 있다.

: 톰이 제리를 먹을까?



?- eat(tom,jerry).

true



다음 예시는 프롤로그가 문자 등급을 숫자 값으로 변환하는 방법을 보여준다.



numeric_grade('A', 4).

numeric_grade('B', 3).

numeric_grade('C', 2).

numeric_grade('D', 1).

numeric_grade('F', 0).

numeric_grade(X, -1) :- not X = 'A', not X = 'B', not X = 'C', not X = 'D', not X = 'F'.

grade('The Student', 'A').





?- grade('The Student', X), numeric_grade(X, Y).

X = 'A',

Y = 4



다음은 포괄적인 예시이다.[90]

1) 모든 용은 불을 뿜는다. 또는 동등하게 어떤 것이 용이라면 불을 뿜는다.



billows_fire(X) :-

is_a_dragon(X).



2) 생물이 부모 중 하나가 불을 뿜으면 불을 뿜는다.



billows_fire(X) :-

is_a_creature(X),

is_a_parent_of(Y,X),

billows_fire(Y).



3) X가 Y의 어머니이거나 X가 Y의 아버지라면 X는 Y의 부모이다.



is_a_parent_of(X, Y):- is_the_mother_of(X, Y).

is_a_parent_of(X, Y):- is_the_father_of(X, Y).



4) 어떤 것이 용이라면 그 어떤 것은 생물이다.



is_a_creature(X) :-

is_a_dragon(X).



5) 노베르타는 용이고, 퍼프는 생물이다. 노베르타는 퍼프의 어머니이다.



is_a_dragon(norberta).

is_a_creature(puff).

is_the_mother_of(norberta, puff).



규칙 (2)는 재귀 (귀납적) 정의이다. 이것은 실행 방식에 대한 이해 없이 선언적으로 이해할 수 있다.

규칙 (3)은 함수가 관계를 사용하여 어떻게 표현되는지 보여준다. 여기서, 어머니와 아버지 함수는 모든 개인이 하나의 어머니와 하나의 아버지 만 갖도록 한다.

프롤로그는 무형 언어이다. 그럼에도 불구하고, 상속은 술어를 사용하여 표현할 수 있다. 규칙 (4)는 생물이 용의 상위 클래스임을 주장한다.

질문은 역추론을 사용하여 답변된다. 질문이 주어지면:



?- billows_fire(X).



프롤로그는 두 가지 답변을 생성한다.



X = norberta

X = puff



프롤로그의 실용적인 응용 분야는 지식 표현과 인공 지능에서의 문제 해결이다.

4. 0. 3. 객체 지향 프로그래밍



'''객체 지향 프로그래밍'''(Object-Oriented Programming|오브젝트 오리엔티드 프로그래밍eng, '''OOP''')은 객체에 대해 연산(함수)을 실행하는 프로그래밍 방식이다.[68][91] 기본적인 아이디어는 현실 세계의 현상이나 개념의 특징(데이터)과 관련 동작(연산)을 하나의 '객체'라는 컨테이너로 묶어 관리하는 것이다.[91]

1970년대에 소프트웨어 규모가 커지면서, 개발자들은 대규모 프로젝트를 관리하기 쉬운 작은 단위, 즉 모듈로 나누는 방법이 필요했다.[65] 단순히 파일을 나누는 물리적 분해뿐만 아니라, 프로그램을 논리적으로 추상 자료형 단위로 나누는 방식이 중요해졌다.[65] 추상 자료형은 기존의 정수, 부동소수점, 문자열 같은 구체적인 자료형들을 조합하여 새로운 자료형을 정의하는 개념이다. 예를 들어, 여러 개의 정수를 묶어 '정수 리스트'라는 새로운 자료형을 만드는 식이다.

객체 지향 프로그래밍에서는 이러한 추상 자료형을 클래스라고 부른다. 클래스는 객체를 만들기 위한 '설계도'나 '틀'에 해당하며, 그 자체로는 메모리를 차지하지 않는다. 이 클래스를 바탕으로 실제 메모리 공간을 할당받아 만들어진 것을 객체라고 한다.[66] 객체는 자신만의 데이터(속성)와 그 데이터를 처리하는 연산(메서드)을 가지고 있다. 객체 지향 프로그래밍은 바로 이 객체들에 대해 연산을 수행하는 방식으로 프로그램을 구성한다.[68]

객체 지향 언어의 중요한 특징 중 하나는 상속이다. 상속은 집합론의 부분 집합/상위 집합 관계처럼, 한 클래스(하위 클래스)가 다른 클래스(상위 클래스)의 속성과 연산을 물려받는 기능이다.[69] 예를 들어, '학생' 클래스는 '사람' 클래스의 하위 클래스로 정의될 수 있다. 이때 학생은 사람의 모든 속성(이름, 나이 등)을 물려받으면서, 학생만의 고유한 속성(학번, 전공 등)을 추가로 가질 수 있다. 상속은 코드의 재사용성을 높이고 클래스 간의 관계를 명확하게 표현하는 데 도움을 준다.[69]

객체 지향 프로그래밍은 모듈화와 안전한 함수형 프로그래밍의 필요성을 결합하며 발전했으며[67][92], 1990년대 후반에는 가장 널리 사용되는 프로그래밍 패러다임 중 하나가 되었다.[65] 대표적인 객체 지향 언어로는 C++, 자바 등이 있다. C++는 1985년에 등장했으며, 원래 이름은 "C with Classes"였다.[70] 이름처럼 C 언어의 기능을 확장하면서 Simula 언어의 객체 지향 개념을 도입하여 설계되었다.[71]

다음은 C++를 이용한 간단한 학교 관련 클래스 예시이다.

  • GRADE 클래스 (성적): 학생의 성적(A, B, C 등)을 문자로 저장하고, 이를 숫자 등급(4, 3, 2 등)으로 변환하는 기능을 가진다.




// grade.h (헤더 파일)

#ifndef GRADE_H

#define GRADE_H

class GRADE {

public:

GRADE(const char letter); // 생성자: 객체 생성 시 호출됨

char letter; // 멤버 변수: 문자 등급 저장

int grade_numeric(const char letter); // 멤버 함수: 문자 등급을 숫자 등급으로 변환

int numeric; // 멤버 변수: 숫자 등급 저장

};

#endif

// grade.cpp (소스 파일)

#include "grade.h"

GRADE::GRADE(const char letter) {

this->letter = letter;

this->numeric = grade_numeric(letter); // 생성 시 숫자 등급 계산

}

int GRADE::grade_numeric(const char letter) {

// 문자 등급에 따라 숫자 등급 반환 (A=4, B=3, ...)

if ((letter == 'A' || letter == 'a')) return 4;

else if ((letter == 'B' || letter == 'b')) return 3;

else if ((letter == 'C' || letter == 'c')) return 2;

else if ((letter == 'D' || letter == 'd')) return 1;

else if ((letter == 'F' || letter == 'f')) return 0;

else return -1; // 유효하지 않은 등급

}


  • PERSON 클래스 (사람): 사람의 이름을 저장하는 기본적인 클래스이다.




// person.h (헤더 파일)

#ifndef PERSON_H

#define PERSON_H

class PERSON {

public:

PERSON(const char *name); // 생성자

const char *name; // 멤버 변수: 이름 저장

};

#endif

// person.cpp (소스 파일)

#include "person.h"

PERSON::PERSON(const char *name) {

this->name = name;

}


  • STUDENT 클래스 (학생): PERSON 클래스를 상속받아 학생을 표현한다. 학생은 사람의 속성(이름)을 가지며, 추가로 성적(GRADE 객체)을 가진다.




// student.h (헤더 파일)

#ifndef STUDENT_H

#define STUDENT_H

#include "person.h" // PERSON 클래스 포함

#include "grade.h" // GRADE 클래스 포함

// STUDENT 클래스는 PERSON 클래스를 상속받음 (public 상속)

class STUDENT : public PERSON {

public:

STUDENT(const char *name); // 생성자

GRADE *grade; // 멤버 변수: 학생의 성적 (GRADE 객체 포인터)

};

#endif

// student.cpp (소스 파일)

#include "student.h"

#include "person.h"

// STUDENT 생성자 구현

STUDENT::STUDENT(const char *name) : PERSON(name) { // 상위 클래스(PERSON)의 생성자 호출

// 추가적인 초기화 작업 없음

}


  • 메인 프로그램: STUDENT 객체를 생성하고, 상속받은 이름과 할당된 성적 정보를 출력한다.




// student_dvr.cpp (메인 프로그램)

#include

#include "student.h"

int main(void) {

// "The Student"라는 이름의 STUDENT 객체 생성

STUDENT *student = new STUDENT("The Student");

// 학생에게 'a' 등급의 GRADE 객체 할당

student->grade = new GRADE('a');

// 학생의 이름(PERSON으로부터 상속)과 숫자 등급 출력

std::cout << student->name << ": Numeric grade = " << student->grade->numeric << "\n";

// 동적 할당된 메모리 해제 (실제 코드에서는 필요)

// delete student->grade;

// delete student;

return 0;

}



객체 지향 설계를 위한 일반적인 전략은 다음과 같다.[95]

1. 객체 식별: 프로그램에서 다룰 주요 대상(주로 명사)을 찾는다. (예: 사람, 성적, 학생)

2. 속성 식별: 각 객체가 가지는 특징이나 상태(데이터)를 정의한다. (예: 사람의 이름, 성적의 문자 값)

3. 작업 식별: 각 객체가 수행할 수 있는 행동이나 기능(주로 동사)을 정의한다. (예: 성적을 숫자로 변환하다)

4. 관계 식별: 객체들 사이의 관계(상속, 포함 등)를 파악한다. (예: 학생은 사람이다, 학생은 성적을 가진다)

객체 지향 프로그래밍 개념은 반드시 객체 지향 언어에서만 구현 가능한 것은 아니다.[93] 예를 들어 C 언어와 같이 객체 지향을 직접 지원하지 않는 언어에서도 구조체를 사용하여 데이터(속성)를 묶고, 해당 구조체를 다루는 함수들을 만들어 추상 자료형과 유사하게 구현할 수 있다.[94] 다만, 이 경우 상속과 같은 객체 지향의 모든 특징을 자연스럽게 활용하기는 어렵다.

4. 1. 프로그래밍 언어의 세대

컴퓨터 프로그래밍의 발전은 컴퓨터 하드웨어의 발전과 밀접한 관련이 있다. 하드웨어 기술이 발전함에 따라 프로그래밍 방식 또한 크게 변화해왔다.

초기 컴퓨터 중 하나인 ENIAC(전자 수치 적분 계산기, 1945년 완성)은 튜링 완전성을 갖춘 범용 컴퓨터였지만, 프로그래밍 방식은 매우 원시적이었다. 진공관 기반의 이 기계는 프로그램을 실행하기 위해 전선을 직접 연결하고 수많은 스위치를 조작해야 했다.[18] 예를 들어, 함수 테이블을 물리적으로 옮겨 플러그 보드에 케이블로 연결하고, 3,000개에 달하는 스위치를 설정하는 방식이었다. 이 때문에 ENIAC를 프로그래밍하는 데는 최대 2개월이 소요되었고, 프로그램 디버깅에도 일주일이 걸렸다.[18][19] 이는 오늘날의 기계어나 어셈블리 언어와 같은 저수준 프로그래밍보다도 훨씬 직접적이고 물리적인 방식이었다.

ENIAC의 튜브를 교체하는 글렌 A. 베크


이후 존 폰 노이만 등이 제시한 저장 프로그램 방식 컴퓨터 개념이 등장하면서 프로그래밍 방식에 혁신이 일어났다.[21][22] 이 방식은 명령어(프로그램)를 데이터와 마찬가지로 컴퓨터의 메모리에 저장하여 실행하는 방식으로, EDVAC나 EDSAC(1949년) 같은 컴퓨터에 적용되었다.[24] 덕분에 전선을 일일이 연결하는 대신 메모리에 프로그램을 로드하여 훨씬 빠르고 유연하게 컴퓨터를 프로그래밍할 수 있게 되었다.[22]

1960년대에 등장한 IBM System/360(1964년)과 같은 컴퓨터는 멀티프로그래밍 기능을 지원하며 더 복잡한 작업을 수행할 수 있게 되었다.[25] 이 시기에는 COBOL, Fortran, ALGOL과 같은 고급 프로그래밍 언어들이 사용되었고, IBM은 이들을 대체할 목적으로 PL/1이라는 새로운 언어를 개발하기도 했다.[26] 이러한 고급 언어들은 인간이 이해하기 쉬운 문법을 사용하여 프로그래밍 생산성을 크게 높였으며, 오늘날 프로그래밍 언어의 3세대로 분류될 수 있는 특징을 보여준다.

1970년대 중반에 제조된 데이터 제너럴 노바 3의 수동 입력을 위한 스위치


하지만 1970년대까지도 일부 컴퓨터에는 여전히 전면 패널 스위치를 이용한 수동 프로그래밍 방식이 남아 있었다.[28] 프로그램을 종이에 작성한 뒤, 명령어에 해당하는 스위치 조합을 설정하고 실행 버튼을 누르는 과정을 반복하는 방식이었다. 물론 천공 테이프나 펀치 카드, 자기 테이프를 이용한 자동 입력 방식도 사용되었다.[28]

마이크로컴퓨터 시대가 열리면서 BASIC(1964년)과 같은 언어가 중요한 역할을 했다. BASIC은 "초보자를 위한 만능 기호 지시 코드"라는 이름처럼 다트머스 대학교에서 학생들이 쉽게 배울 수 있도록 개발되었다.[8] 배우기 쉬운 문법 덕분에 1970년대 후반부터 마이크로컴퓨터에 기본적으로 탑재되었고, 대화형 세션을 통해 사용자와 상호작용하며 프로그래밍할 수 있는 환경을 제공했다.[8] 비록 초기 BASIC의 문법은 대규모 프로그램을 작성하기에는 단순했지만, 이후 구조적 및 객체 지향 개념이 추가되면서 발전했으며, 마이크로소프트비주얼 베이직과 같은 형태로 여전히 사용되고 있다.[7][8]

4. 2. 구문과 의미론

생성 규칙은 터미널과 비터미널의 집합으로 구성된다.


컴퓨터 프로그램의 구문(syntax)은 그 문법을 형성하는 생성 규칙의 목록이다.[96] 프로그래밍 언어의 문법은 선언, 표현식, 문 등이 어떻게 정확하게 배치되어야 하는지를 규정한다.[97] 언어의 구문을 보완하는 것은 의미론(semantics)이다. 의미론은 다양한 구문 구조에 부여되는 의미를 설명한다.[98] 때로는 구문 구조가 생성 규칙상 유효하더라도 여러 가지로 해석될 여지가 있어 의미론적 설명이 필요할 수 있다.[99] 또한, 서로 다른 언어가 동일한 구문을 가지면서도 실제 동작은 다를 수 있다.

언어의 구문은 생성 규칙을 나열하여 공식적으로 설명된다. 자연어의 구문은 매우 복잡하지만, 영어의 일부를 예로 들면 다음과 같은 생성 규칙 목록을 가질 수 있다.[100]

# 문장명사구 다음에 동사구가 오는 것으로 구성된다.

# 명사구관사 다음에 형용사 다음에 명사가 오는 것으로 구성된다.

# 동사구동사 다음에 명사구가 오는 것으로 구성된다.

# 관사는 'the'이다.

# 형용사는 'big' 또는

# 형용사는 'small'이다.

# 명사는 'cat' 또는

# 명사는 'mouse'이다.

# 동사는 'eats'이다.

여기서 굵은 글씨로 표시된 단어들은 비터미널(non-terminal)이라고 하며, '작은 따옴표' 안의 단어들은 터미널(terminal)이라고 한다.[101]

이 생성 규칙 목록을 사용하여 일련의 대체를 통해 완전한 문장을 만들 수 있다.[102] 이 과정은 비터미널을 유효한 다른 비터미널이나 터미널로 바꾸는 것이다. 이 대체 과정은 터미널만 남을 때까지 반복된다. 예를 들어, 다음과 같은 유효한 문장을 생성할 수 있다.

  • sentence
  • noun-phrase verb-phrase
  • article adjective noun verb-phrase
  • ''the'' adjective noun verb-phrase
  • ''the'' ''big'' noun verb-phrase
  • ''the'' ''big'' ''cat'' verb-phrase
  • ''the'' ''big'' ''cat'' verb noun-phrase
  • ''the'' ''big'' ''cat'' ''eats'' noun-phrase
  • ''the'' ''big'' ''cat'' ''eats'' article adjective noun
  • ''the'' ''big'' ''cat'' ''eats'' ''the'' adjective noun
  • ''the'' ''big'' ''cat'' ''eats'' ''the'' ''small'' noun
  • ''the'' ''big'' ''cat'' ''eats'' ''the'' ''small'' ''mouse''


하지만 이 규칙만으로는 다음과 같이 문법적으로는 맞지만 의미상 어색하거나 다른 의미를 가질 수 있는 문장도 생성될 수 있다.

  • ''the'' ''small'' ''mouse'' ''eats'' ''the'' ''big'' ''cat''


따라서 'eats'라는 행위의 정확한 의미를 설명하기 위해서는 의미론이 필요하다.

생성 규칙 목록을 표현하는 한 가지 방법으로 바커스-나우르 형식(BNF, Backus-Naur Form)이 있다.[103] BNF는 언어의 구문을 설명하는 데 사용되며, BNF 자체도 고유한 구문을 가지고 있다. 이러한 재귀적 정의는 메타 언어의 한 예이다.[98] BNF의 구문에는 다음 요소들이 포함된다.

  • `::=` : 오른쪽에 비터미널이 올 경우 '~로 구성된다'로 해석하고, 터미널이 올 경우 '~이다'로 해석한다.
  • `|` : '또는'(or)으로 해석한다.
  • `<` 와 `>` : 비터미널을 감싸는 기호이다.


BNF를 사용하면 앞서 예로 든 영어의 하위 집합은 다음과 같은 생성 규칙 목록으로 표현될 수 있다.

::=

::=


::=

::= the

::= big | small

::= cat | mouse

::= eats

또한, BNF를 사용하여 부호가 있는 정수를 다음과 같은 생성 규칙 목록으로 정의할 수 있다.[104]

::=

::= + | -

::= |

::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

여기서 다음과 같은 재귀적인 생성 규칙에 주목할 필요가 있다.

::= |

이 규칙은 이론적으로 무한한 길이의 정수를 허용한다. 따라서 실제 컴퓨터 시스템에서 표현 가능한 자릿수의 제한 등을 설명하기 위해서는 의미론이 필요하다.

또한, 위 생성 규칙에서는 숫자 앞에 0이 붙는 경우(예: 01, 007)도 허용된다.

::= |

::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

따라서 이러한 선행 0을 어떻게 처리할지(예: 무시할지 여부)를 명확히 하기 위해서도 의미론이 필요하다.
의미론을 공식적으로 설명하는 데 사용될 수 있는 두 가지 주요 방법론으로는 지시적 의미론(Denotational semantics)과 공리적 의미론(Axiomatic semantics)이 있다.[105]

5. 소프트웨어 공학과 컴퓨터 프로그래밍

프로그래밍 언어가 나오기 전, 베티 제닝스와 프랜 빌라스는 케이블을 옮기고 스위치를 설정하여 ENIAC을 프로그래밍했다.


소프트웨어 공학은 ''품질'' 있는 컴퓨터 프로그램을 생산하기 위한 다양한 기술을 다루는 분야이다.[106] 컴퓨터 프로그래밍 자체는 소스 코드를 작성하거나 편집하는 과정을 의미한다.

공식적인 개발 환경에서는 시스템 분석가가 중요한 역할을 한다. 시스템 분석가는 자동화하려는 조직의 프로세스에 대한 정보를 관리자로부터 수집하고, 이를 바탕으로 새로운 시스템 또는 수정될 시스템에 대한 상세 계획을 준비한다.[107] 이 계획은 마치 건축가의 설계도처럼 시스템 개발의 청사진 역할을 한다.[107]

5. 1. 성능 목표

시스템 분석가는 적절한 정보를 적절한 사람에게 적절한 시간에 전달하는 것을 목표로 한다.[108] 이 목표를 달성하기 위한 중요한 요소는 다음과 같다.[108]

  • '''출력의 품질''': 출력이 의사 결정에 유용한가?
  • '''출력의 정확성''': 실제 상황을 정확하게 반영하는가?
  • '''출력의 형식''': 출력이 쉽게 이해되는가?
  • '''출력의 속도''': 시간 제약적인 정보는 고객과의 실시간 소통에서 중요하다.

5. 2. 비용 목표

성능 목표를 달성하는 것은 여러 가지 비용 요소를 고려하여 균형을 맞추어야 한다.[109] 주요 비용 요소는 다음과 같다.

  • '''개발 비용:''' 프로그램을 만드는 데 드는 비용.
  • '''고유성 비용:''' 특정 목적에만 사용되는 프로그램 대신 여러 곳에 다시 사용할 수 있는 프로그램을 만드는 데 드는 추가 비용. 때로는 재사용 가능한 시스템이 더 선호될 수 있다.
  • '''하드웨어 비용:''' 프로그램을 실행하는 데 필요한 컴퓨터 부품 등의 비용.
  • '''운영 비용:''' 프로그램을 유지하고 관리하는 데 드는 비용.


시스템 개발 생명 주기와 같은 체계적인 개발 과정을 따르면, 개발 후반부에 오류를 발견하고 수정하는 데 드는 큰 비용을 줄이는 데 도움이 될 수 있다.[110]

5. 3. 폭포수 모델

폭포수 모델시스템 개발 프로세스의 구현 방식이다.[111] 폭포수라는 이름이 의미하듯이, 기본적인 단계들은 서로 겹치지 않고 순차적으로 진행된다:[112]

# 조사 단계는 근본적인 문제를 이해하기 위한 단계이다.

# 분석 단계는 가능한 해결책을 이해하기 위한 단계이다.

# 설계 단계는 최상의 해결책을 계획하기 위한 단계이다.

# 구현 단계는 최상의 해결책을 프로그래밍하는 단계이다.

# 유지보수 단계는 시스템의 수명 전체에 걸쳐 지속된다. 시스템 배포 후 변경이 필요할 수 있다.[113] 사양 오류, 설계 오류 또는 코딩 오류를 포함한 결함이 존재할 수 있다. 개선이 필요할 수 있으며, 변화하는 환경에 대응하기 위해 적응이 필요할 수 있다.

5. 4. 컴퓨터 프로그래머

컴퓨터 프로그래머는 상세한 계획을 구현하기 위해 소스 코드를 작성하거나 수정하는 전문가이다.[107] 대부분의 시스템은 한 명의 프로그래머가 완료하기에는 너무 크기 때문에 프로그래밍 팀이 필요할 가능성이 높다.[114] 하지만 프로젝트에 프로그래머를 추가한다고 해서 완료 시간이 단축되는 것은 아니며, 오히려 시스템의 품질이 저하될 수도 있다.[114] 효율성을 위해서는 프로그램 모듈을 명확히 정의하고 팀원에게 적절히 배분해야 한다.[114] 또한, 팀원들은 의미 있고 효과적인 방식으로 서로 상호 작용하는 것이 중요하다.[114]

컴퓨터 프로그래머는 소규모 프로그래밍, 즉 단일 모듈 내에서 프로그래밍하는 작업을 수행할 수 있다.[115] 모듈은 다른 소스 코드 파일에 있는 모듈을 실행할 가능성이 높기 때문에, 컴퓨터 프로그래머는 대규모 프로그래밍도 수행한다. 이는 여러 모듈이 서로 효과적으로 결합되도록 프로그래밍하는 것을 의미하며,[115] 응용 프로그래밍 인터페이스 (API) 개발에 기여하는 것을 포함한다.

5. 5. 프로그램 모듈

모듈형 프로그래밍은 ''명령형 언어'' 프로그램을 개선하는 기법으로, 프로그램의 크기를 줄이고 책임을 분리하여 소프트웨어 노후화를 완화하는 데 도움을 준다. ''프로그램 모듈''이란 블록 안에 포함되며 이름으로 식별되는 일련의 문장들을 의미한다.[116]

모듈은 다음과 같은 세 가지 요소를 갖는다:[117]

  • '''기능''': 모듈이 수행하는 작업.
  • '''컨텍스트''': 작업이 수행되는 대상 요소.
  • '''논리''': 기능을 수행하는 구체적인 방법.


모듈의 이름은 먼저 ''기능''을 나타내고, 그 다음으로 ''컨텍스트''를 나타내도록 짓는 것이 좋다. 모듈의 ''논리''는 이름에 포함시키지 않아야 한다.[117] 예를 들어, function compute_square_root( x )function compute_square_root_integer( i : integer )는 적절한 이름이지만, function compute_square_root_by_division( x )처럼 구현 방식을 이름에 넣는 것은 바람직하지 않다.

모듈 ''내부'' 요소들 간의 상호 작용 정도를 응집도라고 하며, 이는 모듈의 이름과 기능 간의 관련성을 나타낸다.[117] 반면, 모듈 ''간''의 상호 작용 정도는 결합도라고 하며, 이는 모듈의 컨텍스트와 실제 작업 대상 간의 관계를 보여준다.[118]

5. 5. 1. 응집도 (Cohesion)

응집도의 수준은 최악에서 최고 순으로 다음과 같다.[119]

  • 우연적 응집도 (Coincidental cohesion): 모듈이 서로 관련 없는 여러 기능을 포함하는 경우이다. 예를 들어, read_sales_record_print_next_line_convert_to_float()와 같은 함수가 이에 해당한다. 이러한 유형의 응집도는 때때로 "모든 모듈은 35개에서 50개의 실행 문을 가져야 한다"와 같은 비합리적인 개발 규칙 때문에 발생하기도 한다.[119]
  • 논리적 응집도 (Logical cohesion): 모듈이 유사한 성격의 여러 기능을 포함하고, 호출 시 특정 기능 하나만 선택되어 실행되는 경우이다. 예를 들어, perform_arithmetic( perform_addition, a, b )와 같이 다양한 산술 연산 중 하나를 수행하는 함수가 있다.
  • 시간적 응집도 (Temporal cohesion): 모듈 내의 기능들이 특정 시점에 함께 실행되어야 하는 관련성을 가질 때이다. 예를 들어, 프로그램 시작 시 변수를 초기화하고 파일을 여는 initialize_variables_and_open_files() 함수나, 특정 작업 단계를 순서대로 묶은 stage_one(), stage_two() 등이 해당된다.
  • 절차적 응집도 (Procedural cohesion): 모듈 내의 기능들이 특정 순서에 따라 실행되어야 하는 경우이다. 기능들은 순차적으로 처리되지만, 반드시 동일한 데이터 구조를 다루지는 않는다. 예를 들어, 부품 번호를 읽은 후 직원 기록을 업데이트하는 read_part_number_update_employee_record() 함수가 있다.
  • 통신적 응집도 (Communicational cohesion): 모듈 내의 기능들이 동일한 입력 데이터를 사용하거나 동일한 출력 데이터를 생성하는 경우, 즉 동일한 데이터 구조를 공유할 때이다. 예를 들어, 부품 번호를 읽고 해당 부품의 판매 기록을 업데이트하는 read_part_number_update_sales_record() 함수처럼, 기능들이 동일한 데이터를 중심으로 작동한다.
  • 정보적 응집도 (Informational cohesion): 모듈이 특정 데이터 구조를 중심으로 관련된 여러 기능을 수행하며, 각 기능은 독립적인 인터페이스(진입점/종료점)를 갖는 경우이다. 객체 지향클래스가 대표적인 예시이며, 동일한 데이터 구조를 공유하는 기능들을 묶는다.
  • 기능적 응집도 (Functional cohesion): 모듈이 단일 기능을 수행하며, 해당 기능을 완전히 캡슐화한 경우이다. 모듈 내부 요소들이 오직 하나의 목표를 달성하기 위해 협력하며, 주로 지역 변수만을 사용한다. 다른 컨텍스트에서도 재사용하기 용이하며, 가장 이상적인 응집도 수준으로 간주된다.

5. 5. 2. 결합도 (Coupling)

결합도는 모듈 간의 상호 의존 정도를 나타내는 척도로, 결합도가 낮을수록 각 모듈의 독립성이 높아져 좋은 설계로 평가받는다. 결합도는 일반적으로 의존성이 높은 순서(최악)부터 낮은 순서(최선)까지 다음과 같이 분류된다.[118]

  • 내용 결합 (Content coupling): 한 모듈이 다른 모듈의 내부 데이터나 코드를 직접 수정하는 경우이다. 예를 들어, 다른 모듈의 지역 변수에 직접 접근하거나 코드를 변경하는 경우가 해당된다. 과거 코볼(COBOL) 언어의 `ALTER` 명령어가 이러한 방식의 예시이다. 이는 가장 높은 결합도에 해당한다.
  • 공통 결합 (Common coupling): 여러 모듈이 전역 변수와 같은 공통 데이터 영역을 공유하고 이를 수정하는 경우이다. 전역 변수를 통해 모듈들이 연결되므로, 한 모듈에서의 변경이 다른 모듈에 예기치 않은 영향을 줄 수 있다.
  • 제어 결합 (Control coupling): 한 모듈이 다른 모듈의 동작 방식을 결정하는 제어 정보(예: 플래그 값, 함수 포인터)를 전달하여 제어 흐름에 영향을 미치는 경우이다. 예를 들어, `perform_arithmetic(perform_addition, a, b)`와 같이 어떤 연산을 수행할지를 매개변수로 전달하여 다른 모듈의 행동을 제어하는 방식이다. 제어 정보 대신, 필요한 기능을 수행하고 결과를 반환하는 방식으로 설계하는 것이 권장된다.
  • 스탬프 결합 (Stamp coupling): 모듈 간에 자료 구조(예: 객체, 레코드)를 매개변수로 전달하지만, 실제로는 그 구조의 일부 데이터만 사용하거나 전달된 자료 구조의 일부를 수정하는 경우이다. 객체 지향의 클래스를 사용하는 경우 이 수준의 결합이 발생할 수 있다.
  • 데이터 결합 (Data coupling): 모듈 간에 필요한 데이터만을 매개변수를 통해 전달하고, 전달된 데이터는 수정되지 않는 경우이다. 또한, 함수의 결과는 단일 값이나 객체 형태로 반환된다. 모듈 간의 상호 작용이 명확하고 필요한 정보만 교환하므로 가장 바람직한 결합도로 여겨진다.

5. 6. 데이터 흐름 분석

샘플 함수 수준 데이터 흐름도


데이터 흐름 분석은 기능적 응집도데이터 결합도의 모듈을 달성하기 위해 사용되는 설계 방법이다.[120] 이 방법의 입력은 데이터 흐름도이다. 데이터 흐름도는 모듈을 나타내는 일련의 타원형 도형이며, 각 모듈의 이름은 타원형 도형 안에 표시된다. 모듈은 실행 가능 수준 또는 함수 수준일 수 있다.

이 다이어그램에는 모듈을 서로 연결하는 화살표도 포함된다. 모듈을 가리키는 화살표는 일련의 입력을 나타낸다. 각 모듈은 단일 출력 객체를 나타내기 위해 단 하나의 화살표만 가져야 한다(선택적으로 추가 예외 화살표가 가리킬 수 있음). 일련의 타원형 도형은 전체 알고리즘을 전달한다. 입력 모듈이 다이어그램을 시작해야 하며, 변환 모듈에 연결되어야 한다. 변환 모듈은 다시 출력 모듈에 연결되어야 한다.[121]

6. 기능적 범주

사용자응용 소프트웨어와 상호 작용하는 것을 보여주는 다이어그램. 응용 소프트웨어는 운영 체제와 상호 작용하며, 운영 체제는 컴퓨터 하드웨어와 상호 작용한다.


컴퓨터 프로그램은 기능적 범주에 따라 크게 응용 소프트웨어시스템 소프트웨어로 나눌 수 있다. 시스템 소프트웨어에는 운영 체제가 포함되는데, 이는 컴퓨터 하드웨어와 응용 소프트웨어를 연결하는 역할을 한다.[122] 운영 체제의 주된 목적은 응용 소프트웨어가 편리하고 효율적으로 실행될 수 있는 환경을 만드는 것이다.[122] 응용 소프트웨어와 시스템 소프트웨어 모두 특정 작업을 돕는 유틸리티 소프트웨어를 활용할 수 있다. 더 낮은 하드웨어 수준에서는 마이크로코드 프로그램이 중앙 처리 장치(CPU) 내부 회로를 직접 제어한다.

6. 1. 응용 소프트웨어 (Application software)

응용 소프트웨어는 컴퓨터 시스템의 능력을 최대한 활용하게 해주는 중요한 요소이다.[123] 전사적 응용 소프트웨어는 기업 운영에 필요한 회계, 인사 관리, 고객 관리, 공급업체 관리 등의 다양한 기능을 하나로 묶어 제공한다. 대표적인 예로는 전사적 자원 관리(ERP), 고객 관계 관리(CRM), 공급망 관리(SCM) 소프트웨어 등이 있다.

기업은 이러한 전사적 응용 프로그램을 필요에 따라 직접 개발하여 독점 소프트웨어로 사용할 수도 있고,[124] 이미 만들어져 판매되는 기성품 소프트웨어를 구매하여 사용할 수도 있다. 구매한 기성품 소프트웨어는 기업의 특수한 요구에 맞게 수정하여 맞춤형 소프트웨어처럼 활용하기도 한다. 소프트웨어를 맞춤 개발하거나 수정할 때는 기업 내부 자원을 활용하거나, 외부 업체에 개발을 맡기는 아웃소싱 방식을 이용할 수 있다. 아웃소싱은 원래 소프트웨어를 만든 회사나 제3의 개발 전문 업체가 담당할 수 있다.[125]
자체 개발 소프트웨어는 다음과 같은 장단점을 가진다.[126][127][128][124]

  • 장점:
  • 기업이 원하는 기능과 보고 형식을 정확하게 구현할 수 있다.
  • 경영진이 개발 과정에 직접 참여하여 진행 상황을 관리하고 통제할 수 있다.
  • 경쟁사의 새로운 전략에 대응하거나 고객 및 공급업체의 요구 사항을 빠르게 반영할 수 있다.
  • 기업 합병이나 인수 시 필요한 소프트웨어 변경에 유연하게 대처할 수 있다.
  • 단점:
  • 개발에 많은 시간과 비용이 소요될 수 있다.
  • 개발된 소프트웨어의 기능이나 성능이 기대에 미치지 못할 위험이 있다.

기성품 소프트웨어는 다음과 같은 장단점을 가진다.[124]

  • 장점:
  • 초기 도입 비용을 명확하게 파악할 수 있다.
  • 기업의 기본적인 요구 사항을 충족하는 경우가 많다.
  • 이미 시장에서 사용되며 성능과 안정성이 검증된 경우가 많다.
  • 단점:
  • 기업에 필요하지 않은 기능까지 포함되어 있어 최종 사용자가 사용하기에 복잡하거나 혼란스러울 수 있다.
  • 기업 운영에 꼭 필요한 특정 기능이 누락되어 있을 수 있다.
  • 소프트웨어의 데이터 처리 방식이 기업의 실제 업무 절차와 맞지 않을 수 있다.


기업의 요구에 맞는 맞춤형 전사적 응용 프로그램을 경제적으로 도입하는 또 다른 방법은 애플리케이션 서비스 제공업체(ASP)를 이용하는 것이다.[129] ASP는 전문성을 바탕으로 하드웨어, 맞춤형 소프트웨어 제공 및 최종 사용자 지원까지 포괄적인 서비스를 제공한다. 숙련된 정보 시스템 인력을 보유하고 있어 새로운 응용 프로그램 개발 속도를 높일 수 있다는 장점이 있다. 특히, 기업 내부 자원을 복잡한 IT 프로젝트 관리 부담에서 벗어나 핵심 업무에 집중할 수 있게 해준다.[129] 이러한 장점 때문에 정보 시스템 자원이 부족한 중소기업이나 빠르게 성장하는 기업들이 ASP를 많이 이용한다.[129] 반면, 자체적인 기술 인프라를 갖춘 대기업은 ASP 활용 필요성이 상대적으로 적을 수 있다. ASP 이용 시에는 기업의 민감한 정보를 외부에 맡겨야 하는 보안 위험과 서비스 제공업체의 인프라 안정성에 의존해야 하는 위험을 고려해야 한다.[129]

6. 2. 시스템 소프트웨어 (System Software)

시스템 소프트웨어는 컴퓨터 하드웨어응용 소프트웨어 사이를 중재하며 컴퓨터 시스템 전체를 효율적으로 운영하고 관리하는 소프트웨어이다. 이는 사용자가 컴퓨터를 편리하고 효과적으로 사용할 수 있도록 기반 환경을 제공한다.

대표적인 시스템 소프트웨어로는 운영 체제(OS)가 있다. 운영 체제는 프로세스 관리, 컴퓨터 메모리 관리, 주변 장치 제어 등 컴퓨터의 기본적인 기능을 수행하며[122], 명령줄 인터페이스, 그래픽 사용자 인터페이스 등을 통해 사용자와 컴퓨터 간의 상호작용을 돕는다.[131] 또한, 시스템의 성능을 최적화하거나 특정 작업을 보조하는 유틸리티 소프트웨어 역시 시스템 소프트웨어의 중요한 일부로 분류된다.[131]

6. 2. 1. 운영 체제 (Operating System)

프로그램 대 프로세스 대 스레드. 스케줄링, 선점, 문맥 전환.


운영 체제는 프로세스를 스케줄링하고 주변 장치를 제어하는 등 컴퓨터의 기본 기능을 지원하는 하위 수준의 소프트웨어이다.[122]

1950년대에는 프로그래머가 직접 프로그램을 작성하고 실행하는 운영자 역할까지 수행했다. 프로그램 실행이 끝나면 결과는 인쇄되거나 나중에 처리하기 위해 종이 테이프나 카드에 기록되었다.[28] 프로그램이 제대로 작동하지 않는 경우가 많았고, 이때 프로그래머는 콘솔의 표시등을 확인하고 스위치를 조작하여 문제를 해결하려 했다. 문제가 심각할 경우, 메모리 내용을 출력하여 추가 분석을 진행하기도 했다. 1960년대에 들어서면서 프로그래머들은 이러한 운영자의 작업을 자동화하여 낭비되는 시간을 줄이기 시작했다. 이 과정에서 컴퓨터에 항상 상주하는 "운영 체제"라는 프로그램이 등장하게 되었다.[130]

"운영 체제"라는 용어는 두 가지 의미로 사용될 수 있다.[131] 좁은 의미로는 프로세스, 컴퓨터 메모리, 주변 장치 등을 관리하는 핵심 프로그램인 커널을 지칭한다. 넓은 의미로는 커널을 포함하여 명령줄 인터페이스, 그래픽 사용자 인터페이스, 유틸리티 소프트웨어, 소스 코드 편집기 등을 모두 아우르는 중앙 소프트웨어 패키지 전체를 의미한다.[131]

커널은 컴퓨터의 응용 소프트웨어를 하드웨어에 연결한다.


커널의 주요 목적은 컴퓨터의 제한된 자원을 효율적으로 관리하는 것이다. 커널 프로그램은 다음과 같은 주요 기능들을 수행한다.

  • 프로세스 스케줄링: 커널은 여러 프로세스가 중앙 처리 장치(CPU)를 공평하게 사용할 수 있도록 관리한다.[132] 이를 문맥 교환(context switching)이라고도 부른다. 프로그램이 실행되도록 선택되면 커널은 해당 프로그램의 프로세스 제어 블록(PCB)을 생성한다. 하지만 실행 중인 프로그램은 CPU를 정해진 시간 조각(time slice) 동안만 독점적으로 사용할 수 있다. 커널은 각 프로세스 제어 블록을 빠르게 선점(preemption)하고 다른 프로세스를 실행시켜, 여러 사용자나 프로그램이 동시에 컴퓨터를 사용하는 것처럼 보이게 한다(시분할 시스템). 시스템 프로그래밍 개발자들은 이러한 전환에 걸리는 시간(디스패치 지연 시간)을 최소화하는 것을 목표로 한다.

물리 메모리는 RAM과 하드 디스크에 흩어져 있을 수 있지만, 가상 메모리는 하나의 연속적인 주소 공간처럼 보인다.

  • 메모리 관리: 커널은 컴퓨터의 메모리를 효율적으로 관리한다.
  • 커널이 실행 파일을 메모리에 처음 로드할 때, 프로그램의 주소 공간을 논리적인 영역(region)으로 나눈다.[133] 커널은 마스터 영역 테이블과 각 프로세스별 영역 테이블(pregion table)을 유지 관리한다.[133] 이 테이블들은 프로그램이 사용하는 가상 주소 공간을 구성한다. 마스터 영역 테이블은 가상 주소가 실제 물리 메모리의 어느 위치에 저장되어 있는지 추적하는 데 사용된다. 각 프로세스는 자체적인 프로그램(텍스트) 영역, 데이터 영역, 스택 영역을 가진다.
  • 프로그램 영역에는 기계 명령어가 저장된다. 이 명령어들은 실행 중에 변경되지 않으므로, 같은 실행 파일을 사용하는 여러 프로세스 간에 프로그램 영역을 공유하여 메모리를 절약할 수 있다.[133]
  • 시간과 메모리를 절약하기 위해, 커널은 디스크 드라이브에서 전체 실행 파일이 아닌 필요한 명령어 블록만 메모리로 로드할 수 있다.[132]
  • 커널은 프로그램이 사용하는 가상 주소를 실제 물리 주소로 변환하는 역할을 한다. 이 과정에서 필요한 데이터가 메모리에 없는 경우(페이지 폴트), 커널은 메모리 관리 장치(MMU)에 접근하여 디스크에서 데이터를 가져와 물리 메모리 영역을 채우고 주소 변환을 완료한다.[134][135]
  • 커널은 프로세스의 요청에 따라 동적으로 메모리()를 할당한다.[64] 프로세스가 메모리 사용을 마치면, 메모리 해제를 요청할 수 있다. 만약 프로세스가 사용한 메모리를 모두 해제하지 않고 종료되면, 커널은 해당 메모리를 회수하기 위해 가비지 컬렉션을 수행한다.
  • 커널은 각 프로세스가 자신의 메모리 영역에만 접근하고, 커널이나 다른 프로세스의 메모리 영역에는 접근하지 못하도록 보호한다.[132]
  • 파일 시스템 관리: 커널은 파일을 생성, 검색, 업데이트, 삭제하는 기능을 제공하며 파일 시스템을 관리한다.[132]
  • 장치 관리: 커널은 마우스, 키보드, 디스크 드라이브, 프린터 등 다양한 하드웨어 장치에 대한 표준화되고 단순화된 인터페이스를 제공한다.[132] 또한 여러 프로세스가 동시에 특정 장치를 사용하려고 할 때 접근을 중재하는 역할을 한다.
  • 네트워크 관리: 커널은 프로세스를 대신하여 네트워크 패킷을 주고받으며 네트워크 통신을 관리한다.[136] 특히, 목적지 시스템까지 효율적인 경로를 찾는 것이 중요한 기능 중 하나이다.
  • 시스템 호출 제공: 커널은 프로그래머가 운영 체제의 기능을 사용할 수 있도록 시스템 레벨 함수 인터페이스를 제공한다.[137]
  • 프로그래머는 파일 접근, 프로세스 생성, 시간 관리 등 복잡한 저수준 작업을 비교적 간단한 인터페이스를 통해 수행할 수 있다. 예를 들어, 파일 관련 시스템 호출은 내부적으로 파일 생성, 파일 디스크립터 관리, 파일 위치 탐색, 물리적 읽기/쓰기 등 복잡한 저수준 I/O 인터페이스를 호출한다.[138]
  • 프로세스 간 통신(IPC): 커널은 실행 중인 프로세스들이 서로 정보를 교환할 수 있는 통신 채널을 제공한다.[139] 대규모 소프트웨어 시스템은 종종 여러 개의 작은 프로세스로 나누어 설계되는데, 이 프로세스들은 신호 등을 통해 서로 통신할 수 있다.


초기의 운영 체제는 주로 어셈블리 언어로 작성되었지만, 현대의 운영 체제는 대부분 고급 프로그래밍 언어로 작성된다. 예를 들어 UNIXC로, macOS는 Objective-C로 작성되었으며, 애플은 Swift를 Objective-C의 대체 언어로 개발했다.

6. 3. 유틸리티 프로그램 (Utility Program)

유틸리티 프로그램은 컴퓨터 시스템 관리와 소프트웨어 실행을 돕기 위해 설계된 프로그램이다. 운영 체제는 디스크 드라이브, 메모리, 스피커, 프린터 등 하드웨어의 상태를 점검하기 위해 하드웨어 유틸리티 프로그램을 사용한다.[140] 또한, 유틸리티 프로그램은 복잡하게 흩어져 있는 파일들을 디스크에서 효율적으로 재배치하여 최적화하는 기능을 수행하기도 한다. 시스템 유틸리티 프로그램은 하드웨어 및 네트워크 성능을 지속적으로 감시하며, 설정된 기준치를 벗어나는 문제가 발생하면 사용자에게 알림을 보낸다.[141]

주요 유틸리티 프로그램의 종류는 다음과 같다.

  • 압축 프로그램: 데이터 파일을 압축하여 더 적은 디스크 공간을 차지하도록 만든다.[140] 압축된 파일은 네트워크를 통해 전송할 때 시간도 절약할 수 있다.[140]
  • 데이터 정렬 및 병합 프로그램: 대량의 데이터 세트를 특정 기준에 따라 정렬하거나 여러 데이터 세트를 하나로 합치는 작업을 수행한다.[141]
  • 컴퓨터 바이러스 탐지 프로그램: 컴퓨터 바이러스나 기타 악성 코드를 찾아내고 제거하는 역할을 한다.[141]

6. 4. 마이크로코드 프로그램 (Microcode Program)

NOT 게이트


NAND 게이트


NOR 게이트


AND 게이트


OR 게이트


마이크로코드 프로그램은 소프트웨어 기반 컴퓨터의 데이터 경로를 제어하는 가장 낮은 수준의 인터프리터이다.[142] 하드웨어 기술이 발전하면서 이러한 연산 기능 중 일부는 하드웨어 실행 회로로 옮겨가기도 했다.[142] 마이크로코드 명령어는 프로그래머가 컴퓨터의 실제 하드웨어인 디지털 논리 레벨을 더 쉽게 다룰 수 있도록 돕는다.[143] 디지털 논리 레벨은 컴퓨터 과학컴퓨터 공학의 경계선상에 있는 개념이다.[144]

디지털 논리 레벨의 기본 요소는 논리 게이트이다. 논리 게이트는 작은 트랜지스터로 만들어지며, 켜짐(ON) 또는 꺼짐(OFF)의 두 가지 신호 중 하나를 출력할 수 있다.[145] 기본적인 논리 게이트의 종류는 다음과 같다.

  • 하나의 트랜지스터는 NOT 게이트를 형성한다. 입력 신호를 반대로 바꾼다.
  • 두 개의 트랜지스터를 직렬로 연결하면 NAND 게이트가 형성된다. 두 입력이 모두 참(ON)일 때만 거짓(OFF)을 출력한다.
  • 두 개의 트랜지스터를 병렬로 연결하면 NOR 게이트가 형성된다. 두 입력이 모두 거짓(OFF)일 때만 참(ON)을 출력한다.
  • NOT 게이트를 NAND 게이트에 연결하면 AND 게이트가 형성된다. 두 입력이 모두 참(ON)일 때만 참(ON)을 출력한다.
  • NOT 게이트를 NOR 게이트에 연결하면 OR 게이트가 형성된다. 두 입력 중 하나라도 참(ON)이면 참(ON)을 출력한다.


이 다섯 가지 기본 게이트는 컴퓨터의 디지털 논리 기능을 구현하는 이진 대수의 기초를 이룬다.

마이크로코드 명령어는 프로그래머가 복잡한 이진 대수 대신 사용할 수 있는 일종의 니모닉 (기억하기 쉬운 약어)이다. 이 명령어들은 중앙 처리 장치 (CPU) 내의 제어 저장소에 저장된다.[146] 이러한 하드웨어 수준의 명령어들은 컴퓨터 내부의 데이터 경로를 통해 데이터를 이동시키는 역할을 한다.

마이크로 명령어의 실행 주기는 다음과 같은 단계로 이루어진다. 먼저, 마이크로 시퀀서가 마이크로 프로그램 카운터를 사용하여 주 기억 장치에서 다음 기계어 명령어를 가져온다 (Fetch).[147] 다음으로, 가져온 기계어 명령어를 해독 (Decode)하여 필요한 하드웨어 모듈의 출력 라인을 선택한다.[148] 마지막으로, 선택된 하드웨어 모듈의 게이트들을 사용하여 명령어를 실행 (Execute)한다.

ALU의 기호적 표현


산술 연산을 수행하는 명령어는 산술 논리 장치 (ALU)를 통해 처리된다.[149] ALU는 정수의 덧셈, 비트 이동(shift), 비교와 같은 기본적인 연산을 수행하는 회로를 포함하고 있다. CPU는 이러한 ALU의 기본 연산들을 조합하고 반복하여 복잡한 산술 연산을 수행한다.

마이크로코드 명령어는 CPU와 메모리 컨트롤러 사이의 데이터 이동도 제어한다. 메모리 컨트롤러와 관련된 마이크로코드 명령어는 주로 두 개의 프로세서 레지스터를 조작한다. 메모리 주소 레지스터 (MAR)는 메모리 각 셀의 주소에 접근하는 데 사용되고, 메모리 버퍼 레지스터 (MBR)는 각 셀의 내용을 읽거나 쓰는 데 사용된다.[150]

또한 마이크로코드 명령어는 CPU와 다양한 컴퓨터 버스 간의 데이터 전송을 관리한다. 예를 들어, 디스크 컨트롤러 버스는 하드 디스크 드라이브와의 데이터 읽기 및 쓰기를 담당한다. 데이터는 PCI 익스프레스 버스와 같은 통로를 통해 CPU와 다른 주변 장치들 사이를 오간다.[151]

참조

[1] 웹사이트 ISO/IEC 2382:2015 https://www.iso.org/[...] 2020-09-03
[2] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[3] 서적 Operating System Concepts, Fourth Edition Addison-Wesley
[4] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[5] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[6] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[7] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[8] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[9] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[10] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[11] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[12] 간행물 Charles Babbage's Analytical Engine, 1838 http://profs.scienze[...] 2015-10-30
[13] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[14] 간행물 Lovelace & Babbage and the creation of the 1843 'notes' 2003-10
[15] 서적 Discrete Mathematics and Its Applications https://archive.org/[...] McGraw-Hill, Inc.
[16] 서적 An Introduction to Formal Languages and Automata D. C. Heath and Company
[17] 서적 An Introduction to Formal Languages and Automata D. C. Heath and Company
[18] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[19] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[20] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[21] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[22] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[23] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[24] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company
[25] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[26] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[27] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[28] 서적 Operating System Concepts, Fourth Edition Addison-Wesley
[29] 웹사이트 Bill Pentz — A bit of Background: the Post-War March to VLSI https://www.digibarn[...] Digibarn Computer Museum 2008-08
[30] 서적 To the Digital Age: Research Labs, Start-up Companies, and the Rise of MOS https://books.google[...] Johns Hopkins University Press
[31] 웹사이트 Manufacturing of Silicon Materials for Microelectronics and Solar PV https://www.osti.gov[...] Sandia National Laboratories 2022-02-08
[32] 웹사이트 Fabricating ICs Making a base wafer https://www.britanni[...] Britannica 2022-02-08
[33] 웹사이트 Introduction to NMOS and PMOS Transistors https://anysilicon.c[...] Anysilicon 2021-11-04
[34] 웹사이트 microprocessor definition https://www.britanni[...] Britannica 2022-04-01
[35] 웹사이트 Chip Hall of Fame: Intel 4004 Microprocessor https://spectrum.iee[...] Institute of Electrical and Electronics Engineers 2018-07-02
[36] 웹사이트 360 Revolution https://www.computer[...] Father, Son & Co. 2022-02-05
[37] 웹사이트 Inside the world's long-lost first microcomputer https://www.cnet.com[...] c/net 2010-01-08
[38] 웹사이트 Bill Gates, Microsoft and the IBM Personal Computer https://books.google[...] InfoWorld 1982-08-23
[39] 서적 The C++ Programming Language, Fourth Edition Addison-Wesley
[40] 서적 The C++ Programming Language, Fourth Edition Addison-Wesley
[41] 서적 Principles of Information Systems, Sixth Edition Thomson
[42] 서적 An Introduction to Formal Languages and Automata D. C. Heath and Company
[43] 서적 Data Structures and Algorithm Analysis in C++ Benjamin/Cummings Publishing Company, Inc.
[44] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[45] 서적 Principles of Information Systems, Sixth Edition Thomson
[46] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[47] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[48] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[49] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[50] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[51] 서적 Principles of Information Systems, Sixth Edition Thomson
[52] 서적 Comparative Programming Languages, Second Edition Addison-Wesley
[53] 서적 The C++ Programming Language, Fourth Edition Addison-Wesley
[54] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[55] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[56] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[57] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[58] 웹사이트 Memory Layout of C Programs https://www.geeksfor[...] 2011-09-12
[59] 서적 The C Programming Language Second Edition Prentice Hall
[60] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[61] 서적 The Linux Programming Interface No Starch Press
[62] 서적 The Linux Programming Interface No Starch Press
[63] 서적 The C Programming Language Second Edition Prentice Hall
[64] 서적 The C Programming Language Second Edition Prentice Hall
[65] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[66] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[67] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[68] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[69] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[70] 서적 The C++ Programming Language, Fourth Edition Addison-Wesley
[71] 서적 The C++ Programming Language, Fourth Edition Addison-Wesley
[72] 서적 The C++ Programming Language, Fourth Edition Addison-Wesley
[73] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[74] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[75] 서적 Data Structures and Algorithm Analysis in C++ Benjamin/Cummings Publishing Company, Inc.
[76] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[77] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[78] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[79] 서적 The Art of Lisp Programming Springer Science & Business Media 2012-12-06
[80] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[81] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[82] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[83] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[84] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[85] 웹사이트 From LCF to HOL: a short history http://www.cl.cam.ac[...] 2021-10-30
[86] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[87] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[88] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[89] 간행물 The birth of Prolog http://alain.colmera[...] Association for Computing Machinery
[90] 문서 Kowalski, R., Dávila, J., Sartor, G. and Calejo, M., 2023. Logical English for law and education. In Prolog: The Next 50 Years (pp. 287-299). Cham: Springer Nature Switzerland.
[91] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[92] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[93] 서적 Software Engineering Aksen Associates Incorporated Publishers
[94] 서적 Data Structures and Algorithm Analysis in C++ Benjamin/Cummings Publishing Company, Inc.
[95] 서적 Software Engineering Aksen Associates Incorporated Publishers
[96] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[97] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[98] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[99] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[100] 서적 Discrete Mathematics and Its Applications https://archive.org/[...] McGraw-Hill, Inc.
[101] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[102] 서적 Discrete Mathematics and Its Applications https://archive.org/[...] McGraw-Hill, Inc.
[103] 서적 Discrete Mathematics and Its Applications https://archive.org/[...] McGraw-Hill, Inc.
[104] 서적 Discrete Mathematics and Its Applications https://archive.org/[...] McGraw-Hill, Inc.
[105] 서적 Comparative Programming Languages, Third Edition Addison-Wesley
[106] 서적 Software Engineering Aksen Associates Incorporated Publishers
[107] 서적 Principles of Information Systems, Sixth Edition Thomson
[108] 서적 Principles of Information Systems, Sixth Edition Thomson
[109] 서적 Principles of Information Systems, Sixth Edition Thomson
[110] 서적 Principles of Information Systems, Sixth Edition Thomson
[111] 서적 Software Engineering Aksen Associates Incorporated Publishers
[112] 서적 Principles of Information Systems, Sixth Edition Thomson
[113] 서적 Software Engineering Aksen Associates Incorporated Publishers
[114] 서적 Software Engineering Aksen Associates Incorporated Publishers
[115] 서적 Software Engineering Aksen Associates Incorporated Publishers
[116] 서적 Software Engineering Aksen Associates Incorporated Publishers
[117] 서적 Software Engineering Aksen Associates Incorporated Publishers
[118] 서적 Software Engineering Aksen Associates Incorporated Publishers
[119] 서적 Software Engineering Aksen Associates Incorporated Publishers
[120] 서적 Software Engineering Aksen Associates Incorporated Publishers
[121] 서적 Software Engineering Aksen Associates Incorporated Publishers
[122] 서적 Operating System Concepts, Fourth Edition Addison-Wesley
[123] 서적 Principles of Information Systems, Sixth Edition Thomson
[124] 서적 Principles of Information Systems, Sixth Edition Thomson
[125] 서적 Principles of Information Systems, Sixth Edition Thomson
[126] 서적 Principles of Information Systems, Sixth Edition Thomson
[127] 서적 Principles of Information Systems, Sixth Edition Thomson
[128] 서적 Principles of Information Systems, Sixth Edition Thomson
[129] 서적 Principles of Information Systems, Sixth Edition Thomson
[130] 서적 Structured Computer Organization, Third Edition https://archive.org/[...] Prentice Hall
[131] 서적 The Linux Programming Interface No Starch Press
[132] 서적 The Linux Programming Interface No Starch Press
[133] 서적 The Design of the UNIX Operating System Prentice-Hall, Inc.
[134] 서적 Structured Computer Organization, Sixth Edition Pearson
[135] 서적 Embedded Systems Architecture Packt
[136] 서적 The Linux Programming Interface No Starch Press
[137] 서적 The Unix Programming Environment Prentice Hall
[138] 서적 The Linux Programming Interface No Starch Press
[139] 서적 Unix System Programming Addison-Wesley Publishing Company
[140] 서적 Principles of Information Systems, Sixth Edition Thomson
[141] 서적 Principles of Information Systems, Sixth Edition Thomson
[142] 서적 Structured Computer Organization, Sixth Edition Pearson
[143] 서적 Structured Computer Organization, Sixth Edition Pearson
[144] 서적 Structured Computer Organization, Sixth Edition Pearson
[145] 서적 Structured Computer Organization, Sixth Edition Pearson
[146] 서적 Structured Computer Organization, Sixth Edition Pearson
[147] 서적 Structured Computer Organization, Sixth Edition Pearson
[148] 서적 Structured Computer Organization, Sixth Edition Pearson
[149] 서적 Structured Computer Organization, Sixth Edition Pearson
[150] 서적 Structured Computer Organization, Sixth Edition Pearson
[151] 서적 Structured Computer Organization, Sixth Edition Pearson
[152] 서적 Principles of Information Systems, Sixth Edition Thomson Learning, Inc. 2003-01-01
[153] 서적 Operating System Concepts, Fourth Edition Addison-Wesley 1994-01-01
[154] 문서 컴퓨ティング
[155] 문서 ENIAC는 운용 시작 후에도 개수가 추가되고 있기 때문에, 상세한 역사를 검토하는 경우는 그 일에 주의가 필요하다.
[156] 간행물 「일본의 소프트웨어의 초창기」(『정보처리』제24권 제3호(1983년3월)) http://id.nii.ac.jp/[...]
[157] 문서 몇몇 컨셉의 실증을 목적으로 하고 있던 기계때문에 실용적이지는 않았지만, [[Manchester Small-Scale Experimental Machine]]이라는 선행례가 있다.
[158] 문서 「お次第書き」라고도 한다. 국어학자[[미즈타니 시즈오]]에 의거한다.
[159] 서적 Advanced Unix Programming, Second Edition Addison-Wesley
[160] 웹인용 Structure and Interpretation of Computer Programs https://mitpress.mit[...] 2018-03-27
[161] 서적 ENIAC – The Triumphs and Tragedies of the World's First Computer https://archive.org/[...] Walker and Company



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com