2017년 11월 17일 금요일

초안... 인데 꽤 반응 좋았떤

by HAJUNHO Aug 14. 2016
Chapter 01. 프로그래밍이 뭐야?

프로그래밍 개념 잡기


‘코딩이 뭐야? 포인터는 뭐고, 연산자는 뭐야?’

처음 프로그래밍을 접하시는 분들은 생소한 용어와 어려운 개념 때문에 첫 단계에서 좌절하시는 경우도 많습니다. 컴퓨터에 익숙하지 않으신 분들은 책에서 시키는 대로 힘들게 IDE(Integrated Development Environment) 프로그램을 깔아서 ‘Hello World’를 출력한 이후 프로그래밍을 접거나 아예 그 전에 포기하시는 분들도 많습니다. 모든 공부가 그렇듯이, 프로그래밍도 쉽게 하기 위해서는 개념을 잡고 능숙해지게 연습을 해야 합니다. 따라서 프로그래밍을 배우고자 하는 우리가 해야 될 첫 번째 일은 바로 프로그래밍에 대한 개념을 잡는 것입니다.

비(非) 전공자의 “프로그래밍이 뭡니까?” 라는 물음에 필자는 “프로그래밍은 책 만들기입니다.” 라고 답을 합니다. 
사람은 의사소통을 말과 글, 즉 언어로 합니다. 사람이 컴퓨터에게 명령을 내릴 때에도 마찬가지로 언어가 필요한데, 이 때 쓰이는 언어가 JAVA, C, C++ 같은 프로그래밍 언어입니다.

글은 문장으로 이루어져 있고, 문장은 단어로 이루어져 있습니다. 그리고 단어는 알파벳이나 한글 같은 글자들의 조합으로 만들어집니다. 단어는 집단에서 추상적인 특정 대상을 가리키기 위해서 암묵적, 또는 공개적으로 정한 약속과 같은 것입니다. 컴퓨터 언어도 마찬가지입니다. 컴퓨터 언어의 단어들은 소스 코드들이 모여서 만들어 지고 이미 만들어져 있는 단어들을 API(Application Programming Interface)라고 합니다. 이런 단어들을 가져다 쓰기도 하고, 만들기도 해서 사용자가 컴퓨터에게 시키고자 하는 명령 문장을 만드는 것을 코딩이라고 합니다.  이렇게 만들어진 명령 문장들이 모여서 프로그램을 만들어가는데 이 과정을 프로그래밍이라고 합니다. 

책 = 프로그램

책 만들기 = 프로그래밍(프로그램 만들기)

글쓰기 = 코딩(code 키보드로 타이핑 하기)

단어 = API

글자 = (source)code

언어 = 프로그램 언어(JAVA, C, C++, 어셈블리어)
달필가가 쓴 글은 중복이 없고, 문체가 간결해서 군더더기 없이 읽혀지기 쉽습니다. 좋은 프로그래머가 만든 프로그램도 똑같습니다. 더 나은 글을 쓰기 위해서 문장이 맞았는지 틀렸는지 알 수 있게 문법을 배우는 과정이 필요하듯, 프로그래밍을 잘하기 위해서는 좀 더 간결하면서 동시에 컴퓨터가 명령을 빠르고 효율적으로 수행할 수 있는 구조로 글쓰기(코딩)를 연습하면 되는 것입니다.

이제 코딩과 프로그래밍에 대한 개념을 어느 정도 살펴보았습니다. 개념을 잡은 뒤엔 실전으로 부딪혀 봐야 합니다. 프로그래밍에는 ‘백문이 불여일견’이라는 말과 비슷하게 ‘백문이 불여일타’라는 말이 있습니다. 백날 소스 코드를 본다고 해서 실력이 늘진 않습니다. 실력은 손으로 직접 코드를 쳐봐야 늘기 마련입니다.


예방주사1

API(Application Programming Interface)
 API는 이미 만들어져 있는 함수(프로그램)의 집합입니다. 조금 더 쉽게 이해하기 위해서  API를 단어 사전이라고 생각하면 이해하기가 더욱 쉽습니다. API는 이미 다른 사람들이 단어를 만들어 놓은 것입니다. 글을 쓸 때 단어가 생각이 안 나면 사전에서 단어가 어떤 뜻인지 찾아보고 적절한 단어를 가져다 쓰듯이, 프로그래밍을 하면서 내가 필요한 부분을 API에서 찾아보고 가져다 쓰면 되는 것입니다.
쉘(shell)
위에서 설명했다시피 컴퓨터가 정보를 주고받기 위해서는 언어가 필요합니다. 컴퓨터는 작동하는 과정에서 0과 1이라는 전기적 신호로 의사소통을 합니다. 무수히 많은 0과 1이 반복되는 컴퓨터 언어는 사람이 알아보기 힘들다는 단점이 있었습니다. 그 결과 사람이 알아볼 수 있도록 어셈블리어라는 언어가 만들어지게 되었습니다. 그런데 어셈블리어를 만들어서 기계에 명령을 내리려고 하자, 이 또한 양이 방대해서 사용하기에 불편했습니다. 그래서 만들어진 것이 커널입니다. 어셈블리어로 만들어진 커널은 컴퓨터의 핵심으로 동작처리, 메모리관리, 입출력 연산 등 컴퓨터가 작동되는 모든 연산들이 프로그래밍 되어있습니다.
 쉘은 이러한 커널에 명령을 내리기 위해서 만들어진 프로그램입니다.
프로그래밍을 모르시는 분들은 ‘마우스 더블 클릭으로 명령을 내리면 되는데, 왜 굳이 쉘에 대해 알아야 하나’고 하시는 분도 있을 수 있습니다. 지금 우리가 사용하고 있는 이 바탕화면을 GUI(Graphic User Interface)라고 합니다. 그리고 쉘이 없으면 GUI는 개발이 되지 않습니다. 쉘이 프로그래밍에서 중요한 이유가 이것입니다.


OS(operating system)
사용자가 컴퓨터를 사용할 수 있게 해주는 프로그램입니다. 흔히 사용하는 windows, MAC, Linux 등이 여기에 속합니다.

CUI(Character User Interface) = TUI(Text User Interface) 
단어 그대로 키보드를 통해서 텍스트로 명령어를 입력해서 컴퓨터가 작업을 사용할 수 있게 하는 환경입니다.
GUI(Graphic User Interface)
지금 우리가 사용하고 있는 컴퓨터처럼, 마우스를 움직여 화면에 있는 아이콘을 클릭해 컴퓨터가 작업을 하게 하는 환경입니다

CMD(command의 줄임말) 
windows에서 키보드를 통해서 명령어를 입력 작업을 수행 할 수 있는 창입니다. 여러분이 아는 까만 바탕화면에 흰 글씨가 적혀있는 창을 커맨드 창이라고 하며, 주로 cmd라고 표기합니다.

디렉터리(directory) 
일상생활에서 문서를 작성한 뒤, 폴더에 넣고 이름과 정보(위치)를 쓴 다음 책장에 꽂아 놓으면 필요할 때 그 폴더를 찾을 수 있습니다. 마찬가지로 시스템 안에서 파일을 생성했을 때 그것이 어디에 있는지 나타내줄 수 있는 정보가 표시된 것을 디렉터리라고 합니다.

변수,상수
 변수는 변하는 값입니다. 수학 시간에 우리는 x+y=5를 배운적이 있습니다. x와 y가 자연수라는 가정하에도 x와 y에는 많은 수가 들어갈 수 있습니다. 마치 빈 그릇과 같습니다. 비어있는 그릇이니까 채웠다 비웠다 할 수 있습니다.  상수는 이와 반대로 바뀌지 않고 한번 정하면 변하지 않는 값을 상수라고 합니다. 

프로그래밍을 해보자 <쉘(shell) 프로그래밍>

먼저 쉘(shell) 프로그래밍 실습을 해봅시다. 시장 점유율이 높은 Windows 운영체제를 중심으로 실습 과정을 진행하면서 코드에 대해 설명해 보겠습니다. 쉘 프로그래밍은 다른 프로그래밍 언어와는 달리 설치 없이 바로 실행할 수 있기 때문에, 바로 실습을 해보기 적합한 프로그래밍이라는 장점이 있습니다.
컴퓨터에 명령어를 입력하기 위해서는 먼저 명령어를 입력할 cmd 창을 띄워야 합니다. 키보드의 Windows key
와 R을 동시에 눌러봅시다. Windows key는 데스크 탑 키보드를 기준으로 보통 Alt key의 옆에 있습니다.

위의 창을 실행 창이라고 합니다. cmd를 입력하면 다음과 같은 cmd.exe 창이 뜹니다. 
이 창을 명령 프롬프트, 또는 도스창이라고 부릅니다. 앞으로의 실습에서는 이 실행창을 ‘cmd 창’이라는 용어로 표기할 예정입니다. 여기에 기본 명령어를 코딩(타이핑) 해보겠습니다. 기본 명령어로는 다음과 같은 것들이 있습니다.
 cls 화면 지우기
dir 디렉터리 보기
 cd 디렉터리 바꾸기
md 디렉터리 생성
  rd 디렉터리 지우기
explorer 현재 디렉터리 기준으로 탐색기 실행
위에 있는 명령어들을 이용해서 간단한 프로그래밍을 해봅시다. 처음 입력해볼 명령어는 dir(디렉터리)입니다. dir은 현재 위치에 어떤 파일이나 디렉터리가 있는지 보여주는 명령어입니다. 지금 우리가 사용하고 있는 cmd 창은 CUI, 즉 텍스트(글자)기반의 사용 환경입니다. cmd 창에서는 내가 원하는 위치의 폴더로 들어가기 위해서 마우스를 이용할 수 없습니다. 글자로만 이루어진 cmd 창에서 위치 또한 글자로 파악해야 하기 때문에 명령어가 필요한 것입니다.
dir을 입력하면 사용자가 위치해 있는 장소인 C:\Users\SORASOFT 폴더 안의 2개 파일과 25개의 디렉터리, 그리고 그 정보들이 나타납니다.
이번에는 폴더를 한번 만들어 보겠습니다. ‘md 폴더명’을 타이핑한 다음 Enter key를 치면 폴더가 생성됩니다.  ‘실습’이라는 이름의 폴더를 만들었습니다.
폴더가 실제로 만들어졌는지 확인하기 위해 방금 전 해봤던 dir 명령어를 다시 입력해 보겠습니다.
2016-07-28 날짜에 실습이라는 폴더가 만들어진 것을 확인했습니다. cmd 창을 이용해서 컴퓨터에게 명령을 내려 봤는데, cmd 창에서 명령한 내용이 실제로 컴퓨터에 적용되었는지 확인해 봅시다.
 cmd 창에 파일 탐색기를 통해서 현재의 디렉터리를 볼 수 있는 explorer 라는 명령어를 입력해줍니다.  ‘explorer .’ 이라고 타이핑하면 지금 제가 있는 디렉터리가 화면에 나오는데, 이때 반드시 explorer를 타이핑 한 다음 한 칸을 띄우고 .을 찍어야 합니다.
