공통기초 프로그래밍 개념 잡기

4. 프로그램 언어 개요


이번 강좌에서는 프로그래밍 언어를 본격적으로 배우기 전에 필요한 기본적인 내용들을 배우게 됩니다. 특정언어에 대한 구체적인 문법이 아닌 개념적 관점에서 어떤 프로그램 언어를 사용하더라도 공통적으로 필요한 용어개념들을 정리하게 됩니다.

이 강의를 통해 프로그램 코드구성요소와 각각의 역할사용법 등에 대해 배우게 되고 실제 프로그램언어 학습에 기초를 다질수 있습니다.


01: 컴파일러와 개발도구

1) 컴파일러(Compiler)

프로그래밍 언어사람이해할 수 있는 문법으로 구성되어 있습니다. 따라서 프로그램의 소스 코드를 컴퓨터가 이해할 수 있는 형태로 변환해야 하는데 이것을 컴파일(Compile) 이라고 하고 컴파일러(Compiler)가 그 일을 수행합니다.

예를 들어 C언어로 프로그램을 개발한다면 C컴파일러가 필요한 것이고 자바언어로 개발한다면 자바 컴파일러가 필요한 것입니다.

크로스 컴파일(Cross Compile)

컴파일된 결과물은 특정 하드웨어운영체제에서 실행 가능한 형태가 되어야 하는데 기본적으로는 컴파일을 수행하는 컴퓨터와 동일한 환경에서 실행 될 수 있는 결과물이 생성 됩니다.

만일 컴파일 하는 프로그램 소스가 다른 환경에서 실행되는 것이라면 컴파일러 옵션을 통해 크로스 컴파일(Cross Compile)을 해야 합니다. 이 경우 컴파일된 결과물은 현재 컴퓨터에서는 실행되지 않습니다.

예를 들어 윈도우에서 라즈베리파이와 같은 플랫폼에서 동작하는 프로그램을 개발하거나 스마트폰용 프로그램을 개발한다고 하는 경우가 이에 해당 됩니다.

자바 언어의 경우 가상머신(Virtual Machine)을 사용하기 때문에 크로스 컴파일이 필요 없습니다. 컴파일된 결과물은 특정 하드웨어가 아닌 가상머신에서 해석되는 바이트코드(Bytecode) 입니다.

인터프리터(Interpreter)

프로그래밍 언어의 소스 코드컴파일 과정 없이 바로 실행하는 환경을 말합니다. 일반적으로 컴파일을 통한 실행이 인터프리터에 의한 실행보다 빠르게 실행됩니다. 그러나 소스 프로그램의 크기가 매우 크다면 컴파일 과정에 상당한 시간이 소요될 수 있는 반면 인터프리터는 즉시 실행이 가능하다는 장점이 있습니다. 특히 소스코드의 빈번한 수정이 필요한 프로그램의 경우 소스 수정 후 바로 실행이 가능한 인터프리터가 유리할 수 있습니다.

대표적으로 Python 이 유명하며 JavaScript, Ruby, Perl 등의 스크립트 언어들도 인터프리터 기반 언어 입니다.

2) 개발도구

개발도구는 프로그램의 소스코드 작성컴파일을 도와주는 도구 입니다. 기본적으로 컴파일러는 CLI를 통해 실행하는 구조이며 규모가 큰 프로그램의 개발시 복잡한 컴파일 과정을 자동화 하기 위해 빌드도구(Build Tool)을 사용 합니다.

대표적인 빌드 도구에는 전통적으로 make 가 있으며 최근의 자바 개발에는 maven, gradle 등이 널리 사용되고 있습니다.


기본적인 개발은 이러한 CLI환경만으로도 충분하지만 소스코드와 연관된 라이브러리 관리, 소스코드 편집기의 다양한 기능(코드 하이라이팅, 자동완성, API매뉴얼,리팩토링), 디버깅 도구, 기타 githubCI(Continuous Integration) 시스템과의 연계등을 통합해서 제공하는 통합개발환경(IDE: Integrated Development Environment) 이 필요합니다.

대표적인 IDE에는 Visual Studio, Eclipse, IntelliJ 등이 유명하며 경량의 웹 개발이나 파이썬 개발등에 많이 사용되는 Visual Studio Code, Atom 등도 단순 편집기라기 보다는 IDE에 가깝게 발전하고 있습니다.

