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매뉴얼
,리팩토링
), 디버깅 도구
, 기타 github
나 CI(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 등을 고려할 수 있습니다.
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언어
는 연속된 문자의 형태로 처리해서 포인터
라는 것을 사용해야 합니다. 포인터는 처음 프로그램을 배우는 사람들에게 가장 어려운 개념으로 알려져 있습니다.
여기서는 기본적으로는 변수의 메모리 위치
에 실제 값이 저장되는 형태가 아니라 별도의 공간에 할당된 메모리 위치를 가리키는(포인터)정보
를 저장한 변수 정도로 이해하도록 합니다.
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--;
}
- 대부분의 언어에서 for 문은 시작값과 종료값 증감식을 포함.
- 최근에는 집합형 데이터를 처리하기 위한
:(in)
형식의 구문도 많이 사용. - for 문 속에 또다른 for 문을 넣을 수 있으나 지나친 충첩은 권장되지 않음.
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(키:값)
의 쌍으로 저장하는 방식입니다. 실제 데이터가 저장되는 형태는 자료구조의 내부구조
에 따르며 사용하는 쪽에서는 내부구조에 대해 신경쓸 필요가 없는 형태 입니다.
- 데이터를 저장할 때 해당 데이터를 찾기 위한
Key
를 부여. Key
값을 알면 언제든 쉽게 데이터를 찾을 수 있음.객체지향 프로그램언어
의 경우 Value 에객체형
이 들어갈 수 있어 복잡한 데이터 처리가 가능.
Map scores = new Map();
scores.put("홍길동",96);
scores.put("김사랑",100);
..
print(scores.get("홍길동"));
Tuple
튜플
이라고 하며 보통 List 와 비슷하지만 한번 생성되면 값을 변경할 수 없는(Immutable
) 자료구조 입니다.
- 기본적으로는 리스트와 같이 순차적으로 데이터 처리.
- 경우에 따라 튜플에 들어가는 데이터에 이름을 붙여 사용할 수 있음.
- 튜플의 데이터는 변경할 수 없음.
t0 = (10,20,50); t1 = (X: 3, Y: 0); t2 = (X: 5, Y: 10); ... print(t0.Item1,t1.X, t2.Y);
Dictionary
딕셔너리
라고 하며 프로그래밍 언어에 따라 Map
대신 사용되기도 합니다.
Map
은 자바, C++
에서 사용되고 Dictionary
는 Python, C#, Swift
등에서 사용됩니다.
이 외에 Associative array
도 비슷한 개념으로 JavaScript, PHP
등에서 사용 되고 있습니다.
07: Lamda
람다
라고 읽으며 λ
으로 표기합니다. 원래는 수학기호
로 대각화 행렬, 고윳값, 라그랑주 승수 등에서 사용됩니다.
최신의 프로그램언어
에서 사용되는 람다식 혹은 람다함수는 함수형 언어
(funtional programming)의 특징에서 나온것으로 익명 함수(Anonymous Function)
를 지칭하는 용어 입니다. 전통적인 프로그램 구문과는 형식이 다르며 내부적인 동작원리나 구조 까지 이해하려면 객체지향 개념에서 부터 중급 수준의 프로그램언어 활용 능력이 요구되므로 여기서는 개념과 특징 정도만 정리 합니다.
기본적으로 함수의 구조로 되어 있으며 보통 ->
와 같이 화살표 형태의 기호를 이용해 매개변수를 함수 바디로 전달하는 형태를 취합니다.
( parameters ) -> expression body
( parameters ) -> { expression body }
() -> { expression body }
() -> expression body
장점
- 효율적인 람다 함수의 사용을 통하여 불필요한 루프문의 삭제가 가능하며, 함수의 재활용이 용이함.
- 필요한 정보만을 사용하는 방식을 통한 성능 향상.
- 일반적으로 다중 cpu를 활용하는 형태로 구현되어 병렬처리에 유리.
단점
- 이론상 단순하게 모든 원소를 전부 순회하는 경우 람다식이 조금 느릴 수 있음.
- 디버깅시 함수 콜스택 추적이 다소 어려움.
- 지나치게 남발하면 코드가 이해하기 어려워짐.
최신언어 지원현황
- 최신지원언어: Kotlin, Swift, JavaScript(ES6)
- C, Fortran, Pascal: 지원 안함
- Java: JDK8 이상
- C++: 버전 11 이상(현재17)
- .Net Framework(C#): 3.5 이상
사용 예
다음 예는 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)의 천국으로 많은 라이브러리가 공개되어 있으므로 관심을 가지고 살펴보길 권합니다.
라이브러리를 사용하는 절차는 프로그램언어마다 차이가 있지만 일반적으로는 다음과 같습니다.
- 필요한 라이브러리를 검색하고 다운로드 한다.
- 개발 프로젝트에서 해당 라이브러리를 사용 할 수 있도록 경로를 설정하거나 프로젝트 폴더 안으로 복사한다.
- 소스코드에서 해당 라이브러리 사용을 위해 import, include 등의 구문을 사용해 명시 한다.
- 코드 작성시 원하는 기능을 제공하는 라이브러리 모듈의 특정 함수 등을 호출해 사용한다.
최근의 개발은 많은 오픈소스 라이브러리
를 포함하는 것이 기본이므로 개발자가 일일이 라이브러리를 찾아 다운로드 하거나 복사하기 어려운 경우가 많습니다. 앞쪽에서 설명했던 빌드도구
들은 컴파일과 관련된 기능뿐만 아니라 프로젝트에 필요한 라이브러리를 자동으로 다운로드 하고 연관된 라이브러리 및 버전관리도 함께 제공하기 때문에 이들을 활용해야 합니다.
09: Open API
API
는 Application Programming Interface
의 약어로 응용 프로그램에서 사용할 수 있는 연결통로
라는 의미로 해석할 수 있습니다.
예를 들어 A 라는 프로그램의 코드가 B 라는 프로그램에 구현된 특정 기능을 사용할 수 있도록 한다고 할때 B라는 프로그램 코드에서 해당 기능을 외부에서 사용할 수 있도록 지정하고 함수의 형태로 구현해 두면 되며 이때 해당 함수는 외부에서 사용할 수 있는 인터페이스가 되는 것입니다.
즉, API는 앞에서 설명한 라이브러리의 사용규격 으로 이해할 수 있으며 Open API는 공개된 API 혹은 라이브러리로 생각할 수 있습니다.
그러나 최근
에 이야기 하는 Open API
는 전통적인 프로그램 라이브러리의 인터페이스가 아니라 인터넷을 통해 사용할 수 있는 공개 라이브러리라는 의미로 사용됩니다. 이를 REST
혹은 RESTful
웹서비스 라고도 합니다.
REST(Representational State Transfer)
REST는 현재 HTTP
와 JSON
을 함께 사용하여 OPEN API
를 구현하는 형태로 많이 사용되고 있으며 대부분의 OPEN API는 REST 아키텍처를 기반으로 만들어져 있습니다. 일반적으로 REST 원칙을 따르는 시스템을 RESTful 이라고 하며 웹 기반으로 구현된 서비스 이므로 RESTful 웹 서비스라고 이야기 합니다.
쉽게 설명하면 WWW
에 사용된 통신 규격인 HTTP
를 이용해 프로그램 구현언어와 상관 없이 공통적으로 이용할 수 있는 라이브러리 서비스를 개발하고 이용하는 방식이라고 설명 할 수 있습니다.
예를들어 사람의 얼굴사진을 제공하면 사진에서 사람의 감정상태를 추출해주는 라이브러리가 있다고 할때,
기존방식
해당 라이브러리를 C버전, Java버전 등등 만들어 배포해야 하고 프로그램을 구현하는 언어에서 해당 라이브러리를 다운로드해 프로젝트에 포함시켜 프로그램을 만드는 방식.
REST
프로그램언어의 종류에 상관없이 HTTP 통신 프로그램을 작성하는 형태로 서버에 원하는 기능을 요청하면서 필요한 데이터를 제공하는 형식.
제약 사항
- 반드시 인터넷에 연결되어 있어야 함.
- 주고받는 데이터가 큰 경우에는 실시간 서비스가 어려움.
장점
- 라이브러리를 다운로드 하거나 관리할 필요가 없음.
- WWW를 이용하므로 보안, 성능 문제등의 해결이 쉬움.
- 라이브러리 사용 통제가 쉬우며 이용에 따른 과금도 가능.
REST와 관련한 보다 자세한 설명은 짧굵배 블로그를 참고하기 바랍니다.