새로 뜬 창에서 방금 전 cmd 창에서 만든 폴더가 생성되어 있는 것을 확인할 수 있습니다. 
 ‘rd 폴더명’을 입력하면 생성했던 폴더, 혹은 기존에 존재했던 폴더가 삭제됩니다. 쉘에서 명령어를 타이핑하는 것도 코딩입니다. 앞으로는 다양한 플랫폼의 적응을 위해, cmd 창도 ‘쉘’이라는 용어로 통일하도록 하겠습니다.
기본적인 명령어와 입력 방법을 익혔으니 쉘에 다음 명령을 코딩해 봅시다. 코딩에서 띄어쓰기는 매우 중요한 부분이니 주의해서 입력해 봅시다.
for %i in (1, 2, 3, 4, 5, 6, 7, 8) do md 새폴더%i
User 폴더에 새폴더1부터 새폴더8까지의 이름을 가진 8개의 폴더가 생성되었습니다. 위에서 했던 것과 같이 ‘explorer .’을 이용해서 User 폴더에서 새폴더를 직접 확인할 수도 있고, dir 명령어로 cmd 창에서 확인할 수도 있습니다.  갑자기 약간 복잡해진 명령어 코딩 때문에 혼란스러웠을 수 있지만 하나하나 풀어보면 별것 아닙니다. md가 폴더를 만드는 명령어였던 것처럼 다른 명령어에도 각기 역할이 있습니다. for는 문장을 반복하게 하고, %i는 변수라고 불리며 그릇의 역할을 합니다. i 안에 괄호 안의 숫자들을 넣은 폴더가 생기는 것입니다. 
for %i in (1, 2, 3, 4, 5, 6, 7, 8) do md 새폴더%i
       반복해서 i라는 변수에 1,2,3,4,5,6,7,8 숫자를 넣어서 폴더를 만들어라 새폴더i 이름의 
조금 다른 코딩을 이용해 9에서 20까지의 새 폴더를 만들어 봅시다.

for /L %i in (9, 1, 20) do md 새폴더%i
for과 %i 값은 그대로 넣되 /L이라는 옵션이 등장했습니다. 소괄호 안에 입력한 값도 이전의 코딩과는 다른 구조로 되어 있습니다(이 구문에서 소괄호 안의 값은 띄어쓰기를 하여도, 하지 않아도 동일한 결과가 나옵니다).
/L 옵션을 이용하여 소괄호에 입력하는 값을 (시작값, 증가치, 종단값)으로 FOR LOOP 문 인자를 바꾸었습니다. 옵션을 이용하여 일정한 규칙에 의해 반복되는 값을 입력하는 수고를 줄인 것입니다.
여기까지 폴더를 만들어보았습니다. 실습을 위해 만들었던 폴더를 삭제하고 싶다면, 위에서 입력해본 명령어와 구문을 응용할 수도 있습니다.
새폴더를 만드는 실습에서 우리는 새폴더1부터 새폴더20까지, 스무 개의 폴더를 만들었습니다. 시작값을 1로 두고 종단값을 20으로 둔 뒤, 증가치를 1로 설정해줍니다. 폴더를 만드는 대신 이번엔 폴더를 삭제하는 명령어를 넣어줍시다.

for /L %i in (1, 1, 20) do rd 새폴더%i
User에서 결과물을 확인해봅시다!

이렇게 명령어를 입력하여 작업을 하는 쉘 프로그래밍에서는 띄어쓰기나 점으로 명령하는 내용이 완전히 뒤바뀌는 경우도 있습니다. 방금 전 입력해보았던 cd(change directory)와 explorer 명령어를 예로 설명해보겠습니다.
cd는 디렉터리를 바꾸어주는 명령어입니다. cmd 창에서의 .은 현재 폴더를, ..은 상위 폴더 즉 한 단계 위의 폴더를 뜻합니다. 이 명령 단위들을 조합해 입력해봅시다.

‘.’이 하나일 경우에는 위치가 C:\Users\SORASOFT 그대로이지만 ‘..’을 사용하자 C:\Users\SORASOFT에서 상위 디렉터리인 C:\User로 바뀌었습니다. 한번 더 사용하니 C:\ 최상위 디렉터리로 이동 되어진 것을 확인할 수 있습니다. .cd 명령어로는 cmd 창에서의 디렉터리가 바뀌는 것 만을 확인할 수 있지만, explorer를 이용하면 좀 더 쉽게 눈으로 상위 폴더로의 이동을 볼 수 있습니다. 똑같은 방법으로 explorer를 입력해봅시다.
‘.’이 하나 일때는 C의 Users의 user 폴더창이 뜨게 되고, ‘..’ 점이 두 개 일때는 C의 Users 폴더창이 뜨는 것을 확인하실 수 있습니다.

이것으로 아주 기초적인 코딩을 마쳤습니다. 이렇게 쉘에서 코딩을 해 프로그래밍 하는 것을 쉘 프로그래밍이라고 합니다. explorer로 간단히 실행할 수 있었던 탐색기의 모든 기능을 만들기 위해서는 고급 개발자가 한 달 이상 투자를 해야 합니다. 버그를 잡기 위해서는 다시 한 달 이상을 투자해야 합니다. 사용자에게 베타 테스팅을 하고 시장에서 검증 받으려면 추가로 많은 돈과 시간이 들어갑니다. 그렇지 않았다면 누구나 TOTAL COMMAND와 같이 수십 억(76억 추정)의 수익을 올리는 탐색기를 만들 수 있었을 것입니다.
상황에 따라 최적의 솔루션을 만드는 데에는 쉘 프로그래밍만한 것이 없습니다. 가령 shutdown –s –t 3600을 입력한다면, 여러분은 1시간(3600초) 뒤에 컴퓨터가 자동으로 꺼지도록 할 수 있습니다. 물론 shutdown –a로 명령을 취소하는 것도 가능합니다.
지금까지 해온 일련의 과정을 바로 쉘 프로그래밍이라고 합니다. 혹은 Shell script coding이라고도 합니다. 이런 작업들을 “프로그래밍 하다”, “코딩을 하다”로 표현하며, 작업을 이루어내는 사람을 “프로그래머”나 “코더”라고 부르는 것입니다.
Chapter 2. 프로그램을 실행시켜 보자
 앞선 장에서 우리는 쉘(shell)프로그래밍을 통해서 간단하게 프로그래밍의 맛을 봤습니다. 이번장에서는 C와 JAVA를 통한 프로그래밍을 해 보려고 합니다. 

Visual Studio 설치 (C/C++)

이번 장에서는 C 프로그래밍을 도와줄 수 있는 IDE인 Visula Studio의 설치를 해 보겠습니다.
앞서 ‘왜 Visual Studio여야 하는가?’라는 질문을 해결해보았습니다. 지금부터는 운영체제가 Windows라는 전제 하에 Visual Studio 2015 community version을 설치해봅시다.
0. 컴퓨터의 용량을 확인하자
Visual Studio는 소위 말하는 용량 괴물입니다. 설치 안내에서는 약 11GB의 공간을 확보해야 한다고 나와 있지요. 용량 부족으로 설치 도중 오류가 뜨지 않도록, 사전에 Visual Studio를 설치할 공간을 마련해야 합니다.
Windows key와 E키를 동시에 눌러봅시다. 컴퓨터(내 PC)에서 사용 가능한 용량을 확인할 수 있습니다. 로컬 디스크(C; , C드라이브)의 용량이 96.9GB 남았으니 충분하게 설치가 가능합니다.
1. 프로그램 다운받기
주소창에 https://www.visualstudio.com/를 입력합니다.
‘모든 개발자 및 모든 앱을 위한 도구’라는 설명과 함께 다운로드 창이 뜹니다. 다운로드 종류 중 가장 처음 나오는 Community 2015 다운로드를 클릭하면 설치가 시작됩니다.
2. 설치 유형과 기능 선택
설치 위치는 기본적으로 C드라이브의 Program File로 지정됩니다. 설치 위치를 변경하고 싶을 경우, 
표시 아이콘을 눌러서 원하시는 위치를 지정하시면 됩니다.
설치 유형은 기본값과 사용자 지정 설치 두 가지로 나뉩니다. 대부분의 Visual Studio 설치 관련 글에서는 사용자 지정 설치를 권하고 있습니다. 사용자 지정 설치의 경우 인스톨 패키지를 지정할 수 있는 특징이 있습니다. 책에서는 사용자 지정 설치를 해보도록 하겠습니다.
사용자 지정 설치를 선택한 관계로, 우리는 다음 단계에서 프로그램의 설치를 위해 필요한 기능을 선택해야 합니다. 상단에 있는 [프로그래밍 언어]를 열어봅시다. [⦊버튼 클릭]
이 책에서 Visual Studio를 설치하는 목적은 C/C++ 프로그래밍을 위해서 입니다. [프로그래밍 언어] 항목에서 Visual C++ 항목에 [모두 선택]을 해줍니다. 우측 하단의 ‘다음’ 버튼을 누르면 선택한 기능을 확인하는 창이 뜹니다. 확인 후 설치(I)를 클릭합니다. 설치 과정에는 상당한 시간이 걸립니다.
위 화면이 뜸과 동시에 설치가 완료되었습니다. 프로그램이 정상적으로 작동하는지 확인하기 위해서, 재부팅 후 Visual Studio 2015를 시작해 보도록 하겠습니다.
3. 프로그램 열기
시작 프로그램에서 Visual Studio 2015를 열면 로그인 창이 뜹니다. ‘나중에 로그인’을 눌러도 서비스를 이용할 수 있지만, 설치 후 30일 이후부터는 등록을 해야 계속 Visual Studio 2015를 사용할 수 있습니다. 로그인은 Microsoft 계정으로 하며, 메일 주소나 전화번호로 계정을 만들 수 있습니다.
로그인 화면을 넘기면 환경 설정을 해야 합니다. 개발 설정은 일반으로 고정되어 있습니다. 색 테마를 고르고 Visual Studio 시작(S)을 클릭하면 시스템 설정이 완료됩니다.
번외. 생길지도 모를 오류
Visual Studio 2015를 설치하는 도중, 다음과 같은 안내창이 뜨면서 설치가 자동으로 이루어지지 않는 경우가 있습니다. 이 경우 [인터넷에서 패키지 다운로드]를 선택해줍니다. 패키지는 팝업 창의 지시에 따라 쉽게 다운 받을 수 있으며, 이후 자동으로 설치가 계속 진행됩니다.
설치 패키지 오류가 나면 인터넷에 위 화면이 뜹니다. 설치가 완료되거나 패키지를 다운 받으면서 [확인]을 누르면 됩니다.

예방주사2