개발언어와 프로젝트의 규모 그리고 성격에 따라 개발도구는 달라질 수 있습니다. IDE는 많은 기능을 포함하고 있기 때문에 경우에 따라 많은 용량컴퓨팅파워를 요구 하므로 사용 목적에 따라 효과적인 선택이 필요 합니다.

가볍게 C/C++ 로 프로그램을 개발한다면 Visual Studio Community, Visual Studio Code 나 Eclipse 가 좋고 대규모 C/C++ 프로젝트나 본격적으로 C# 기반의 윈도우 프로그램을 개발한다면 Visual Sudio를 선택하면 됩니다.

자바의 경우 Eclipse 혹은 IntelliJ 를 선택할 수 있으며 웹 프론트엔드 개발의 경우 Visual Studio Code 나 Atom 등을 고려할 수 있습니다.

일반적으로 IDE는 많은 기능을 제공하고 있으므로 제대로 사용하기 위해서는 IDE 자체에 대한 상당한 학습이 요구된다는 점을 잊지 마세요..

02: 변수와 자료형

여기서 부터 나오는 예제들은 특정언어의 예가 아니며 개념이해를 위한 표현 이므로 실제 정확한 문법과 사용법은 해당 언어를 학습하며 배워야 합니다.

변수(Variable)

변수는 말 그대로 변하는 수를 의미 합니다. 프로그램에 필요한 데이터일시적으로 보관하는 용도로 이해 할 수 있습니다.

예를 들어 사람이 2 + 8 = 10 이라는 계산을 할때 2 와 8이라는 값을 일시적으로 기억해야 더하기 연산을 수행하는 것 처럼 컴퓨터 프로그램에서는 연산에 필요한 데이터연산결과를 어디엔가 임시로 저장해야 하는 개념 입니다.

다음은 간단한 변수 사용의 예 입니다. ";"은 프로그램 구문의 끝이라는 의미로 많은 프로그램언어들이 사용합니다만 최신의 언어들은 굳이 입력하지 않아도 됩니다.

num1 = 2;
num2 = 8.2;
result = num1 + num2;

과거의 프로그램언어들은 컴퓨터 친화적으로 변수에 들어가는 값들은 기본적으로 숫자 데이터 였습니다. 그러나 연산 프로그램이 아니라 회사나 일반인이 사용하는 프로그램들에는 문자열이 더 많이 사용되고 객체지향프로그래밍이 확산되면서 변수에 들어가는 데이터가 숫자가 아닌 객체형으로 변화하고 있습니다.

변수에 있어 중요한 개념중 하나는 메모리의 할당 입니다. 즉 컴퓨터 구성요소중 메모리가 일시적인 저장을 담당하기 때문에 변수사용해 데이터를 저장한다는 것은 바로 메모리사용하는것으로 변수에 어떤 데이터를 저장하느냐에 따라 해당 변수에 들어갈 데이터의 크기를 지정해 주어야 하는 것입니다.

자료형(Data Type)

자료형은 변수에 들어가는 데이터의 유형구분해 놓은 것으로 자료형에 따라 변수에 할당되는 메모리 크기가 달라지게 됩니다.

따라서 앞의 변수 선언 예는 다음과 같이 구체적인 자료형을 명시하는 형태로 작성되어야 합니다.

int num1 = 2;
double num2 = 8.2;
double result = num1 + num2;

프로그램 언어에 따라 자료형의 명칭과 크기에는 다소 차이가 있지만 유형은 거의 비슷합니다.

데이터 유형 사용 예 자료형 예시
정수형 10, 123, 1024 int, long, __int64
실수형 10.5. 123.95 float, double, long double
진위형 true, false bool, boolean
문자형 ‘A’, 65 char, unsigned char
문자열 “Hello”, “50” String, char *


문자형의 경우 기본적으로 정수형에 준합니다. 컴퓨터는 문자를 처리할 수 없기 때문에 숫자로 구성된 ASCII 코드 테이블이라는 것을 만들어 테이블에 정의된 숫자 위치의 문자를 출력하는 형식 입니다. 알파벳 A의 경우 65번이 되며 프로그램에서는 출력시 숫자 혹은 문자를 선택할 수 있습니다. C언어 계열에서는 기본적으로 1바이트 크기 이며 자바의 경우 유니코드를 기본으로 하기 때문에 2바이트로 되어 있습니다. 참고로 한글은 UTF-8 이라는 유니코드 체계를 사용하고 있어 2바이트가 한글처리에는 유리 합니다.

