본문 바로가기
반응형

컴퓨터/프로그래밍90

템플릿을 사용한 제네릭 프로그래밍, C++ <> 제네릭 프로그래밍(Generic Programming)이란 데이터 타입을 특정한 하나로 고정하지 않고 프로그램을 작성하는 것을 의미한다. 예를 들면, 함수의 인수와 내부 변수의 데이터 타입을 지정하지 않고 프로그램을 작성한 후 그 함수를 호출할 때 데이터 타입을 지정하는 것이다. 가장 대표적인 예가 C++의 template 이다. 다음과 같이 Swap 함수를 제네릭하게 작성하면 Swap 함수를 호출할 때 데이터 타입을 지정할 수 있다. 아래 코드에서는 데이터 타입을 int 형으로 사용하였고 short, long 등의 다른 데이터 타입으로도 호출 할 수 있다. template void Swap(T a, T b) { T temp = b; b = a; a = temp; } int i = 1, j = 2; Sw.. 2019. 11. 14.
auto, register, static, extern의 차이 auto는 함수 내의 지역변수를 나타낸다. 함수 내의 변수는 자동으로 지역변수로 정의되기 때문에 생략해도 된다. 즉 아래의 두 명령은 동일하다.int a;auto int a; register는 지역변수를 RAM이 아닌 CPU의 레지스터에 저장하도록 한다. 레지스터에 저장하면 실행 속도가 빨라진다.register int a; static은 지역변수와 전역변수에 사용할 수 있는데, 두 경우는 서로 다른 의미를 가진다. 지역변수에 static을 사용하면 함수를 빠져 나와도 static으로 정의된 변수의 값을 유지한다.전역변수에 static을 사용하면 다른 파일에서 extern으로 사용할 수 없도록 한다. 다른 파일에서 static 변수를 extern하면 컴파일 중 에러 메세지를 출력한다. extern은 다른 .. 2019. 11. 14.
malloc 함수 사용법 일반적인 변수들은 프로그램이 시작할 때 메모리를 할당하고 프로그램이 실행한 이후에는 변수 크기를 변경할 수 없다. malloc 함수는 프로그램 실행 중 운영체제로부터 메모리를 할당 받는 함수이다. 프로그램 실행 중 조건에 따라 원하는 크기의 변수를 생성할 수 있다. malloc 함수의 선언은 다음과 같다.void *malloc(size_t size)헤드 파일은 이다. malloc 함수를 사용하는 예는 다음과 같다. char *s; s = (char*)malloc(30); strcpy(s,"ABC"); printf("%s", s); free(s); malloc 함수를 사용하지 않는 다면 다음과 같이 사용해야 한다. char s[30]; strcpy(s,"ABC"); printf("%s", s); 2019. 9. 24.
Atom 프로그래밍 에디터 Atom은 GitHub에서 만든 프로그래밍 에디터이다. Git이 내장되어 있다. 다운로드: https://atom.io/ Atom은 CoffeeScript, JavaScript, Less, HTML, Electron으로 웹 기반으로 만들어졌다. 2014년에 개발되었다. 처음에는 IDE용으로 사용할 수 있었지만 현재는 에디터로만 사용할 수 있다. Atom의 장점 중 하나는 매우 많은 패키지가 있다는 것이다. 자신에게 필요한 기능의 패키지를 선택하여 설치할 수 있다. 탭 크기 탭 크기가 처음에는 2로 되어 있는데 File - Settings - Editor에서 탭 크기를 바꿀 수 있다. Soft Tab은 탭에 스페이스를 넣는 것이고 Hard Tab은 탭을 그대로 넣는 것이다. 함수 리스트 함수 리스트를 볼 .. 2019. 7. 3.
객체 지향의 블록 다이어그램 코드 상으로는 객체지향의 개념을 정확하게 이해하기 어렵고 이와 같은 코드를 블록 다이어그램으로 그리면 보다 쉽게 개념을 이해할 수 있다. C++ 코드를 블럭 다이어그램의 블럭으로 나타내면 다음 그림과 같다. 블럭 다이어그램은 여러 분야에서 많이 사용되는 직관적이고 익숙한 표현방법이다. C++의 한 객체를 나타내는 클래스가 블럭 다이어그램에서는 블럭이 된다. 여러개의 블럭으로 구성된 시스템에서는 각각의 블럭이클래스(객체)로 구성된다. 실제 객체 지향 프로그래밍 기법으로 프로그램을 설계할 때는 먼저 전체 시스템의 블럭 다이어그램을 설계하고 그 후 각각의 블럭을 설계한다. 이와 같이 함으로써 프로그램이 모듈화되고 팀에서 블럭별로 분업하여 프로그램을 각각 개발하고 나중에 합치기 수월하다. 소프트웨어 공학 기법을.. 2019. 4. 9.
Visual Studio Code에서 주석 색 변경하기 settings.json 파일을 열면 처음에 다음과 같이 되어있다. { "editor.fontSize": 12, "editor.minimap.enabled": false } 여기서, 다음과 같이 콤마를 붙이고 주석 색을 지정하는 명령을 입력하고 저장한다. 저자하면 바로 적용되어 색이 변한다. { "editor.fontSize": 12, "editor.minimap.enabled": false, "editor.tokenColorCustomizations":{ "comments": "#00FF00" } } settings.json은 다음 폴더에 있다. C:\Users\이름\AppData\Roaming\Code\User 위 폴더에서 직접 열어 편집해도 되고, 다음과 같은 Setting 화면의 Edit in s.. 2019. 4. 8.
프로그래밍 에디터 추천 프로그래밍 에디터 2019년 현재 프로그래밍 에디터 조사에서 많은 경우 Vim, Visual Studio Code, Sublime Text, Notepad++ 순서로 인기가 많다. 하지만, Vim은 처음 사용법을 배우기가 어렵고 Sublime Text는 유료이고 Visual Studio Code는 아직 문제가 많다. Notepad++는 사용하기 가장 쉽지만 안되는 기능이 너무 많다. 현재까지 사용했던 에디터 중 가장 좋은 것은 Atom이다. Atom은 사용하기 쉬우면서 수많은 플로그인을 사용할 수 있는 유연성을 가지고 있다. Vim은 기존 프로그램과 사용법이 너무 달라 익숙해지기가 어렵다. 키보드만을 사용할 때는 Vim이 좋지만 마우스와 함께 사용할 때는 Atom이 좋다. 가장 인기 있는 프로그래밍.. 2019. 4. 4.
시간 조건을 가지는 출력 신호 프로그래밍 다음 그림과 같이 시간 조건이 있는 신호들을 출력하고자 한다.위와 같은 신호를 출력하기 위한 객체는 다음과 같다.객체의 코드는 다음과 같다. if(Start==1) { // DO1 if(DO3_OFF_time >= T1-T2-T3) DO1 = 1; else DO1 = 0; // DO2 if(DO1_ON_time == T2) DO2 = 1; else if(DO1_ON_time < T2) DO2 = 0; else ERROR; // DO3 if(DO2_ON_time == T3) DO3 = 1, Fin = 1; else if(DO2_ON_time < T3) DO3 =0; else ERROR; } 2019. 3. 10.
컴퓨터 그래픽 공학 RGBA 알파 채널색을 나타낼 때 보통 RGB를 사용하지만 RGBA를 사용할 때도 있다. RGBA에서 A는 알파 채널(Alpha Channel)로 투명도를 나타낸다. 알파 채널의 값이 100%이면 투명하지 않는 일반적인 RGB를 나타내고 알파채널 값이 작아질 수록 투명해지며 0%가 되면 완전 투명하여 보이지 않게 된다. 베지어 곡선베지어 곡선 (Bézier curve)은 컴퓨터 그래픽 분야에서 곡선을 그릴 때 많이 사용하는 곡선의 방정식이다. Linear Bézier curve의 정의는 다음과 같다.Quadratic Bézier curve의 정의는 다음과 같다.Cubic Bézier curve의 정의는 다음과 같다. 2018. 11. 29.
Ada 언어 용도와 장단점 Ada (에이다)Ada는 1977-1983년에 미 국방성의 요구로 CII Honeywell Bull에서 만들어진 프로그래밍 언어 이다. 현재 버전인 Ada 2012은 ISO/IEC 8652:2012로 표준화 되었다. Ada는 모듈화, 런타임 검사, 병렬 처리, 메세지 처리, 예외 처리 등의 특성을 가지는 프로그래밍 언어이다. Ada는 안전이 매우 중요한 미사일 유도 장치, 우주선 항법 장치, 비행기 시스템, 인공 위성, 기차 제어, 은행 등에 사용된다. Hello World -- Ada Hello, World! program. with Text_IO; use Text_IO; procedure Hello is begin Put_Line("Hello, World!"); end Hello; 2018. 9. 22.
Lex와 Yacc Lex와 Yacc● Lex는 Lexical Analyzer (또는 Scanner 또는 Lexer) 프로그램을 만드는 프로그램이다. Lexical Analyzer에서는 Token 형태로 결과를 출력한다.● Yacc (Yet Another Compiler-Compiler)는 Parser 프로그램을 만드는 프로그램이다.● 프로그램을 만드는 프로그램이란 규칙을 입력하면 규칙에 따라 동작하는 프로그램 코드를 생성하는 것을 의미한다. 예를 들면 Lex에 어휘 규칙을 입력하면 규칙에 따라 어휘를 추출하는 Lexical Analyzer C 코드를 생성한다.● 보통 Lex는 Yacc와 함께 사용한다.● Flex는 Lex의 오픈 소스 버전이고 Bison은 Yacc의 GNU 버전이다. Lex와 Yacc 컴파일flex (또는.. 2018. 8. 26.
파이썬 입문 예제 파이썬 (Python)● 파이썬은 비단뱀이라는 뜻이다.● 파이썬은 1991년 개발된 인터프리터 방식의 프로그래밍 언어 이다.● 파이썬 2.0과 파이썬 3.0은 서로 호환이 되지 않고, 앞으로 파이썬 2.0의 지원은 중단된다.● 문장의 들여쓰기가 문법적 의미를 가진다. 공백이 의무 사항 이다.● 파이썬의 공식적인 철학Beautiful is better than ugly (예쁜 것이 좋다)Explicit is better than implicit (명시적인 것이 좋다)Simple is better than complex (단순한 것이 좋다)Complex is better than complicated (어려운 것보다 복잡한 것이 좋다)Readability counts (가독성이 중요하다)● 파이썬 프로그램을.. 2018. 8. 17.
Stack Overflow 에러 발생원인과 해결 Stack Overflow는 Stack 영역의 메모리가 지정된 범위를 넘어갈 때 발생한다. Stack 메모리는 보통 지역 변수가 저장되는 영역이다. 함수에서 지역 변수를 선언하면 지역 변수는 Stack 메모리에 할당되고 함수를 빠져 나오면 Stack 메모리에서 해제된다. 하나의 프로그램이 실행 될 때 수 많은 함수를 호출하고 빠져 나오게 되는데 그 때마다 함수에서 사용하는 지역 변수는 Stack 영역에 할당되고 해제되는 것을 반복하게 되며 그에 따라 사용되는 Stack 영역도 변하게 된다. 만약 한 함수에서 너무 큰 지역 변수를 선언하거나 함수를 재귀적으로 무한정 호출하게 되면 Stack Overflow가 발생할 수 있다. Stack Overflow가 발생하면 컴파일러 옵션에서 Stack 영역의 크기를 .. 2018. 7. 22.
폰트 C 소스 파일 생성 프로그램 리눅스나 윈도우 CE 등을 사용하는 임베디드 시스템에서는 폰트가 OS에 내장되어 있지만 성능이 낮은 MCU를 OS 없이 직접 사용할 때는 폰트를 직접 만들어야 한다. The Dot Factory는 폰트를 C 파일로 변환시켜주는 무료 프로그램이다 (MIT 라이센스). 생성된 C 파일의 배열 데이터를 LCD에 라이팅 하여 LCD에 글자를 표시할 수 있다. 옵션에서 폰트를 가변폭 또는 고정폭을 선택할 수 있다. 2018. 7. 9.
시리얼 프로그램 SerialTerm 2022 SerialTerm은 COM 포트를 통한 시리얼 통신 프로그램이다. 프로그램 다운로드 2018. 4. 13.
델파이 (Delphi) 델파이 (Dephi) 델파이는 처음 Borland에서 개발되었고 이후 Codegear에 매각되고 다시 Embarcadero에 매각 되었다. 버전 출시일 Borland Delphi 1995년 Borland Delphi 2 Borland Delphi 3 Borland Delphi 4 Borland Delphi 5 Borland Delphi 6 Borland Delphi 7 2002년 Borland Delphi 8 Borland Delphi 2005 Borland Delphi 2006 Codegear Delphi 2007 2007년 Codegear Delphi 2009 2009년 Embarcadero Delphi 2010 2009년 Embarcadero Delphi XE 2011년 Embarcadero Del.. 2018. 3. 29.
Hello World 프로그램 Hello World 프로그램은 단순히 Hello World 라는 메세지를 출력하는 프로그램으로 어떤 언어를 배울 때 가장 먼저 작성해 보는 프로그램이다. Hello World 프로그램을 실행시켰다는 것은 그 언어의 컴파일러를 설치하고 기본적인 설정을 마쳤다는 이야기이다. 경우에 따라 다르지만 어느정도 프로그래밍 언어를 아는 사람이라면 Hello World 프로그램을 실행했다면 거의 50%정도는 넘어섰다고 볼 수 있다. 특히, 마이크로 프로세서를 사용할 때 Hello World 프로그램을 처음 띄우기가 매우 어렵고 시간이 많이 걸리는 작업이다. 왜냐하면, 마이크로 프로세서 회로에서 버그가 없어야 하고 컴파일러 환경 꾸미기가 어렵기 때문이다. 실제로는 마이크로 프로세서를 사용할 때 LED 깜박이는 프로그램.. 2018. 3. 28.
Visual C++ 그레이 스케일 이미지 그리기 Visual Studio C++에서 SetDIBitsToDevice 또는 StretchDIBits을 사용하여 이미지를 표시할 때 기본적으로 RGB를 사용한 24비트 컬러로 표시되고 이미지 데이터도 24비트 컬러 정보를 가지고 있어야 한다. 8비트 컬러 정보를 가지고 있는 그레이 스케일 (Grayscale) 이미지를 표시하기 위해서는 파레트를 사용하여야 한다. 다음과 같이 BITMAPINFO에서 256개의 파레트 정보를 설정하고 SetDIBitsToDevice 또는 StretchDIBits에서 bitInfo를 사용하면 그레이 스케일 이미지가 표시된다. BITMAPINFO* bitInfo = (BITMAPINFO*)malloc(sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)); .. 2018. 3. 23.
Visual Studio 버전 Visual Studio 각 버전에서 업데이트를 적용하면 버전의 소수점 이하 숫자가 변한다. Visual Studio 이름 버전 Visual Studio 97 5.0 Visual Studio 6.0 6.0 Visual Studio.NET 2002 7.0 Visual Studio.NET 2003 7.1 Visual Studio 2005 8.0 Visual Studio 2008 9.0 Visual Studio 2010 10.0 Visual Studio 2012 11.0 Visual Studio 2013 12.0 Visual Studio 2015 14.0 Visual Studio 2017 15.0 2018. 3. 23.
OpenCV 3.4.1을 Visual Studio 2017 32비트 빌드 하는 방법 OpenCV 3.4.1은 윈도우용 Pre-build로 64비트만 제공한다. 32비트용은 직접 만들어야 한다. 빌드하는 자세한 방법은 여기에 설명되어 있는데 정리가 제대로 되어 있지 않다. 빌드하는 방법은 다음과 같다. 1. CMake을 여기에서 다운 받는다. Windows win64-x64 ZIP 또는 Windows win64-x86 ZIP을 다운 받는다. 2. OpenCV 소스를 여기에서 다운 받는다. 3.4.1에서 Sources를 클릭하면 다운 된다. 3. 다운 받은 CMake 폴더에서 cmake-gui.exe를 실행한다. 4. Browse Source 버턴을 눌려 다운 받은 OpenCV 소스 폴더를 선택하고, Browse Build를 눌려 빌드용 폴더을 만들고 그 폴더를 선택한다. 5. Config.. 2018. 3. 22.
OpenCV OpenCV OpenCV는 오픈 소스 컴퓨터 비전 (Computer Vision) 라이브러리이다. 1999년 인텔에서 처음 개발을 시작하였다. 2012년부터 OpenCV는 비영리 단체인 OpenCV.org에서 관리되고 있다. OpenCV 버전 차이 (2.4와 3.4의 차이) 현재 OpenCV는 2.x 버전과 3.x 버전 2가지가 있다. 과거에는 1.x 버전과 2.x 버전이 있었고 1.x은 C로 되어 있고 2.x는 C++로 되어 있었다. 1.x 버전은 현재 지원하지 않는다. 2014년에 처음 나온 3.x 버전은 2.x에서 기본 구조를 많이 변경한 버전으로 멀티쓰레드와 하드웨어 가속 등의 기능이 지원된다. 2.x과 3.x은 완전히 호환되지 않기 때문에 현재 2.x을 지원하고 있지만 앞으로 2.x 버전에서 3.. 2018. 3. 22.
RGB를 Grayscale로 변환하는 공식 OpenCV에서 RGB를 Grayscale로 변환하는 공식은 다음과 같다. RGB를 Grayscale로 변환할 때 RGB의 평균값이 아닌 가중치를 둔 값으로 변환해야 한다. 왜냐하면, 사람 눈에는 동일한 값을 가질 때 G가 가장 밝게 보이고 그 다음 R과 B가 밝게 보이기 때문이다. 위 식은 1982년에 제정된 ITU-R BT.601에 정의된 식이다. 1990년에 제정된 ITU-R BT.709에는 다음과 같이 정의하고 있다. Y = 0.299×R + 0.587×G + 0.114×B 과거의 1035i HDTV에서는 다음과 같이 정의하였다. Y = 0.212×R + 0.701×G + 0.087×B ☞ 인간 눈의 색 인식 민감도 2018. 3. 15.
HSV (색상, 채도, 명도) HSV (색상, 채도, 명도) 색을 RGB로 많이 표현하지만 색을 HSV (색상, 채도, 명도)는 나타낼 수도 있다. H (Hue) 색상: 빨강, 파랑, 노랑 등과 같은 색의 종류를 나타낸다. S (Saturation) 채도: 짙은 빨강, 옅은 빨강 등의 색의 진한 정도 V (Value) 명도: 밝은 빨강, 어두운 빨강 등과 같은 색의 밝기 아래 그림과 같이 색상(H)가 변할 때는 색의 종류가 바뀌고 채도(S)가 변할 때는 색의 진한 정도가 바뀌고 명도(V)가 변할 때는 색의 밝기가 바뀐다. RGB를 HSV로 변환하는 공식 OpenCV에서 RGB를 HSV로 변환하는 공식은 다음과 같다. 여기서, R,G,B는 0~1의 범위로 가진다. RGB가 0~255의 범위일 때는 255로 나누어준다. V와 S는 0~1.. 2018. 3. 15.
움짤 뜻 움짤은 움직이는 짤방의 줄임말이고 짤방은 사진의 인터넷 용어이다. 즉, 움짤은 움직이는 사진이라는 뜻이다. 움짤은 대부분 GIF 파일이다. GIF는 '지프'라고 발음하기도 하고 '기프'라고 발음하기도 하는데, 발음에 관해 인터넷에서 논쟁이 되기도 했다. GIF 파일 개발자는 '지프'로 발음해야 한다고 했다. GIF(Graphics Interchange Format) 파일은 1987년 CompuServ라는 회사에서 처음 만들었고 그 후 몇번의 업그레이드가 있었다. GIF 파일은 한 파일내에 여러장의 사진을 저장하여 순차적으로 보여 줄수 있어서 움직이는 사진처럼 보이는 것이다. GIF 파일은 트루 컬러 파레트를 사용하고 한 번에 256 컬러만을 표현할 수 있다. 파레트를 사용한다는 말은 24비트 트루 컬러 .. 2018. 3. 15.
인텔 CPU 보안 버그 멜트다운 인텔 CPU에서 발견된 보안 버그인 멜트다운 (Meltdown)를 이해하기 위해서는 CPU가 동작하는 방법을 이해해야 한다. CPU는 기본적으로 한 번에 하나의 명령어를 실행한다. 첫 번째 명령어를 실행한 후 다음 명령어를 순차적으로 실행한다. 하지만, CPU 내부에서는 빠른 실행을 위해 뒤에 오는 명령어도 미리 분석하고 실행 결과를 캐쉬에 올려 둔다. 그리고, 자기 차례가 오면 캐쉬의 데이터로 빠르게 실행한다. 만약, 일반 사용자가 커널 메모리의 데이터를 읽는 명령어를 실행한다면 CPU는 일반 사용자는 권한이 없기 때문에 그 명령어를 실행하지 않는다. 하지만, 그 명령어가 실행이 되지는 않지만 그 명령어의 결과는 이미 캐쉬에 들어있다. 캐쉬에 들어 있는 데이터는 직접적으로 알 수는 없지만 데이터를 읽는.. 2018. 1. 7.
버블 정렬 알고리즘 버블 정렬(Bubble Sort)은 가장 단순한 정렬 알고리즘으로 최소 n 번, 평균 n2, 최대 n2의 비교를 수행해야 한다. Sinking Sort라고도 한다. 버블 정렬 알고리즘은 다음과 같다. while(1) { flag = false; for(i=1; iA[i]) { swap(&A[i-1],&A[i]); flag = true; } } if(flag==false) break; } 5,3,4,1,2을 1,2,3,4,5로 정렬하는 과정은 다음과 같다. 2016. 5. 23.
대칭키 암호와 공개키 암호 차이 암호(Encryption)는 크게 대칭형 암호 (또는 대칭키 암호)와 비대칭형 암호 (공개키 암호)로 나눌 수 있다. 많이 사용되는 RSA 암호는 공개키 암호 방식이다. 공개키 암호의 기본적인 개념을 이해하는 것이 처음에는 조금 어렵다. 암호 이론에서 기본적인 전제는 모든 통신 내용은 도청이 된다고 가정하는 것이다. 암호는 통신이 도청이 되었을 때 메세지를 보호하는 것이 목적이다. 1) 대칭키 암호 대칭키(Symmetric Key) 암호는 비밀키 1개로 암호화와 복호화를 모두 하는 것으로 다음 그림과 같이 메세지를 보낸다. 1. A는 B에게 비밀키를 전달한다. 2. A는 그 비밀키를 사용하여 평문을 암호화하여 암호문을 만든다. 3. A는 암호문을 B에게 전달한다. 4. B는 A에게서 받은 암호문을 비밀키.. 2016. 3. 25.
오토마타 이론 오토마타 이론(Automata Theory)은 계산 기능이 있는 추상 기계와 이 기계를 이용하여 풀 수 있는 문제를 연구하는 분야이다. 이 계산을 할 수 있는 추상 기계를 오토마톤 (Automaton)이라고 한다. 오토마타는 오토마톤의 복수형이다. 즉, 컴퓨터를 추상화한 모델을 오토마톤이라고 볼 수 있다. 오토마타 이론은 컴퓨터 과학과 이산 수학의 한 분야이다. 2016. 2. 28.
UltraEdit 프로그래머를 위한 UltraEdit 설정 방법 - 일반설정 울트라에디트(UltraEdit)은 매우 많은 기능이 있고 그에 따라 설정하는 것도 매우 많다. 할때마다 설정하는 메뉴가 어디에 있는지 항상 잊어버린다. 그래서, 프로그램 작성할 때 필요한 설정을 정리해 보았다. UltraEdit의 버전은 14.20이다. Configuration 윈도우는 Advanced 메뉴에 있다. Backup 파일 생성하지 않게 하기 Tab 크기 설정하기 Tab Stop value를 4로 설정할 것을 추천한다. UltraEdit을 복수 창에서 열기 또는 1개 창에서 열기 Allow multiple instances를 체크 또는 해제한다. 이것은 상황에 따라 사용하면 된다. 글자색 설정 배경색, 라인 컬러링 설정 메뉴의 View.. 2016. 2. 20.
MSX BASIC 프로그램 MSX 컴퓨터는 처음의 MSX에서 MSX2, MSX2+, MSX TurboR까지 출시 되었다. 대우에서 만든 MSX2 호환 컴퓨터 IQ-2000은 한글이 내장되어 있다. MSX에는 기본적으로 BASIC이 설치되어 있고 처음 실행하면 자동으로 BASIC이 실행된다. MSX의 BASIC과 MSX-DOS는 빌게이츠의 마이크로 소프트가 만들었다. MSX는 BASIC이 내장되어 있어 전원을 켜면 바로 실행할 수 있다. 대화형 프로그래밍 언어로 현재의 Visual Studio와 같은 컴파일러와는 다른 색다른 매력이 있다. MSX BAISIC 프로그램하는 방식은 매우 특이하다. 마치 컴퓨터와 대화를 하듯이 사용한다. 2016. 2. 17.
반응형