드라이브 (Drive)
라이브러리(library)
라이브러리란 기계어로 번역된 바이너리 파일입니다. 프로그램에서 자주 사용되는 프로그램이나 부분들을 모아놓은 것입니다. 단어의 뜻 그대로 도서관이라고 생각하시면 이해가 쉽게 될 것입니다.  책을 쓰는데 필요한 자료들을 도서관에서 찾는 것과 같다고 생각하시면 됩니다.  
라이브러리에는 동적라이브러리와 정적 라이브러리가 있습니다.
정적 라이브러리의 경우 프로그램이 동작되는데 있어서 자주 접근해야 하는 부분들이기 떄문에 링크 시 프로그램에 합쳐집니다. 
동적 라이브러리는 필요할 때만 접근하기 
헤더(header)
Y 199.1 2583 c.2 
stdio.h  이것이 헤더 파입니다.  이 말은 표준 입출력 라이브러리 내용을 가져다 쓰기 위해서 프로그램에 저렇게 명시를 한 것입니다. 
 헤더는 라이브러리의 색인(index) 이라고 이해 하시면 쉽습니다. 라이브러리의 설명에서 이어 말을 하면, 책을 쓰는데 필요한 자료를 모두 다 넣다보면 책의 분량이 너무 방대해지기 때문에, 간단하게 그 책의 제목이나 정보를 넣어서 참조했다는 것을 표시하는 개념인 것입니다.
직역해서 객체 라고 부를 수 있습니다. iostream은 헤더 파일입니다. ‘함수 원형’으로 불리기도 합니다. JAVA의 인터페이스(*향후 나올 자바의 주요 개념) 와 같이 본체는 없지만 형식만 있는 것입니다. 프로토타입으로 자주 불리기도 합니다. 이처럼 여러 이름을 가지고 있습니다. 앞으로는 간단히 header(헤더) 로 하겠습니다. 명확한 의미상으로는 모두 ‘프로토타입’으로 말하고 싶으나 파일 확장자가 .h로 되어 있습니다. .h 파일을 찾아서 열어 봅시다. math.h 파일을 열어 봤습니다.
우리는 이미 hello, world를 만들어 보았습니다. 왠지 { } 가 나오고 그 안에 내용들이 들어가는 형식이 나와야 하는데 없습니다. 구현 내용이 없다고 생각하시면 됩니다.
헤더와 헤더의 내용이 구현된 소스와 결합된 오브젝트 파일은 다른 프로그램에 연결해서 사용할 수도 있기에 라이브러리라고 할 수 도 있습니다. 링커의 입장에서 보면 .obj 확장자 파일과 .lib확장자 파일의 차이가 없습니다. 이처럼 소스에서 obj 파일로 변환하는 과정을 컴파일 과정이라고 합니다. 컴파일 과정은 WINDOWS 뿐 아니라 LINUX, MAC에서도 동일합니다. 컴파일러의 차이가 있습니다.
include
메모리

Path 설정

쉘 프로그래밍에서 dir,md,cd,rd 등은 쉘(shell)에 내장된 예약어 입니다. 즉 쉘이 가지고 있는 API 입니다. 이들 API는 어느 곳에 있던지 항상 실행할 수 있습니다.  그러나 explorer, notepad 는 예약어가 아닌 프로그램입니다. 즉, 아무데서나 호출할 수 있는 API가 아닙니다. 그런데 어떻게 호출할 수 있었을까요? 이 때 필요한 것이 바로 PATH 입니다.
PATH에 등록이 되어 있다면 어떤 곳에서든 실행이 가능합니다.
만약에 path 설정이 되지 않은 cl(cl.exe)이라는 컴파일 명령어를 사용하려고 하면 다음과 같은 문구를 접하게 됩니다. 
하지만 path 설정을 하게 되면 다음과 같이 cl명령어가 작동되는 것을 볼 수 있습니다. 
 PATH는 단어 뜻 그대로 길, 통로입니다. 가령 책을 쓰는데, 참고할만한 내용이 있는 책이 A도서관에 있습니다. 그런데 그 도서관이 어디 있는지 가는 길을 모릅니다. 그러면 우리는 도서관의 주소를 가지고 책을 찾으러 갑니다.  이와 마찬가지로 우리가 사용하고자 하는 파일들의 주소를 paht에 등록함으로써 우리는 어떤 곳에서든 그 프로그램을 사용할 수 있게 되는 것입니다.
 이 개념은 나중에 다시 설명하겠지만 library와 include의 사용과도 같은 맥락입니다.  
자 그럼 지금부터 C의 path 설정을 해 보도록 하겠습니다. path 설정은 컴퓨터의 Windows 버전에 따라 팜업 창의 모양이 조금씩 다릅니다. 먼저 버전 10 이상의 화면을 예시로 설명해 보겠습니다.
윈도우키와 Break 키를 누르면 제어판의 시스템 창이 뜹니다. ‘컴퓨터에 대한 기본 정보 보기’에서 현재 자신의 운영체제 버전을 확인할 수 있습니다. 좌측 고급 시스템 설정에 들어가면 여러 탭이 보입니다. 
고급 탭에서 환경 변수를 클릭합니다.
[시스템 변수]에서 PATH 를 찾아 더블클릭 합니다.
우리가 C언어로 만든 프로그램의 컴파일과 링크를 위해서는 cl.exe 와 link.exe가 있는 경로를 지정해 줘야 합니다. 컴파일과 링크에 대해서는 바로 다음 장에 설명을 하니 여기에서는 넘어가도록 하겠습니다.  

시스템 변수에 Visual Studio의 cl.exe가 있는 디렉토리를 찾아서 넣어주세요. cl.exe를 찾기 위해 탐색기를 이용하는 방법도 있습니다. Visual Studio가 있는 폴더 또는 내 PC에서 cl.exe를 검색하면 다음과 유사한 경로의 cl.exe 파일을 찾을 수 있습니다.
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin 경로에 cl.exe가 많이 보입니다.

경로에 있는 \ 표시를 슬래쉬라고 합니다. \와 똑같다고 이해하셔도 좋습니다. 경로를 복사하고 붙여넣는 과정에서 표기가 바뀌는 경우도 있지만 실제로 이상이 있는 것은 아닙니다.
보통 자신의 컴퓨터에 Visual Studio가 설치되면 C드라이브에 설치가 되지만, D나 E 혹은 F드라이브에 설치되어 있다면 위와 비슷한 경로를 설치된 드라이브에서 찾아서 넣어주시면 됩니다.  
새로 만들기 버튼을 클릭해서 경로를 넣어주시면  path 설정이 끝납니다. 이제 우리는 {자신의 드라이브}:\Program Files (x86)\Microsoft Visual Studio14.0\VC\bin에 있는 파일들을 어떤 곳 에서든지 사용할 수 있게 되었습니다. 

윈도우 10 이하 버전에서의 path 설정 화면은 다음과 같습니다. 표시 방법에 차이가 있을 뿐 path 설정 방법은  똑같습니다. 시스템 변수에서 path를 선택해서 편집 버튼을 누릅니다.
다음과 같이 path에 추가되어있는 많은 경로들이 보입니다.  ; 이 표시는 ‘구분자’라고 하며, 말 그대로 구분을 지어주는 역할을 합니다. 경로;경로;경로와 같은 식의 구분을 짓습니다. 
변수 값 항목에  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin 경로를 추가합니다. 추가 방법은 아래와 같이 기존에 있던 경로에 ‘;’을 붙이고 바로 path를 추가하시면 됩니다.                    
경로;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin 
다음과 같이 변수 값의 마지막 부분을 정리해줍니다. 마지막에 슬래쉬(\)를 추가하면 위 사진과 같은 변수 값이 완성됩니다. 확인을 누르면 path 설정이 끝납니다.

컴파일(Compile)/링크(Link) 

 코딩을 하게 되면 컴파일, 링크, 라이브러리와 같은 용어들을 많이 듣게 됩니다. 많이 등장하는 용어란 기본이고 중요하다는 뜻과도 같습니다.
컴파일과 링크는 우리가 코딩한 프로그램이 실제로 컴퓨터에서 동작을 할 수 있는 실행 파일이 되는 과정입니다. Windows 에서의 실행 파일은 확장자(. 뒤에 붙는 영문자) 가 .com 혹은 .exe 인 파일 입니다.
 .com은 작은 메모리를 사용하는 유틸리티에서 많이 사용되었던 확장자 입니다. Windows의 실행 파일은 .exe 라고 알아 두셔도 되겠습니다.
아래 그림의 KaKaoTalk.exe 파일이 카카오톡의 실행파일입니다.
  이전 장에서는 만들어진 프로그램을 책에 비유했습니다. 이 책을 만든 우리는 한국인이기 때문에 한글로 쓰여졌습니다. 만약 미국인이 이 책을 읽고자 한다면 한글을 이해하지 못하기 때문에 읽지 못 할 것입니다. 따라서 미국인이 책을 읽기 위해서는 번역가가 책을 영어로 번역을 해주어야 합니다.  프로그램도 마찬가지입니다. 우리가 알아보기 쉬운 고급언어(C,C++,JAVA 등)로 만들어진 프로그램을 컴퓨터가 이해할수 있는 기계어로 변환 시켜주는 작업을 컴파일이라고 합니다. 컴파일과정이 끝나고 라이브러리(library)에 링크하는 과정을 거치면 컴퓨터가 실행할 수 있는 실행파일이 생성됩니다.  
컴파일 과정을 조금 더 깊이 들어가 보면 다음과 같습니다. 
그림에서 보여지듯이 Preprocessor, Parser,Translation, Assembler 과정을 컴파일(compile)이라고 합니다.  프리프로세서 과정은  컴퓨터가 알아보기 쉽게 코드를 정리하는 단계입니다.
 #include, #define 과 같은 매크로나 지시자를 소스코드로 변환해 줍니다.  여기서 우리의 소스코드 파일인 sourc.c는 source.i 파일로 변환 생성됩니다. 
Parser 는 코드들이 문법적으로 이상이 있는지 없는지 문법검사를 하고, Translation 과정에서는 명령어들에 대응하는 어셈블리어로 바꿔주는 역할을 수행합니다.  여기서 source.i 파일은 C 컴파일러인 cc1에 의하여 어셈블리 코드인 source.s 로 변환된다.
Assembler는 어셈블리 코드를 기계어로 코드를 바꿔줍니다. Translation과정의 결과물인 source.s 파일은 이 과정에서 source.o 파일로 변환됩니다.
여기까지가 컴파일 과정입니다. 이 과정에서 생긴 결과물은 실행파일이 되기에는 반쪽짜리 결과물입니다. 왜냐하면 라이브러리 링크 과정이 없었기 때문입니다. 
그렇다면 링크는 무엇일까요?  링크는 프로그램이 돌아가는데 필요한 라이브러리를 이어주는 작업을 수행합니다. 
 앞장에서 API를 단어 사전이라고 했던 설명을 기억하시나요?  라이브러리는 바로 이 API를 모아놓은 장소라고 생각하시면 쉽게 이해가 되실 겁니다. 단어의 뜻인 도서관처럼 다양한 책들이 모여있고 우리가 책을 만들 때 필요한 내용들을 찾아서 넣으면 됩니다. 