문자열의 경우는 조금 복잡한데 자바String 이라는 타입을 제공해 문자열 사용이 쉬운 반면 C언어는 연속된 문자의 형태로 처리해서 포인터 라는 것을 사용해야 합니다. 포인터는 처음 프로그램을 배우는 사람들에게 가장 어려운 개념으로 알려져 있습니다.

여기서는 기본적으로는 변수의 메모리 위치에 실제 값이 저장되는 형태가 아니라 별도의 공간에 할당된 메모리 위치를 가리키는(포인터)정보를 저장한 변수 정도로 이해하도록 합니다.

최신의 프로그램언어들은 사람 친화적으로 자료형이나 크기 혹은 메모리 할당/반환과 같은 작업들을 개발자가 계산하거나 직접 처리하지 않는 쪽으로 발전하고 있습니다. 또한 타입추론(Type Inference)기능이 도입되어 자료형을 선언하지 않고 원하는 값을 사용하면 알아서 해당 타입이 결정되기도 합니다.

03: 조건문

조건문은 프로그램의 로직(logic) 구현에 필요한 구문으로 특정 조건에 따라 수행문분기할 수 있습니다.

예를 들어 아이디와 비밀번호를 넣고 로그인하는 경우 입력한 값과 DB에 저장되어 있는 값을 비교해 둘다 맞으면 로그인 성공 그렇지 않으면 실패 메시지를 출력하는 경우등이 조건문의 사용 예 입니다.

이 외에도 게임 프로그램에서 미사일 발사 버튼을 누르는 경우 남아있는 미사일이 0 이라면 발사가 되지 않거나 파워가 10 이하인 경우 서서히 추락하게 한다거나 하는 로직 구현에도 조건문이 사용됩니다.

즉, 프로그램에서 뭔가의 입력을 받아 입력된 값에 따라 동작을 다르게 하거나 특정 조건에 따라 처리되도록 하는 경우 조건문을 사용한다고 볼 수 있습니다.

대표적인 조건문은 if 이며 다양한 조건 구성을 위해 if ~ else if 등이 사용 됩니다. 또다른 조건문으로 switch 문을 들 수 있으며 switch 는 조건값에 따라 수행블럭을 구분해서 정의할 수 있습니다. 이 외 3항연산과 같이 참/거짓에 따른 간단한 조건연산을 수행할 수 있는 구문도 있습니다.

// if, else if
if(power < 10) {
    slowdown();
}
else if(power > 100) {
    gofaster();
}

// switch
switch(input) {
    case 1: 
        ... 
        break;
    case 2: 
        ... 
        break;
    case 3:
        ... 
        break;
    default: ...
}

// 3항연산
String result = (login)? "로그인성공":"로그인실패";

04: 반복문

특정 조건에 따라 동일한 작업반복해서 수행하기 위한 구문 입니다. 조건문과 함께 프로그램의 로직을 설계하는데 꼭 필요한 구문 입니다. 특정 문제 해결을 위해 처리 로직을 만들 수 있는데 이를 알고리즘이라 합니다. 그리고 알고리즘 구현에 조건문과 반복문이 주요 역할을 수행 합니다.

대표적인 반복문은 for, while, do ~ while 등이 있습니다.

// 0 ~ 9 까지 즉 10회 반복
for(int i=0;i<10;i++) {
    ...
}

// members 집합형 데이터 크기만큼 반복하면서 Member 타입 데이터를 가지고 옴.
for(Member m : membders) {
    ...
}

// power > 10 보다 큰 경우에는 go() 함수를 호출해 동작시키고 power를 1감소
while(power > 10) {
    go();
    power--;
}


05: 함수

함수특정 기능을 수행하도록 구현된 모듈화된 코드 블럭으로 동일한 기능이 필요할때 어느곳에서나 호출해서 사용할 수 있습니다.

객체지향 프로그램언어 에서는 함수(function)를 메서드(method)라고 부르기도 합니다.

함수의 구조는 리턴값 함수명(인자) 형식 입니다.

다음은 함수 사용의 예 입니다.

int calc(int n1, int n2) {
    return n1+n2;
}

print(calc(10,20));
print(calc(30,50));