링크과정을 좀더 자세히 알아보면 링크에는 동적링크와 정적링크가 있는데, 이것은 라이브러리의 종류에 따라서 나뉘어집니다. 
 프로그램이 실행되는데 있어서 자주 쓰여지는 부분들은 정적 라이브러리로 분류 되는데 이 부분들은 링크 시 프로그램에 합쳐집니다. 동적 라이브러리는 필요할 때만 접근하면 되기 때문에 실행파일에는 포함되지 않고 따로 배포가 됩니다. 
소스가 컴파일 된 오브젝트 파일(source.o 10MB)과 정적 라이브러리(100MB), 동적 라이브러리(20MB)가 있으면, 링크 과정을 거쳐서 실행파일(source.exe) 110MB 가 생성됩니다. 
우리가 코딩한 소스들은 이렇게 컴파일과 링크 과정을 거쳐서 생성된 실행파일을 컴퓨터가 인식해서 동작을 하게 되는 것입니다.

C/C++ 프로그래밍

지금까지 배운 내용들을 C/C++ 프로그래밍을 통해서 실습을 해보겠습니다. 
먼저 cmd 창을 열어보겠습니다. 
쉘 프로그래밍에서 배웠던 예약어를 복습하면서, 앞서 설치했던 Visual Studio 디렉터리를 찾아가보겠습니다. 앞에서는 cd.. 명령어를 통해서 순차적으로 가고자 하는 디렉터리를 찾아갔다면 이번에는 우리가 원하는 디렉터리로 바로 들어가 보도록 하겠습니다. 
다음과 같이 cd 명령어 뒤에 원하는 디렉터리의 완전한 경로를 넣어주시면 됩니다. 이때 반드시 드라이브가 포함된 완전한 경로를 넣어야 명령어가 실행됩니다.
 cd C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
이번에는 현재 위치에서 제가 원하는 파일들을 찾아보겠습니다. 
dir *.exe
이 명령어에서 뒤에 모든(all)을 뜻하는 애스터리스크 마크(*)는 모든(all)을 뜻합니다. 즉 이 파일 안에 있는 exe 확장자를 가진 모든 파일을 보여달라는 것입니다. 
이 exe 파일들이 컴파일에 필요한 실행 파일들 입니다. 즉, 개발툴 입니다.
자 다시 user 폴더로 돌아와서 notepad a.cpp 를 타이핑하고 다음과 같은 창이 뜨면 새 파일을 만들어보겠습니다.
우리는 메모장을 통해 a.cpp 라는 파일을 생성했습니다. 
explorer . 명령어를 통해서 파일이 생성되어 있는 것을 확인해보겠습니다. 
메모장으로 돌아와서  ‘hello world’라는 문자가 출력되는 내용을 코딩해보겠습니다.             
#include <iostream>

int main()
{
   printf("hello world");
   return 0;
}
이렇게 만들어진 a.cpp 를 소스 또는 소스 파일 혹은 원시 파일 이라고도 합니다. 앞으로는 간단히 소스(source) 라고 하겠습니다.
메모장에서 코딩하지 않고 cmd 창에서 바로 코딩을 하려면 copy con 명령어를 이용해도 됩니다.
소스코드 타이핑이 끝나면 ^Z(Ctrl키 + Z키)키를 누르시면 “1개 파일이 복사 되었습니다.”라는 문구와 함께 파일이 생성됩니다. 
컴파일 과정                    
cl.exe a.cpp
이 명령어를 타이핑 하고 엔터키를 누르는 것을 컴파일 링크 과정이라고 합니다. 이를 간단히 ‘컴파일’ 이라고 합니다.                    
cl.exe /c a.cpp
이렇게 옵션(/c)을 주면 링크를 생략하고 컴파일만 하게 됩니다.
옵션을 주던, 주지 않던 에러가 발생합니다. 발생한 에러를 고치는 것을 ‘디버깅’이라고 합니다. ‘버그를 잡는다.’고도 표현합니다. 
에러 메세지를 보면 다음과 같습니다. 
a.cpp(1) : a.cpp 파일의 1번째 줄에서 에러가 발생했다. 
에러내용: iostream 포함 경로를 설정하지 않았습니다. 
즉, #include <iostream> 이 구문에서 에러가 발생하였다는 것입니다.  iostream 은 입력과 출력을 위한 헤더 파일이고, ‘include’는 이 헤더 파일을 가져오는 것을 뜻합니다. 포함 경로를 설정하지 않았습니다 라는 에러 문구에서 알수 있듯이 문제는 iostream에 대한 경로가 설정되지 않아서 include가 되고 있지 않는 것입니다.
문제를 해결하기 위해서는 include 라는 변수에 iostream의 경로(path)를 넣어 주어야 합니다.
 앞에서 설명한 ‘PATH 설정’에서 했던 것과 같이  [시스템환경] 변수에서 paht설정이 가능 하지만, 이번에는 shell 에서 명령어로 설정해 보겠습니다. 우리가 쓸 명령어는 다음과 같습니다.
set INCLUDE=값
여기서 INCLUDE는 “변하는 수”인 변수입니다.  해당 변수에 iostream 경로를 넣어주어야 합니다. 아래 경로에서 iostream 을 검색해 보시기 바랍니다.                         
C:\Program Files (x86)\Microsoft Visual  Studio 14.0
C:\ 일 수도 있고D:\ 일수도 있습니다. Visual Studio 가 설치된폴더에서 검색하면 됩니다. 시간이 걸리더라도 괜찮으면 컴퓨터 전체 검색으로 찾아도 되겠습니다.
찾은 경로는 C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include 입니다. 이제 이 경로를 INCLUDE 변수에 넣어주면 됩니다.                    
set INCLUDE=C:\Program  Files (x86)\Microsoft Visual Studio 14.0\VC\include\
그리고 다시 한번 실행시켜 줍니다. cl.exe에서 .exe는 제외해도 됩니다.                                             
cl /c a.cpp
이번에는 다음과 같은 에러가 발생합니다.
에러 메시지를 통하여 corecrt.h 파일이 필요하다는 것을 알 수 있습니다. corecrt.h 파일을 찾아서 추가하면 됩니다. 
이렇게 주소를 추가하면서 한 글자라도 틀리게 되면 제대로 추가가 되지 않습니다. 그리고 매번 장문의 주소를 추가하기가 힘들기 때문에 앞에서 배웠던 변수를 재 사용하는 방법을 사용하겠습니다.                     
set INCLUDE=추가할 경로;%INCLUDE%
이처럼 세미콜론(;)을 붙이고 %INCLUDE% 로 덧붙이게 되면 아까 INCLUDE에 들어가있던 주소와 이번에 새로 추가할 경로까지 한번에 들어가게 됩니다. 
해당 파일을 찾아서 넣어줍니다.                     
set INCLUDE=C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\
해당 경로를 넣고 이번에는 링크제거(/c) 옵션을 제외하고 명령어를 실행 해 보겠습니다.                     
cl a.cpp
a.obj 파일이 생성되었습니다. 이로서 컴파일 과정은 완료했다는 것을 알수 있습니다. 하지만 libcpmt.lib 파일을 열 수 없습니다.  라는 에러 문구를 통해서 링크과정에서 문제가 생긴것을 알 수 있습니다. 
먼저 a.obj 파일이 생성되었는지 확인해보겠습니다. 다음 명령어를 실행 해봅니다.                    
dir a.obj
실제로 SORASOFT 디렉터리 안에 a.obj 파일이 생성되었습니다. 
 링크 에러는 발생하였지만 a.obj 파일이 생겼습니다. 링크 에러를 보고 싶지 않다면
cl /c a.cpp 를 통하여 컴파일 과정만 진행 합니다. warning은 발생합니다. 그러나 obj 가 만들어 집니다. 이를 통하여 warning 은 error 처럼 .obj 파일을 만들지 못하게 할 수는 없다는 것을 알 수 있습니다. obj는 object의 약자 입니다. 
자 이제 링크 과정으로 돌아오겠습니다.  libcpmt.lib가 파일을 열 수가 없다고 합니다. 이제 어떻게 해야 하는지 아시죠? 해당 파일을 찾습니다. 찾아서 LIB라는 변수에 넣어줍니다.                         
set LIB=경로;경로;경로
넣고 실행합니다. 에러가 또 나면 에러 메시지를 보고 해당 파일을 찾아서 또 넣어 줍니다. 디버깅 과정이 이렇게 지루한 반복 작업이 많습니다. 이렇게 하는 디버깅을 RUN & FIX디버깅, 혹은 블랙박스 디버깅이라고 합니다. 앞으로는 간단히 “디버깅”이라고 하겠습니다.
저의 경우 다음과 같이 경로 지정을 해 주어야 했습니다.                                             
set LIB=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86
라이브러리 경로 지정 후 컴파일을 한 결과 a.exe가 생성되었습니다.  
해당 디렉터리를 열어보면 소스파일(a.cpp)과 컴파일 과정을 거치면서 만들어진 오프젝트 파일(a.obj) 그리고 링크과정을 실행파일(a.exe)이 생성되어 있는 것을 보실 수 있습니다. 
자 이제 a.exe를 실행시켜보겠습니다. 이때는 a 만 적어도 실행이 됩니다. 
‘hello world’ 라는 문자열이 출력이 되었습니다. 
여러분은 지금까지 C/C++언어로 코딩에서 컴파일과 링크 과정을 거쳐서 실행 파일 생성과 실행까지의 과정을 모두 해보셨습니다. 

JDK / Eclipse 설치 (JAVA)

이번에는 JDK(Java Development Kit)와 IDE종류 중 하나인 Eclipse를 설치 해보겠습니다. JDK(Java Development Kit)는 쉽게 말해 JAVA의 응용 프로그램 개발을 위한 프로그램입니다. JDK는 JAVA 언어를 이용한 소스 파일을 컴파일 할 수 있는 컴파일러, 디버깅 툴 등으로 이루어져 구성되어 있습니다.
0. 설치환경 점검
JDK는 컴퓨터 환경에 따라 설치 파일이 다르므로 설치 전 컴퓨터의 (bit)를 확인해 보아야 합니다. Windows는 정보 처리의 속도에 따라 32bit와 64bit로 나뉩니다. 컴퓨터의 운영체제에 따라 알맞은 파일을 다운받아야 합니다. 운영체제는 다음과 같은 방식으로 확인할 수 있습니다. 실행창에서 dxdiag를 입력해 봅시다.
저의 컴퓨터는 64비트 인 것으로 나옵니다.  자신의 컴퓨터 정보를 보고 해당하는 비트에 맞는 JDK 버전을 다운로드 하시면 됩니다.  
1. 프로그램 다운받기
주소창에

를 입력합니다.
다운로드 탭에 마우스를 가져가면 좌측 상단에 있는 Popular Downloads 목록에 있는 JAVA for Developers를 클릭합니다.
화면 중앙에 있는 JDK DownLoad 버튼을 눌러서 다음 화면으로 넘어갑니다.
JAVA SE Development Kit 8u101 버전을 다운로드 하겠습니다. 이때 라이센스에 동의를 해야지 다운로드가 가능합니다. Accept License Agreement 에 체크를 하고, 아래쪽에 있는 windows x64버전을 클릭합니다. 
여기서 보시면 JAVA SE Development Kit 8u101 버전과 JAVA SE Development Kit 8u102 버전이 있습니다. 큰 차이는 없지만, 차이점을 아시고 싶으시면 각 버전의 release note를 읽어보시면 아실 수 있습니다.  
설치파일을 클릭하시면 아래쪽에 다음과 같은 팝업창이 뜹니다.
저장을 눌러서 실행파일을 다운로드 받으셔서 실행하셔도 되지만 저는 바로 실행 버튼을 눌러서  설치를 하겠습니다.                    
download.oracle.com 의 jdk-8u101-windows-x64.exe(193MB)을(를) 실행하거나 저장하시겠습니까?
프로그램 접근을 허용하는 창이 뜨면 예를 선택하시고 프로그램 설치 창이 뜨면 Next 버튼을 누르시면 됩니다.
Next 버튼을 누릅니다.
설치준비를 하고 있습니다.
설치할 공간을 설정해야 합니다. 원하시는 위치가 있으면 변경 버튼을 이용해서 위치를 지정하시면 됩니다. 저는 변경하지 않고, 디폴트로 잡혀있는 설치 위치에 바로 설치를 하도록 하겠습니다.
다음 버튼을 누릅니다.
설치가 진행중입니다.
Complete! 설치가 완료되었습니다. close 버튼을 누릅니다. 이로써 JAVA를 설치하였습니다.
이번에는 JAVA의 IDE 중 주로 쓰이는 Eclipse를 설치해보겠습니다.C/C++과 C#의 경우 Visual Studio라는 IDE를 사용합니다. 마찬가지로 JAVA 언어를 위한 개발툴(tool) 중 주로 쓰이는 IDE가 바로 Eclipse입니다.
1. 프로그램 다운받기
주소창에

를 입력합니다.
화면 우측 상단에 다운로드 버튼을 누릅니다.
다운로드 화면으로 넘어왔습니다. 자신의 운영체제가 Windows이고 64비트라면 바로 화면에 있는 DOWNLOAD 64 BIT 버튼을 누르면 됩니다. 
운영체제가 다르거나 64비트가 아니라면 버튼 밑에 있는 Download Package 글씨를 눌러서 자신에게 맞는 조건의 이클립스 버전을 받으시면 됩니다.  
DOWNLOAD 버튼을 클릭하면, 화면 하단에 다음과 같은 팝업 창이 뜨게 됩니다. 
ftp.jast.ac.jp의 eclipse-inst-win64.exe(44.7MB)을(를) 실행하거나 저장하시겠습니까? 
실행(R) 버튼을 클릭해서 설치를 합니다. 저장버튼을 눌러서 실행파일을 실행시키셔도 됩니다.
eclipse installer 화면으로 넘어왔습니다. 우리가 설치하고자 했던 Eclipse IDE for Java Developers를 선택해서 설치하도록 하겠습니다.
이클립스 설치 경로 설정 화면입니다. 설치를 원하시는 경로가 있으면 폴더
를 클릭해서 지정하시면 됩니다. 저는 기본으로 정해져 있는 경로 그대로 설치를 진행하도록 하겠습니다.
INSTALL 버튼을 클릭합니다.
설치가 끝났습니다.  LAUNCH 버튼을 누르면 프로그램이 실행이 됩니다.

Path 설정

앞선 C/C++ path 설정에 이어 이번에는 JAVA의 패스 설정을 해보겠습니다.  JAVA 컴파일 파일인 javac.exe 파일을 찾아보겠습니다
제 컴퓨터의 경우 C:\Program Files\Java\jdk1.8.0_101\bin  위치에 있는 것을 볼 수 있습니다. 이 폴더에 JAVA 컴파일에 관련된 파일들이 있는 것입니다. 보통 자신의 컴퓨터에 JAVA가 설치되면 C드라이브에 설치가 되지만, D나 E 혹은 F드라이브에 설치되어 있다면 위와 비슷한 경로를 설치된 드라이브에서 찾아서 넣어주시면 됩니다.  
자 그럼 지금부터 JAVA의 path 설정을 해 보도록 하겠습니다. path 설정 윈도우키와 Break 키를 눌러 봅시다. 좌측 고급 시스템 설정에 들어가면 여러 탭이 보입니다. 
고급 탭에서 환경 변수를 클릭합니다.
[시스템 변수]에서 PATH 를 찾아 더블클릭 합니다.
새로 만들기 버튼을 클릭해서 경로를 넣어주시면  path 설정이 끝납니다. 
이제 우리는 {자신의 드라이브}:\Program Files\Java\jdk1.8.0_101\bin에 있는 파일들을 어떤 곳 에서든지 사용할 수 있게 되었습니다. 
 JAVA 관련 서적이나 인터넷 검색을 해 보면, JAVA 환경변수에 있어서 classpath, 환경변수, java_home 추가 등의 부분을 볼수 있습니다. 

컴파일(Compile)/링크(Link) 

 이번에는 JAVA 
JVM  JRE

JAVA 프로그래밍 

JAVA 코딩부터 컴파일 과정까지 실습을 통해서 연습해보도록 하겠습니다. 
먼저 cmd 창을 열어서 코딩을 해보겠습니다. 이번에는 copy con 명령어로 실습을 해보겠습니다.
copy con Practice.java            
public class Practice {
  public static void main (String [] args){
       System.out.print("hello world");
 } 
}

Chapter3.포인터
모든 언어의 아버지 격인 C를 만든 데니스 리치 & 브라이언 커니핸의 저서는 “The C programming language” 입니다. 이 책의 차례에만 “pointer” 단어가 10번 이상 나옵니다.
그만큼 중요한 개념입니다. 다른 모든 언어를 이해할 때도 포인터가 가장 기초적 개념이 됩니다. 심지어 이기종의 언어인 JAVA도 해당 개념으로 이해할 수 있습니다.

기본개념

포인터를 만드는 키워드는 * (Asterisk, 애스터리스크) 이다. point는 “가리키다”는 뜻이며, pointer는 “가리키는 것” 입니다. 명확한 정의는 “메모리의 특정 주소를 가리키는 것” 입니다. [주소]를 가리키기에 보통 아파트 [주소]에 비유 합니다.
메모리 주소의 경우
0xb000001
로 표현하고
아파트 주소의 경우
수원시 영통구 영통로 154번길 자바아파트 108동 1004호
의 식으로 표현 합니다.
포인터와 아파트 주소의 다른 점이 있습니다. 포인터의 경우 아파트 평수도 고려를 해야 한다는 것입니다. 그리고 포인터 변수의 크기는 우편번호와 같이 고정 길이로 되어 있습니다.                    
printf("%d %d\n", sizeof(char), sizeof(char*));
printf("%d %d\n", sizeof(short), sizeof(short*));
printf("%d %d\n", sizeof(int), sizeof(int*));
printf("%d %d\n", sizeof(long), sizeof(long*));
printf("%d %d\n", sizeof(float), sizeof(float*));
printf("%d %d", sizeof(double), sizeof(double*));
백설표 설탕 마크(*)가 붙은 모든 변수는 32bit 컴파일 했을 때는 4byte, 64bit로 컴파일 했을 때는 8byte 입니다. 왜냐면 특정값을 말하는 것이 아니라 메모리 주소값을 말하기 때문입니다. 프리미티브 변수의 경우 변수 자체가 값을 의미합니다.                    
int s = 88;
int *o = &s;
printf("%d, %d, %d, %x, %d", s, o, &s, &o, *o);
포인터 변수 o 에 변수 s 의 메모리 주소값을 담고 있습니다. 즉 88=s=*o 입니다. &s = o 입니다. &o 의 경우 포인터 변수 o 자체의 주소를 말합니다. 메모리 특정 공간에 4byte, 64머신이라면 8byte의 공간을 차지하고 있습니다.
모든 프로그램은 메모리에서 실행이 되기 때문에 포인터는 그 이름 그대로 메모리의 모든 공간을 가리킬 수 있습니다. 다만, 얼마만큼의 공간을 가리키는지 정해줘야 합니다. int 형의 경우 int형 포인터로 선언해서 같은 공간을 가리킬 수 있습니다. char 형의 경우 char 포인터 변수를 이용해서 가리키면 됩니다. int와 long 형 모두 4byte 이므로 int형을 long 형 포인터로 가리켜도 관계 없습니다. 아파트 주소와는 다르게 아파트 평수도 함께 기입을 해 줘야 합니다. 즉,
int *s; 의 경우 *s 부분만 아파트 주소를 말합니다.
수원시 영통구 영통로 154번길 자바아파트 108동 1004호 (24평)
처럼 평수를 기입하는 것이 바로 *s의 앞부분 int 부분 입니다.
이처럼 int 형은 안다는 것은 메모리의 개념은 연속적인 것이라서 특정 부분까지 읽어야 한다는 뜻입니다. 예를 들어, “아버지방구” 를 메모리에 적재했을 때 다음과 같이 연속적 공간에 적재된다고 봅시다.
|아|버|지|가|방|구|
3글자를 읽으면 아버지가 되고
5글자를 읽으면 아버지가방이 되고
6글자를 읽으면 아버지가방구 가 됩니다.
읽는 크기에 따라서 얻을 수 있는 값이 달라진다는 뜻입니다.

포인터 연산자

포인터 관련 연산자는 단 두가지 입니다. & 의 경우 주소값을 말하며, *의 경우 값을 말합니다. 둘은 정반대의 개념입니다.                    
int s = 88;
printf("%d", *&*&*&*&*&*&*&*&*&*&*&s);
이와 같은 경우 printf 안에 &*...s 는 단순히 s를 적어 준 것과 같습니다.

리틀 엔디안, 빅 엔디안

CPU는 무조건 둘 중 하나의 바이트 오더를 가집니다. 옵션으로 선택을 할 수 도 있고, 처음부터 고정되어서 나오기도 합니다. 여기서 unit(단위)이 byte 단위라는 것이 가장 중요한 포인트 입니다. int 형 4바이트(혹은 8바이트)수를 char 형 포인터 변수로 읽는다면 앞 부분 혹은 뒷 부분의 일부분 밖에 읽을 수 없습니다. 앞 부분/뒷 부분의 방식은 CPU의 endian 방식에 따라 달라집니다. 빅 엔디안의 경우 우리가 생각하는 그대로의 모습입니다. 그러나 리틀 엔디언의 경우 그 반대 입니다.                    
int n = 0x11223344;
printf("%x\n", (char)n);
의 경우 44가 남습니다.
데스크톱 컴퓨터에서 가장 많이 쓰는 Intel CPU의 경우 리틀 엔디언 입니다. 0x 로 시작하는 16진수 숫자 하나의 경우 4비트를 표현할 수 있습니다. 8비트가 1바이트니 “44”라는 2개의 숫자가 나오는 것입니다.
포인터 변수의 경우 메모리의 주소 값을 가지고 있는 특수 목적 변수입니다.
p의 경우 가리키는 곳의 주소값을
&p의 경우 포인터 변수 자체의 주소값을
*p의 경우 가리키는 곳의 주소값의 실제 값을 가리킵니다.

다중 포인터