06: 자료구조

프로그램을 작성하는 과정에는 여러 데이터가 필요 합니다. 예를들어 100명 학생의 성적을 처리한다고 할때 각각의 성적 값을 변수에 할당한다면 100개의 변수가 필요합니다. 이런경우 배열을 이용하면 하나의 변수명으로 100개의 데이터를 처리할 수 있게 됩니다.

자료구조는 컴퓨터 프로그램에서 데이터를 처리하기 위해 만든 구조로 Array, List, Map이 대표적입니다. 이 외에 프로그램 언어에 따라 Tuple, Dictionary 등을 사용하기도 합니다.

Array

가장 대표적인 자료구조 입니다. 배열 이라고 하며 데이터를 순차적으로 저장해 0부터 시작하는 인덱스를 통해 접근할 수 있습니다.

int scores[] = {95,100,87,91};

for(int i=0;i<scores.length;i++) {
    print(scores[i]);
}

List

리스트라고 하며 순차적인 자료구조를 제공 합니다. 객체지향 프로그램언어에는 보통 List 자료구조가 기본적으로 제공되며 그렇지 않을 경우 직접 자료구조를 구현하거나 구현된 라이브러리를 사용해야 합니다.

데이터 접근을 위해 인덱스를 사용해야 하는 점은 배열과 같지만 배열의 모든 문제점해결하고 있습니다.

Linked List는 현재 데이터에 다음 혹은 이전 데이터를 읽을 수 있는 정보를 추가한 것으로 객체지향 프로그램언어 에서는 보통 Iterator 객체가 있어 이를 사용하면 이전, 다음 데이터를 쉽게 읽어 올 수 있습니다.

List scores = new Scores();
scores.add(95);
scores.add(100);
...

print(scores.indexOf(95)); // 95 값이 처음 나오는 위치를 알려줌.
print(scores.contains(95)); // 95 값이 리스트에 포함되어 있는지 알려줌.

Map

이라고 하며 데이터를 Key:Value(키:값)의 쌍으로 저장하는 방식입니다. 실제 데이터가 저장되는 형태는 자료구조의 내부구조에 따르며 사용하는 쪽에서는 내부구조에 대해 신경쓸 필요가 없는 형태 입니다.

Map scores = new Map();
scores.put("홍길동",96);
scores.put("김사랑",100);
..
print(scores.get("홍길동"));

Tuple

튜플이라고 하며 보통 List 와 비슷하지만 한번 생성되면 값을 변경할 수 없는(Immutable) 자료구조 입니다.

Dictionary

딕셔너리라고 하며 프로그래밍 언어에 따라 Map 대신 사용되기도 합니다. Map자바, C++ 에서 사용되고 DictionaryPython, C#, Swift 등에서 사용됩니다.

이 외에 Associative array 도 비슷한 개념으로 JavaScript, PHP 등에서 사용 되고 있습니다.


07: Lamda

람다라고 읽으며 λ으로 표기합니다. 원래는 수학기호로 대각화 행렬, 고윳값, 라그랑주 승수 등에서 사용됩니다.

최신의 프로그램언어에서 사용되는 람다식 혹은 람다함수는 함수형 언어(funtional programming)의 특징에서 나온것으로 익명 함수(Anonymous Function)를 지칭하는 용어 입니다. 전통적인 프로그램 구문과는 형식이 다르며 내부적인 동작원리나 구조 까지 이해하려면 객체지향 개념에서 부터 중급 수준의 프로그램언어 활용 능력이 요구되므로 여기서는 개념과 특징 정도만 정리 합니다.

기본적으로 함수의 구조로 되어 있으며 보통 ->와 같이 화살표 형태의 기호를 이용해 매개변수를 함수 바디로 전달하는 형태를 취합니다.

( parameters ) -> expression body
( parameters ) -> { expression body }
() -> { expression body }
() -> expression body

장점

단점

최신언어 지원현황

사용 예

다음 예는 1,2,3 세개의 값을 가지고 있는 배열의 각 원소값에 자기자신을 곱한 값을 출력하는 코드 입니다. 람다를 사용하지 않을 경우 배열을 만들고 for 문의 이용해 처리해야 하는 과정을 거쳐야 합니다.

Arrays.asList(1,2,3).stream()
	.map(i -> i*i)
	.forEach(System.out::println);

// 실행결과 -> 1 4 9