주소값을 대입할 때 다음과 같이 중첩해서 대입할 수 있습니다.                    
int s = 88;
int *o, **o2o, ***o2o2o, ****o2o2o2o, *****o2o2o2o2o, ******o2o2o2o2o2o;
o = &s;
o2o = &o;
o2o2o = &o2o;
o2o2o2o = &o2o2o;
o2o2o2o2o = &o2o2o2o;
o2o2o2o2o2o = &o2o2o2o2o;
printf("%d\n", ******o2o2o2o2o2o);

배열 포인터                    

int s[3][6] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
int (*o)[6] = s;
printf("%d ", o[1][1]);
배열 포인터라는 단어에서 앞부분은 “배열”, 뒷부분은 “포인터” 입니다. 복잡한 배열과 포인터의 해석에서는 뒷 단어만 보면 됩니다.. 배열 포인터는 포인터 입니다. 만약, 배열에 포인터에 포인터에 배열에 포인터의 배열이라고 하면… 가장 뒤에 배열이 있으니 “배열” 입니다.
배열 포인터는 배열을 가리키는 포인터 입니다. 가리킬 때 “아파트 평수”를 같이 말해줘야 합니다. 아파트 평수는 별로 선호하는 비유가 아니므로 이후부터는 “메모리 공간을 바라보는 크기”, 줄여서 “크기”라고 표현 하겠습니다. 배열의 크기가 6이므로 *o는 6개의 단위로 끊어서 메모리를 바라보게 됩니다. printf 값은 7이 나오게 됩니다.
그럼, 항상 이렇게 값을 알려줘야 할까요? “아버지가방구”처럼 마음대로 읽고 싶다면 그렇게 해도 됩니다.                    
int s[3][6] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
int **r = s;
printf("%d", *(int*)r+15);
이와 같이 대입 후 r 의 크기(메모리 공간을 바라보는 크기, 아파트 평수, 아버지방구)를 int 형으로 지정 후에 끊어서 읽으면 됩니다. 15번째 값이므로 15가 출력 됩니다.
printf("%d", *(int*)r+15); 는 다음과 같이 바꿀 수도 있습니다.                    
printf("%d", ((int*)r)[15]);
[] 는 +와 * 의 역할을 합니다.

포인터 배열                    

int s = 88;
int *o, **o2o, ***o2o2o, ****o2o2o2o, *****o2o2o2o2o, ******o2o2o2o2o2o;
o = &s;
o2o = &o;
o2o2o = &o2o;
o2o2o2o = &o2o2o;
o2o2o2o2o = &o2o2o2o;
o2o2o2o2o2o = &o2o2o2o2o;
printf("%d\n", ******o2o2o2o2o2o);
int *p[6] = { o, o2o, o2o2o, o2o2o2o, o2o2o2o2o, o2o2o2o2o2o };
printf("%d\n", s);
printf("%d\n", *p[0]);
printf("%d\n", *(int*)*p[1]);
printf("%d\n", *(int*)*(int*)*p[2]);
printf("%d\n", *(int*)*(int*)*(int*)*p[3]);
printf("%d\n", *(int*)*(int*)*(int*)*(int*)*p[4]);
printf("%d", *(int*)*(int*)*(int*)*(int*)*(int*)*p[5]);
위에서 설명한 것과 같이 “포인터 배열”의 뒷 부분만 읽으면 “배열” 입니다. 포인터를 담는 배열로 생각하면 되겠다. 포인터를 하나씩 꺼내어 참조했던 값들을 따라가서 모두 88이 출력되는 프로그램 입니다.

동적 할당                    

int *a = (int*)calloc(9, sizeof(int)); 
int y[8] = {0, 1, 2, 3, 4, 5, 6, 7};
for (int i = 0;i < 8;i++) {
 a[i] = y[i];
}
printf("%d\n", y[6]);
printf("%d\n", a[6]); 
y[6] = 88;
printf("%d\n", y[6]);
printf("%d\n", a[6]);
free(a);
a = y;
printf("%d", a[6]);
동적 할당은 메모리 공간 확보로 이해하면 됩니다. 성능이 크게 중요하지 않다면 malloc 보다 calloc를 사용하는 것을 권장 합니다.. 메모리 공간을 확보하고 배열을 이용하여 값을 복사합니다. 포인터 변수 a는 단지 확보된 메모리를 가리키는 변수일 뿐입니다. 메모리를 해제하고 a를 y가 가진 메모리를 가리키고 바뀐 값을 보여주는 예제 입니다.

함수 포인터

lvalue 는 변수를 중심으로 종류를 구분하며 일반 변수, 포인터, 함수, 배열 中 하나이다.
변수 우측에
아무것도 없다면 일반 변수, x는 일반 변수
*가 왼쪽에 있다면 포인터, *x는 포인터
( 로 시작하면 함수, x() 는 함수
[ 로 시작하면 배열, x[] 는 배열
) 로 닫혀 있으면 괄호()안이 우선된다.
*p[] 는 배열 이지만, (*p)[] 는 포인터, (*p[])(int, int) 는 배열이다.
이처럼 닫혀진 괄호, )에 따라 읽는 우선순위가 바뀐다.
Visual Studio 이용하여 코드로 배워보자. 
C++, Windows Console Application 을 생성한다.
#include "stdafx.h"
int main()
{
    return 0;
}
글자를 출력해 보자.
#include "stdafx.h" // 다음에 생략하자.
int main()
{
    printf("7");
    return 0;
}
변수를 써 보자.
int main()
{
    int value = 6; 
    printf("%d", value);
    return 0;
}
더하기 함수를 만들어 보자.
int Addition(int, int);
int main()
{
    int value = Addition(4, 2); //다음에 생략하자.
    printf("%d", value);
    return 0;
}
int Addition(int x, int y) {
    return x + y;
}
더하기 빼기 곱하기 나누기 함수를 만들어 보자.
int Addition(int, int);
int Subtraction(int, int);
int Multiplication(int, int);
int Division(int, int);
int main()
{
    printf("%d ", Addition(4, 2));
    printf("%d ", Subtraction(4, 2));
    printf("%d ", Multiplication(4, 2));
    printf("%d ", Division(4, 2));
    return 0;
}
int Addition(int x, int y) {
    return x + y;
}
int Subtraction(int x, int y) {
    return x - y;
}
int Multiplication(int x, int y) {
    return x * y;
}
int Division(int x, int y) {
    return x / y;
}
함수 포인터를 만들자.
int Addition(int, int);
int Subtraction(int, int);
int Multiplication(int, int);
int Division(int, int);
int main()
{
    int(*p)(int, int);
    p = Addition;
    printf("%d ", p(4, 2));
    printf("%d ", Subtraction(4, 2));
    printf("%d ", Multiplication(4, 2));
    printf("%d ", Division(4, 2));
    return 0;
}
int Addition(int x, int y) { //다음에 생략하자.
    return x + y;
}
int Subtraction(int x, int y) { //다음에 생략하자.
    return x - y;
}
int Multiplication(int x, int y) { //다음에 생략하자.
    return x * y;
}
int Division(int x, int y) { //다음에 생략하자.
    return x / y;
}
for 문을 돌리기 위해 함수 포인터 배열을 만들자. 
int main()
{
    int(*p[4])(int, int);
    p[0] = Addition;
    p[1] = Subtraction;
    p[2] = Multiplication;
    p[3] = Division;
    for (int i = 0; i<4; i++) printf("%d ", p[i](4, 2));
    return 0;
}
main() 도 함수다. main 우측에 ( 가 있기 때문이다.
int main()
{
    int(*p[4])(int, int);
    int(*pMain)(int);
    pMain = main;
    p[0] = Addition;
    p[1] = Subtraction;
    p[2] = Multiplication;
    p[3] = Division;
    for (int i = 0; i<4; i++) printf("%d ", p[i](4, 2));
    pMain();
    return 0;
}
main을 가리키는 함수 포인터를 생성해서 실행시켜 주었다. 이에 무한 루프가 된다.
팩토리얼 재귀 호출처럼 만들어 보자. main에 파라미터를 값을 주지 않으면 1이 할당된다.
int main(int mainParam)
{
    int(*p[4])(int, int);
    int(*pMain)(int);
    pMain = main;
    p[0] = Addition;
    p[1] = Subtraction;
    p[2] = Multiplication;
    p[3] = Division;
    for (int i = 0; i<4; i++) printf("%d ", p[i](4, 2));
    printf("\n"); //지저분해서 추가
    if (mainParam == 1) mainParam = 5; //초기값 할당
    if (mainParam == 2) return 0; //탈출 조건
    else pMain(--mainParam);
    return 1; //그냥
}
typedef 를 써보자.
typedef int(*_pMain)(int);
int main(int mainParam)
{
    _pMain pMain;
    int(*p[4])(int, int);
    pMain = main;
    p[0] = Addition;
    p[1] = Subtraction;
    p[2] = Multiplication;
    p[3] = Division;
    for (int i = 0; i<4; i++) printf("%d ", p[i](4, 2));
    printf("\n");
    if (mainParam == 1) mainParam = 5;
    if (mainParam == 2) return 0;
    else pMain(--mainParam);
    return 1;
}
만약, 함수포인터 _pMain이 파라미터라면?
int(*fp)(_pMain)
풀어쓰면,
int(*fp)(int(*)(int))
함수 포인터를 파라미터로 가지는 함수 포인터다. 복잡하다. 어렵다. 결론은 포인터라고 읽는다.
우측이 )로 닫혀 있어서 ()안을 먼저 해석하면 변수에 fp가 붙어서 포인터니까 말이다.
이것을 담는 배열을 만들고 싶다면
int(*fp[8])(int(*)(int))
처럼 만들면 된다. 함수 포인터를 파라미터로 가지는 함수 포인터 배열이다.
즉, 배열이다.
변수, 함수, 포인터, 배열은 구분할 줄 알아야 한다.
typedef가 class와 닮은 점이 조금이나마 보인다면, C/C++, JAVA를 연계해서 이해할 준비가 된 것이다.
부록                    
산술 연산 규칙



1.피연산자에double형이 있으면double형으로 연산이 수행
2.피연산자에float형이 있으면float형으로 연산이 수행
3.피연산자에long형이 있으면long형으로 연산이 수행
4.그 외에는int형으로 연산이 수행(int형보다 작은 형은 모두int형으로 변환)











연산자
사용 예
설명

#ERROR!
a += b
a = a + b

-=
a -= b
a = a - b

*=
a *= b
a = a * b

/=
a /= b
a = a / b

%=
a %= b
a = a % b

&=
a &= b
a = a & b

^=
a ^= b
a = a ^ b

!=
a |= b
a = a | b

<=
a <= b
a = a < b

>>=
a >>= b
a = a >> b

>>>=
a >>>= b
a = a >>> b





형 변환
사용 예
설 명

묵시적
int a = 10;
long b ;
b =a;
int형 변수a를long형 변수b에 넣는다. long형의 유효범위가int형보다 크기 때문에 자동적으로 형 변환이 일어나 대입된다

묵시적
long a = 10;
double b;
b = a;
long형 변수a를double형 변수b에 넣는다. double형의 유효범위가long형보다 크기 때문에 자동적으로 형변환이 일어나 대입된다.

명시적
long a = 10;
int b;
b = (int)a;
long형 변수a를int형 변수b에 넣는다. long형의 유효범위가int형보다 크기 때문에 명시적으로 형 변환을 해주어야 한다.

명시적
float a = 10.0f;
int b;
b = (int)a;
float형 변수a를int형 변수b에 넣는다. float형의 유효범위가int형보다 크기 때문에 명시적으로 형 변환을 해주어야 한다.





순 위
연산자
적용방향
사용예
1
. , [], ()
->
(a+b)
2
전치형++,--단항+, -
->
"++a, --b, +a, -b"
3
후치형++,--
<-
a++, b--
4
(형 변환 유형), new
<-
(int)a, new
5
*, /, %
->
a*b, a/b, a%b
6
#ERROR!
->
a+b, a-b
7
<<, >>, >>>
->
a<<2, a>>2, a>>>2
8
<, >, <=, >=,instaceof
->
a<b, a>b, a<=b, a>=b,객체instanceof객체의 형
9
#ERROR!
->
a==b, a!=b
10
&
->
a&b
11
^
->
a^b
12
|
->
a|b
13
&&
->
a&&b
14
||
->
a||b
15
?:
->
(a>b) ? a : b
16
#ERROR!
<-
a=10, a+=b




Wrapper(랩퍼)클래스



1.모든 기본 데이터 타입을 위한 랩퍼 클래스가 정의 되어있다.
2.랩퍼 클래스는 모두java.lang패키지에 포함되어 있기 때문에 명시적으로import하지 않고도 사용할 수 있음
3.모든 랩퍼 클래스는final제한자로 선언되어 있다.
4. Character를 제외한 모든 랩퍼 클래스는 인자로String를 받는 생성자가 정의







랩퍼 클래스
기본 데이터 형


Boolean
boolean


Character
char


Byte
byte


Short
short


Integer
int


Long
long


Float
float


Double
double










인터페이스
특 징
구현클래스

Set
요소의 정렬순서는 정해져 있지 않다.
요소는 중복될 수 없다.
AbstractSet, HashSet,
LinkedHashSet, TreeSet

List
요소는 인덱스로 정렬된다.
요소는 중복될 수 있다.
AbstractList, ArrayList,
LinkedList, Vector

Map
키와 요소로 관리된다.
키는 중복될 수 없다.
요소는 중복될 수 있다.
HashMap, TreeMap,
WeekHashMap, Hashtable





클래스
특 징


HashSet
집합의 요소들은 정렬되지 않는다.동기화 처리가 되어 있지 않다.


LinkedHashSet
집합의 요소들은 추가된 순서대로 정렬된다(insertion order).동기화 처리가 되어 있지 않다.


TreeSet
SortedSet interface로 구현된다.집합의 요소들이 오름차순으로 정렬됨.(ascending order, natural order).동기화 처리가 되어 있지 않다.






메소드명
매개변수
기 능

add()
Object o
지정된 요소가 집합에 존재하지 않는다면 추가

clear()
-
집합에 있는 모든 요소를 제거

contains()
Object o
집합에 지정된 요소가 있다면true를 리턴

equals()
Object o
지정된 객체가 이 집합과 동일한지를 비교

isEmpty()
-
집합에 어떤 요소도 추가되어 있지 않다면true를 리턴

remove()
Object o
지정된 요소가 존재한다면 제거

size()
-
집합의 요소의 수를 리턴

toArray()
-
집합에 있는 모든 요소를 배열로 리턴





사용 예
설명


a + b
a와b가 숫자라면 합,문자열이라면 문자 이어줌


a - b
a에서b를 뺀다


a * b
a에서b를 곱한다


a / b
a에서b를 나눈다


a % b
a를b로 나눈 후 나머지를 구한다


"+a"
a의 부호를 유지한다


"-b"
a의 부호를 바꾼다


개요를 적기 전에 지금까지 발견된 문제점을 알려 드립니다.
    비전공자를 위한 책인데 비전공자의 경우, 용어를 모르는 경우가 많습니다. 이에 되도록 이면 쉬운 용어로 설명을 해야 겠습니다. 어쩔 수 없이 IT 용어를 적어야 하는 경우 [각주]를 달아서 쉽게 설명을 해야 합니다.  
    IT 서적은 많지만 재미가 없다는 것이 이슈 입니다. 이에 책이 성공하기 위해서는 차별화된 포인트를 주어야 합니다. 쉽게 설명하면서도 집에 있는 컴퓨터로 바로 실행해 볼 수 있다는 것이 장점이어야 합니다. 이에 [쉘 스크립트 프로그래밍]이 바로 들어 갔습니다.  
    용어 설명이나 기타 설명을 곁들이면서 우선 바로 실행하면서 이것저것 설명을 한다면 읽는 입장에서는 재미가 있을 수 밖에 없습니다. 이런 시리즈로 [무작정 따라하기]라는 책이 한 때 크게 히트를 친 적이 있습니다. 해당 시리즈를 벤치마킹하고 기존 윈도우에서 쉘 스크립트 프로그래밍 서적은 없기 때문에 차별화 포인틀르 주었습니다.  
    다른 IT 서적을 읽는 징검다리 역할을 꼭 해야 하는 책 입니다. 이에 인터넷에서 설명하는 방식이 아니 더 자세한 방식으로 이해를 시켜야 하고 [비유]는 필 수 입니다. 이에, 특히나 [추상화]와 [API]의 개념은 IT 전공자도 쉽게 설명하지 못하는 두리 뭉실한 개념입니다.  
위의 주의 사항으로 나간다면 우선 초안들에서 보여지는 형식을 따라가시면 되겠습니다.
크게 보면 
    따라할 수 있는 쉘 스크립트 프로그래밍  
    추상화 API등 어려운 용어에 대한 쉽고 비유적인 설명들  
    Vislau Studio 와 Eclipse를 설치하고 HELLO WORLD를 IDE를 통하지 않고 직접 찍어보는 연습.  
    해당 연습이 되었을 때 컴파일과 링크에 대해서 설명하는 부분.  
    파일이 실행되면 메모리에 올라가서 프로세스가 되어서 윈도우 에서 해당 정보를 볼 수 있고 프로세스를 종료하면 프로그램이 죽는 이유와 용어에 대한 설명들…  
이런 부분들과 고해상도 스크린샷이 많이 들어 간다면 아마 300페이지는 나올 것 같습니다.
고맙습니다.
개요 관련해서 예전에 작업했던 라인의 개요를 붙여 넣어 봅니다.
〈가제 : 비전공자를 위한 프로그래밍〉
서론
책이 만들어진 계기 (C&JAVA가 함께 있는 책의 부재)
책의 내용 (목차를 풀어서 쓴다고 생각하자)
책이 지향하는 바 or 책을 읽은 후에 기대할 수 있는 효과
주의할 점
프로그래밍을 배우게 된 계기
프로그래밍을 공부하는 방법
자신감 주기 (……)
셸 프로그래밍
cmd 창
코딩
(추상화와 API)
단어장 1
프로그래밍
프로그래밍 언어 (C, C++ / JAVA)
코드
컴파일과 컴파일러 (개발툴) +Visual Studio 이야기
Visual Studio 설치
설치 방법 (스크린 샷)
PATH의 개념과 확인, 설정
C/C++ 프로그래밍
컴파일
단어장 2 (추가 예정)
JDK
 JDK 설치, 설치 방법
Eclipse
JDK, Eclipse

손코딩 & 발코딩