08: 라이브러리(Library)

라이브러리는 프로그램 개발에 필요한 중요한 기능들을 모아놓은 집합 입니다. 공통적으로 사용할 수 있도록 모듈화 되어 있으며 실제 구현의 형식은 함수의 형태를 취하고 있습니다.

모든 프로그램 언어는 기준이 되는 표준 규격이 버전에 따라 존재 하고 각 표준에는 문법적인 요소뿐 아니라 기본적으로 제공하는 라이브러리에도 차이가 있습니다.

일반적으로 프로그램 언어에서는 필수적인 라이브러리만 제공 하고 그 외 다양한 라이브러리는 서드파티(3rd party) 라이브러리 라고 불리우며 개인 혹은 기업/기관 등에서 만들어 무료 혹은 유료로 배포하게 됩니다.

개발자들은 자신에게 필요한 기능이 무엇인지 알아야 하고 어떤 라이브러리가 해당 기능을 제공해 주는지 찾을 수 있어야 합니다.

github 는 이러한 오픈소스라이브러리(Open Source Library)의 천국으로 많은 라이브러리가 공개되어 있으므로 관심을 가지고 살펴보길 권합니다.

라이브러리를 사용하는 절차는 프로그램언어마다 차이가 있지만 일반적으로는 다음과 같습니다.

최근의 개발은 많은 오픈소스 라이브러리를 포함하는 것이 기본이므로 개발자가 일일이 라이브러리를 찾아 다운로드 하거나 복사하기 어려운 경우가 많습니다. 앞쪽에서 설명했던 빌드도구들은 컴파일과 관련된 기능뿐만 아니라 프로젝트에 필요한 라이브러리를 자동으로 다운로드 하고 연관된 라이브러리 및 버전관리도 함께 제공하기 때문에 이들을 활용해야 합니다.


09: Open API

APIApplication Programming Interface 의 약어로 응용 프로그램에서 사용할 수 있는 연결통로 라는 의미로 해석할 수 있습니다.

예를 들어 A 라는 프로그램의 코드가 B 라는 프로그램에 구현된 특정 기능을 사용할 수 있도록 한다고 할때 B라는 프로그램 코드에서 해당 기능을 외부에서 사용할 수 있도록 지정하고 함수의 형태로 구현해 두면 되며 이때 해당 함수는 외부에서 사용할 수 있는 인터페이스가 되는 것입니다.

즉, API는 앞에서 설명한 라이브러리의 사용규격 으로 이해할 수 있으며 Open API는 공개된 API 혹은 라이브러리로 생각할 수 있습니다.

그러나 최근에 이야기 하는 Open API는 전통적인 프로그램 라이브러리의 인터페이스가 아니라 인터넷을 통해 사용할 수 있는 공개 라이브러리라는 의미로 사용됩니다. 이를 REST 혹은 RESTful 웹서비스 라고도 합니다.

REST(Representational State Transfer)

REST는 현재 HTTPJSON을 함께 사용하여 OPEN API를 구현하는 형태로 많이 사용되고 있으며 대부분의 OPEN API는 REST 아키텍처를 기반으로 만들어져 있습니다. 일반적으로 REST 원칙을 따르는 시스템을 RESTful 이라고 하며 웹 기반으로 구현된 서비스 이므로 RESTful 웹 서비스라고 이야기 합니다.

쉽게 설명하면 WWW 에 사용된 통신 규격인 HTTP를 이용해 프로그램 구현언어와 상관 없이 공통적으로 이용할 수 있는 라이브러리 서비스를 개발하고 이용하는 방식이라고 설명 할 수 있습니다.

예를들어 사람의 얼굴사진을 제공하면 사진에서 사람의 감정상태를 추출해주는 라이브러리가 있다고 할때,

기존방식

해당 라이브러리를 C버전, Java버전 등등 만들어 배포해야 하고 프로그램을 구현하는 언어에서 해당 라이브러리를 다운로드해 프로젝트에 포함시켜 프로그램을 만드는 방식.

REST

프로그램언어의 종류에 상관없이 HTTP 통신 프로그램을 작성하는 형태로 서버에 원하는 기능을 요청하면서 필요한 데이터를 제공하는 형식.

제약 사항

장점

REST와 관련한 보다 자세한 설명은 짧굵배 블로그를 참고하기 바랍니다.