프로그래머 자신이 바라보는 개발이 어떤 것인지 구체적으로 다시 한번 생각하고 넘어가야 할 사색의 의무가  있습니다. 5년 이상 IT 전공자 대상으로 개인별 멘토링을 실시 했을 때, Self-test를 실시하고 나면 항상 하는 이야기가 책이나 인터넷에서 찾을 수 있는 내용이라고 합니다. 여러 대답을 해주었지만 가장 효과가 좋았던 사례를 들어 보겠습니다.  당신의 부모님께서 병에 걸려  수술을 해야 합니다. 그럼 제가 수술을 해도 되겠네요. 어차피 의학 지식이야 책이나 인터넷에서 찾을 수 있으니까요. 수술 후에 몸 속에 수술 기구가 들어 있어도 됩니다. 수술만 끝나면 되니까요. 프로그램도 실행만 되면 되니까요. 추가로 관련 의사 면허, 컴퓨터 자격증 등 여러 이야기를 한다는 것이 구차하기도 합니다. 최근 프로그래밍 분야는 전공자보다 비전공자를 더 선호하는 이유도 이와 같습니다. 처음부터 하나하나 다 이끌어줘서 가르치는 시간을 투자할 것이라면 비전공자의 학생들이 너 넓은 지식을 보유하기에 더 나은 퀄리티의 제품을 만들 수 있기 때문입니다. 특히나 IT 전공자 멘티의 경우 자신이 잘한다고 하던 80% 이상의 인원이 자신의 위치를 모르고 평가나 프로젝트를 거부하며 막연하게 무조건 이끌어 줄 것을 원합니다. 자신의 위치를 찾는 것이 중요합니다. 자격증을 따는 것도 상대방에게 마일스톤을 보여주는 좋은 예 입니다. 국내 리눅스마스터 자격증을 땄다고 하면 리눅스 시스템을 어느 정도 이해해도 bash shell 정도는 할 줄 알 것이라고 생각합니다.
1년 정도 공부하면 1시간 정도 세미나 분량이 나옵니다. 멘티와 10년 이상  경험 차이가 있는 멘토도 10 시간 이상 계속해서 세미나를 할 수 없습니다.  청중 중에는 겸손한 사람들도 많지만 한 시간 듣고 마치 모든 것이 자신의 것이 된 줄 착각하는 사람들이 많습니다. 엔지니어를 볼 때도 같은 분야에서 10년 경험이던 1년 경험이던 똑같은 말을 하면 똑같은 실력으로 보는 사람들이 많습니다. 그 과정에서의 수많은 트러블 슈팅 경험은 더 잘하는 개발자만이 보고 평가 할 수 있기 때문입니다.
대부분의 개발 방법은 Run & Fix 입니다. 블랙박스 테스팅을 한다고 거창하게 바꿔 말할 수 있겠지만 흔히 원시적인 개발 방법이라고 합니다. 다양화되고 지속적으로 진화하는 개발 방법론, 모든 것을 포괄하고 정형화된 프레임웍이 계속해서 나오고 있습니다. 그러나  Run&Fix는 사라지지 않고 또 앞으로 그럴 것 입니다. 한 사람이 모든 것을 알 수 없다는 원자력 발전소처럼 거대한 프로그램의 버그는 한 사람이 찾기 힘들 때도 있습니다. 하드웨어 문제로 발생할 수도 있기 때문입니다. 한 사람이 컴퓨터의 모든 하드웨어와 소프트웨어를 만들지 않는 이상 개개인의 역량과 소통의 문제 등도 전체를 파악하는데 힘든 장애물입니다.  최종 제품을 테스팅하여 버그를 발견하고 디버깅 하는 방법인 Run&Fix는 계속해서 사라지지 않을 것입니다.
Run&Fix 의 반대말은 무엇일까요? 하드웨어까지 고려한다면 상당히 어려운 질문 입니다. 그러나 생각 외로 쉬운 답이 나올 수 있습니다. 프로그래밍을 실행시킨 후 값을 알 수 있다는 뜻의 반대말을 찾으면 됩니다. 바로 “손코딩” 입니다. 컴파일러로 코드를 실행하기 전에 자신이 직접 컴파일러가 되어 보는 것이 ‘손코딩’ 입니다. 손코딩은 사람의 생명을 다루는 소프트웨어를 만드는 분야에서 필요합니다. 하드웨어, 컴파일러 및 프레임웍을 믿을 수 없는 파트에서 필요 합니다. 일반적으로 디버깅 단계에서는 다른 모든 파트는 문제가 없다고 믿어야 합니다. 자신이 짠 코드만 문제가 있다고 생각해야 버그를 빨리 잡을 수 있습니다. 사람의 생명을 다루는 소프트웨어 엔지니어의 경우는 그 반대 입니다. 모든 부분을 의심해야 합니다. 디버깅의 Entry Point는 자신의 소스가 되어야 합니다. 자신이 만든 소스 코드 만큼은 완벽하게 만들어 100% 신뢰할 수 있는 Base 파트를 만들어야 합니다. 그래야 다른 파트의 문제점까지도 의심해 볼 수 있습니다. 내가 만든 프로그램이 들어간 장비가 가족의 생명을 쥐고 있다고 생각하면 간단합니다. 왜 손코딩을 해야 하는지 쉽게 알 수 있습니다. 여러분이 많이 사용하는 휴대폰 플랫폼인 Android 는 Notification 관련 오류를 검출하지 못하는 버그가 있었습니다. 애플리케이션을 만드는 응용 프로그래머가 Notification Bar를 수없이 생산하면 휴대폰이 다운되어 버리는 현상이 있었습니다. 이런 경우 산에서 조난 당한 사람에게는 잘못 만들어진 애플리케이션이 사람의 생명을 위협하기도 합니다. 많은 사람들이 대단하게 생각하는 기업, 구글이라고 해도 애플과 경쟁하기 위해 오픈 방식을 선택할 수 밖에 없었습니다. 또 백만개가 넘는 애플리케이션을 일일이 검사할 수는 없습니다. 안드로이드 프레임웍도 구글이 최종 승인을 하지만 해당 부분을 캐치 못하는 버그는 고쳐지지 않고 제품 출시가 된 이력도 있습니다. 이에 관련된 증거는 스마트폰 사용자라면 쉽게 찾을 수 있습니다. 아무리 뛰어난 애플, 구글의 프레임웍이라 해도 재부팅, 먹통, 휴대폰이 다운되었던 경험은 누구나가 가지고 있습니다. reset, infinite loop, error 로 표현 할 수 있습니다.
비단 손코딩을 해야 할 프로그래머는 꼭 의료 계통 개발의 문제만은 아닐 것 입니다.
아이러니하게도 발코딩은 손코딩과 정반대의 개념은 아닙니다. 스파게티 코드와 유의어 입니다. 막 짠 코드를 말합니다. 어떤 경우던 for 문을 쓰지 않고 7번 적었다고 하면 대부분의 동료들이 발코딩 했다고 말할 것입니다. 애플리케이션만 만드는 프로그래머는 의아해하겠지만 점점 칩단(LOW LEVEL)로 내려가면서 프로그래밍을 하다 보면                     
for (int i = 0; i < 7; i++) dosomething(); 
 보다.                    
dosomething();
dosomething();
dosomething();
dosomething();
dosomething();
dosomething();
dosomething();
의 속도가 더 빠를 때가 있습니다. 프레임웍에서 매우 자주 사용하는 코드이므로 큰 성능 차이를 보이기도 합니다. 결국 컴파일러 최적화 옵션도 의심하고 컴파일러 자체, 운영체제나 프레임웍의 하부 구현, 심지어 하드웨어까지도 의심해봐야 하는 경우가 있습니다. 사람의 생명을 다루는 프로젝트라면 처음부터 끝까지 안정성을 의심해 봐야겠습니다. 그 외의 프로젝트에서는 손코딩 까지는 아니더라도 발코딩을 줄이려고 노력한다면 안정성 높은 코드를 생산할 수 있습니다.
발코딩을 하지 않는 최선의 방법은 ‘겸손’ 입니다. 자신이 모른다고 생각해야 하기에 계속해서 많은 시간을 투자해야 합니다. 그래서 개발자는 힘든 길을 걸을 수 밖에 없습니다. 밤샘 개발을 밤샘 연구로 생각하며 위로해야 합니다. 다만 그런 개발자 생활이 오래도록 지속되면 지치게 됩니다. 물론, 프로젝트를 완료하거나 제품을 출시하고 나면 ‘유레카’를 외칠 정도의 기쁨도 만끽합니다. 그런 창조의 기쁨은 길지 않습니다. 국가대표 선수들이 단상에서 받는 기쁨은 노력한 세월에 비하여 매우 짧은 시간인 것과 같습니다. 여러 프로그래밍 언어를 다루며 개발을 하다보면 언어 각각의 철학과 자존심까지 이해하게 됩니다. 그런 언어의 철학들도 제품을 생산하는 입장에서는 중요하지 않는 순간이 오게 됩니다. 포토샵을 잘 다룬다고 화가라고 하지 않는 것과 같습니다. 프로그래밍 언어도 툴에 지나지 않습니다.
한국말과 같은 언어가 세계에 수백 가지나 존재합니다. 언어의 본질은 소통입니다. 프로그래밍 언어도 마찬가지 입니다. 프로그래밍 언어의 본질은 CPU와 Memory 를 다루는 것입니다.
이 본질을 이해하는 방법은 간단합니다. 어셈블리어를 배우면 됩니다. 그러면 최종 컴파일된 기계어를 어셈블리어로 바꾸어 비교/설명하는 방식으로 모든 현상이 이해가 가능 합니다. 통상 고급 프로그래밍 언어부터 저급 프로그래밍 언어인 어셈블리어를 아는 프로그래머를 고급 프로그래머라고 합니다. 어셈블리어를 안다는 것은 해당 어셈블리어가 동작하는 시스템의 구조를 안다는 말이며, 운영체제 관련한 지식도 상당하다는 말입니다. 해당 방법이 가장 정석의 길이긴 하나 초/중급 프로그래머를 대상으로 설명하기 때문에 해당 방식으로 길을 알려드리지는 않습니다. 정석의 길로 공부할 수 있도록 나침반 역할을 하기 위해서 초/중급 프로그래머가 들었던 개념들과 용어로 설명을 하려고 합니다. 이 후 어셈블리어 언어를 공부하고 작은 운영체제 프로젝트를 진행하고 난 후에는 영화 매트릭스의 스미스 요원이 오라클의 눈을 얻었을 때와 같은 경험을 하게 될 것 입니다. 유레카!

책에서 표현하는 방법

벤 다이어 그램

Venn diagram - 고등학교 때 배운 그림이다. 이해를 돕기위해 이 책에서 대부분의 그림들을 Venn diagram으로 추상화 합니다.
Activity Diagram
Block Diagram
Class Diagram
Communication Diagram
Component Diagram
Composite Structure Diagram
Deployment Diagram
Interaction Overview Diagram
Object Diagram
Package Diagram
Profile Diagram
Sequence Diagram
State Machine Diagram
Timing Diagram
Use Case Diagram
기타...
이와 같은 방법으로 다음의 API는 “Hello, NEW World”를 화면에 출력하는 자바용 API, C용 API 입니다.  hnw.java 파일로 저장했다면 hnw.class로 변환해야 하며, hnw.c 파일로 저장했다면 hnw.out 혹은 hnw.exe 파일로 변환해야 합니다. 앞으로는 “API를 쓴다” 고 표현합니다.                    
System.out.println("Hello, NEW World");
printf("Hello NEW World");
이와 같이 CBD, 모듈, 프레임웍, SOA, EAI, PaaS, SaaS, DBaaS, IaaS  등도 추상화 과정을 거쳐 나온 API의 일종입니다. System.out.println('HELLO WORLD"): 을 쓸 때 화면에 점을 찍는 방법 ASCII CODE나 UNICODE, JVM 프레임웍을 거쳐 RAM에 저장된 내용이 CPU를 거치고 메인보드의 노스브릿지를 거쳐 그래픽 카드로 가고 GPU에서 여러 처리 과정을 거친 뒤 D-Sub, DVI, 혹은 HDMI 등을 거쳐 모니터로 표현되고 모니터에 H라는 글자를 찍을 때 점의 위치 조합과 색 표현 방법, 주사 방식, 주파수 등 다 몰라도 됩니다. System.out.print 가 화면에 찍는 API라는 것만 알면 되지요. 이것을 추상화 된 API라고 부릅니다.
또 간단히 API라고 부릅니다.
[추상화]와 [API] 우선 이렇게 짚고 이해를 하기 시작하면 많은 용어들에 대한 안개가 걷히게 됩니다. 깊게 들어 가다보면 여러 해석들이 나눠지지만 뿌리는 이렇습니다. 그래서 다음의 용어들도 모두 API로 추상화 합니다.                    
CBD, 모듈, 프레임웍, SOA, EAI, PaaS, SaaS, DBaaS, IaaS, COM, JSON, Cloud, AWS, Azure
컴파일 -
               저장된 것을 말한다.
LEVEL - 3
컴파일 - javac hnw.java
              gcc hnw.c
LEVEL - 1
CBD, SOA, EAI, PaaS, SaaS, DBaaS, IaaS - API의 일종이다.

추상화와 API

프로그래머는 자연의 법칙을 토대로 추상화 한 결과인 API로 프로그램을 만듭니다.
추상화는 抽象化, 뽑을 추, 꼴 또는 모양 상, 되게 할 화.입니다. 어떤 것에서 뽑아내는 방법을 말합니다. 
진짜 추상화입니다. 추상화가 잘되었습니다. 누가 봐도 사람이지요. 사실적 표현 양식과는 다르게 작가의 눈에 비친 인간의 내면 모습까지도 표현해 냈습니다. 
발전설비, 전기 설비, 집으로 오기까지 변압 과정들, 전등과의 배선에 대해서 전체를 모르더라도 스위치를 ON 하면 불을 켜고 OFF 하면 불을 끈다는 것을 알고 있습니다.
첫 번째 추상화와 두 번째 스위치. 모두 추상화 과정을 거쳐서 나온 결과물입니다.
이것을 API라고 합니다.
경험주의자
키워드 선택 0 / 3

댓글 없음:

댓글 쓰기

국정원의 댓글 공작을 지탄합니다.

UPBIT is a South Korean company, and people died of suicide cause of coin investment.

 UPBIT is a South Korean company, and people died of suicide cause of coin. The company helps the people who control the market price manipu...