diff --git a/README.md b/README.md
index 8e25079f196e1d1c5a67191748b773f2ec918e57..7389120482a3e8864370dd2b6891b670b5c58888 100644
--- a/README.md
+++ b/README.md
@@ -226,3 +226,735 @@
    * ex) cat hello.c hello.cpp 1> out.txt 2> err.txt  (에러를 저장하려면 2>을 사용해야함.)
       
    * '>>': 명령의 결과를 파일에 추가. (기존의 것들이 삭제되지 않음.)
+
+## Lecture 03
+
+### Linux command
+
+1. which  
+   * 파일의 위치를 출력하는 명령어.
+1. grep
+   * 입력으로 전달된 파일의 내용에서 특정 문자열을 찾고자할 때 사용하는 명령어.
+1. tee
+   *  입력한 내용을 화면에 출력하는 동시에 파일에 저장 해주는 명령어. stdin을 받아서 stdout과 하나 이상의 파일에 그 입력을 출력.
+
+ ```
+ cp ~hwan/.profile ~hwan/.bashrc ~hwan/.bash_logout ~
+ source .profile
+ ```
+ 교수님 코드를 카피하여 프롬프트가 초록색이 됨. 또한 path에 .이 추가되어 a.out만 입력해도 실행됨.
+
+
+### md 사용법
+* 제목: #
+* 부제목 : ## -> 6개까지 사용 가능. 
+* *은 리스트를 만들 때 유용, Tab을 써서 구분
+* br을 통해 줄 구분.
+* 1.을 통해 번호를 매길 수 있으며, 1만 써도 자동으로 번호가 카운트. tab을 하면 다른 리스트로 분류되어 숫자가 리카운트.
+* 순수하게 1.을 쓰고 싶다면 1\. 라고 입력하면 됨.
+* ** ** 사이에 글자를 넣으면 bold, * * 사이에 넣으면 이태리체
+* 글자 끝에 #을 넣어 줄 구분.
+
+### git command
+* git clone https://git.ajou.ac.kr/Hyeonuk/pcc000.git
+   * 해당 git 사이트에 있는 소스코드를 복제하여 내 컴퓨터에 가져옴.
+* git pull
+   * 수정된 소스를 저장소로부터 가져오는 명령어.
+* git add
+   * 작업 디렉토리(working directory) 상의 변경 내용을 스테이징 영역(staging area)에 추가하기 위해서 사용.<br>다음 변경(commit)을 기록할 때까지
+     변경분을 모아놓기 위해서 사용.
+* git commit -m ""
+   * commit은 파일 및 폴더의 추가/변경 사항들에 대해 기록을 하는 것, 작업공간 안에 있는 모든 파일과 파일의 데이터를 사진 찍듯이 복사해서 저장소에 보존.  
+   즉, 커밋은 작업공간의 어떤 시점의 스냅샷.
+   * -m을 통해 editor 실행X.
+   * "" 사이에 말을 추가 가능.
+* git config
+   * 원격 저장소로 데이터를 넘길때 커밋한 사람이 누구며, 어떠한 사람인지 남길 필요가 있다. 이런 인증에 대한 부분을 git config 명령어로 설정.
+* git push
+   * 현재 프로젝트의 커밋된(HEAD) 내용을 원격 저장소로 내보내는 명령어입니다.
+* git mv
+   * git에 있는 파일의 이름을 바꾸는 명령어.
+* git rm
+   * 로컬 디렉토리와 git 저장소 모두에서 파일을 삭제.
+
+
+### fork, branch 차이점
+* fork는 다른 사람의 Github repository에서 내가 어떤 부분을 수정하거나 추가 기능을 넣고 싶을 때 해당 respository를 내 Github repository로 그대로 복제하는 기능이다. <br>
+즉 Repository에 권한이 없는 사용자가 저장소를 fork하고 fork한 자신의 저장소에 변경 사항을 적용한 후 Push한다. 이 후 원래 저장소(original repository)에 내 저장소에 있는 브랜치를 Pull Request 한다. 내가 만든 코드가 ok되면 해당 저장소에 Merge 된다. <br>
+-> 또 다른 프로젝트를 만들 때 사용.
+* 은 특정 repository를 내 local machine에 복사하여 새로운 저장소를 만든다. clone한 원본 repository를 remote 저장소 origin으로 가지고 있다. 권한이 없는 경우 해당 저장소로 push 하지 못한다. <br>
+->소규모 팀에서 활용 가능한 예, 프로젝트를 수정할 때 사용.
+
+## Lecture 04
+
+### understanding redirection 
+* Basic
+    * < = 0<, << = 0<<, > = 1>, >> = 1>>, 2> = 2>>
+    * &>, 2>&1, &>>
+    * <<<
+* Position of redirection
+    * echo hello > /tmp/out - hello를 tmp/out에 저장. <br>
+      = echo > /tmp/out hello <br>
+    * echo hell0 >&2 - stdout, stderr 둘다 내보낸다. <br>
+      = echo >&2 hello
+    * read -r line < file - file의 한 줄을 읽는다. <br>
+      = < file read -r line
+* 단축코드
+    * mycomn > outfile 2>&1 을 줄여서 mycomn &> outfile
+    * mycomn >> outfile 2>&1 을 줄여서 mycomn &>> outfile
+    * mycomn1 2>&1 | mycomm2 을 줄여서 mycomm1 |& mycomm2
+    * https://mug896.github.io/bash-shell/redirections.html
+### Here document, Here String
+* 0<<, <<
+    *  임시 파일을 만들어 stdin으로 연결. <br>
+    ```
+    $cat << EOF
+    > "200"
+    > EOF
+    "200"
+    ```
+* <<< (bash only)
+    * string을 stdin 입력으로 연결.
+    ```
+    $ cat <<< *
+    *
+    ```
+### Pipe Order of execution
+* 실행의 순서는?
+    * $ cmd1 | cmd2
+        * cmd1과 cmd2는 동시에 병렬로 실행된다.
+        * cmd1이 cmd2보다 빠르면 파이프에 write은 블록되고 더 이상 진행되지 않는다.
+        * cmd2가 cmd1 보다 빠르면 파이프로부터의 read는 블록된다.
+        * cmd1이 먼저 종료하면 파이프는 close 되고 cmd2는 End-Of-File 로 인식해 종료한다.
+        * cmd2가 먼저 종료하면 파이프는 close 되고 cmd1은 다음번 write에 SIGPIPE 신호를 받게되고 종료된다.
+### Named pipe
+* pipe는 자동으로 생성/소멸
+* Named pipe
+    * mkfifo 명령으로 생성 - 파일처럼 생성됨.
+    * redirection으로 sending
+* 읽는 상대편이 없으면 Block 된다.
+* Buffer Control이 필요.
+
+### linux command
+* ????*
+    * 이름이 4글자 이상인 파일들을 모두 보여주는 명령어.
+* echo [abc]*
+    * 이름이 a, b, c로 시작하는 파일들을 모두 보여주는 명령어.
+* echo [a-q]*
+    * 알파벳 사전순으로 a~q까지의 알파벳으로 시작되는 파일을 모두 보여주는 명령어.
+
+### Type Basic
+*Standard signed integer type
+    * signed char, short int, int, long int, long long int
+* Unsigned
+    * Unsigned ...
+* floating type
+    * flout, double, (long double)
+* Definition in standard
+    * char - large enough to store any execution character set.
+    * floating - The set of values of the type float is a subset of the set of values of the type double; 
+      the set of values of the type double is a subset of the set of values of the type long double.
+    * _complex
+    * _Bool - can store 0, 1
+
+### Negative integer
+* 3 Well know methods to represent signed integer
+    * the corresponding value with sign bit 0 is negated (sign and magnitude);
+    * the sign bit has the value - (2M)(two's complement);
+    * the sign bit has the value (2M-1)(one's complement).
+* Which method is used in C Language?
+    * All three are possible.
+    * 근데 대부분은 2's complement를 사용.
+    * 2'complement
+        * 1의 보수(~)를 구한 후, 가장 낮은 비트에 +1
+     
+### Unsigned int
+* un-sign-ed 라는 것은 결국 "부호가 없다"는 뜻이고, 그래서 항상 플러스 값만 가짐.
+* %u를 통해 출력.
+
+### 시프트 연산
+* '>>': /2
+* '<<': *2
+
+### signed int 와 unsigned int에서 시프트 연산의 차이
+```
+int in_a, in_b;
+fscanf(stdint, "%d", &in_a);
+in_b = in_a >> 2;
+```
+signed int의 경우 a에 음수 값을 넣고 오른쪽으로 두칸 이동할 때 남는 공간에 1이 채워진다. 양수 값일 경우 0이 채워짐.
+```
+unsigned int in_a, in_b;
+fscanf(stdint, "%d", &in_a);
+in_b = in_a >> 2;
+```
+unsigned int의 경우 a에 음수 값을 넣고 오른쪽으로 두 칸 이동할 때 남는 공간에 0이 채워짐. 양수 값일 경우 1이 채워짐.
+
+나누기 연산에서도 마찬가지이다. 
+
+## Lecture 5
+
+### Linux command 
+
+1. more
+   * 파일을 화면 단위로 출력해주는 명령어. 
+   * Enter : 다음 한 줄 출력 
+   * Space Bar or z : 다음 한 페이지 출력 
+   * q,Q : 종료 
+1. less 
+   * 파일 내용을 페이지 단위로 보여주는 명령어.
+   * more 명령어의 기능을 줄인 명령어. 
+
+### signed와 unsigned의 fscanf 입력
+```
+#include <stdio.h>
+int main()
+{
+    signed int siA;   
+   unsigned int unA;
+   signed int sumS;
+   unsigned int sumU;
+
+   fscanf(stdin, "%d", &siA);
+   fprintf(stdout, "Signed Inteager : %d\n", siA);
+   unA = siA;
+   fprintf(stdout, "Unsigned Inteager : %u\n", unA);
+   fprintf(stdout, "Unsigned Inteager percent d : %d\n", unA);
+   fprintf(stdout, "Signed Inteager percent d : %u\n", siA);
+
+    sumS = siA + unA;
+    sumU = siA + unA;
+   fprintf(stdout, "sumS %%d %d\n", sumS);   
+   fprintf(stdout, "sumS %%u %u\n", sumS);   
+   fprintf(stdout, "sumS %%d %d\n", sumU);   
+   fprintf(stdout, "sumS %%u %u\n", sumU);
+```
+![lec05_1](./Image/lec05_1.jpg)
+![lec05_2](./Image/lec05_2.jpg) <br>
+위 사진은 코드를 실행하고 100, -100을 넣은 결과이다.
+unsigned int로 선언했더라도 출력시 %d로 받는다면 signed 형태로 받아서 나온다. 그래서 -100을 넣어도 -200이라는 sumS, sumU 출력값이 나온다.<br>
+![lec05_3](../Image/lec05_3.jpg)<br>
+위 사진은 코드를 실행하고 4294967200을 넣은 결과이다. <br>
+근데 결과를 보면 Signed int가 -96이 나온 것을 볼 수 있다. 오버플로우가 일어나지 않은 이유가 무엇일까? 
+우선 4294967200이 2진수로 변환하면 11111111111111111111111110100000이 된다. 그리고 scanf에 %d가 들어가면 내부적으로 strtol이 호출되는데, 
+이것은 변환대상이 최대값을 넘어갈 경우 long_max(0x7fffffff)을 반환한다. fscanf도 마찬가지로 내부에서 strtol 함수를 호출해서 
+오버플로우 현상이 일어나 입력값을 2147483647로 구겨넣는다. 하지만 64 bit os의 최대값은 0x7fffffffffffffff임으로 오버플로우가 일어나지 않는다. 
+그러므로 2진수로 변환된 11111111111111111111111110100000이 그대로 들어간다. 이 숫자는 96의 2의 보수이다.  <br>
+반면 unsigned int는 정상 출력이 되는 것을 확인 할 수 있는데 이는 unsigned int의 범위가 0~4294967295까지이기 때문이다.
+
+### Count number of 1 (binary)
+```
+#include <stdio.h>
+
+//Count number of 1 (binary)
+int count_one(int in_a)
+{
+        int i, count = 0;
+        for(i = 31; i>=0; i--)
+        {
+                if((in_a>>i) & 1)
+                        count++;
+                count += (in_a>>i)&1; 
+        }
+        return count;
+}
+
+int main()
+{
+        int i;
+        unsigned int in_a;
+        fscanf(stdin, "%u", &in_a);
+        fprintf(stdout, "%u \t: ", in_a);
+        for(i=31; i>=0; i--)
+        {
+                fprintf(stdout, "%d", ((in_a>>i) & 1));
+                if(i % 4==0)
+                {
+                        fprintf(stdout, " ");
+                }
+        }
+        fprintf(stdout,": %d \n", count_one(in_a));
+}
+```
+
+하지만 코드를 좀 더 빠르게 하기 위해
+```
+int count_one(int in_a)
+{
+        int i=32, count = 0;
+        while (i>0)
+        {    
+            count += (in_a>>i) & 1;
+            i--;
+        } 
+        return count;
+}
+```
+위 사진과 같이 함수를 수정하여 나타낼 수 있다. if문은 operation이 오래걸리기 때문이다. 
+
+![lec05_4](./Image/lec05_4.jpg) <br>
+사진과 같이 10과 -1을 넣었을 때 결과값을 확인할 수 있다. 이때 -1을 넣었을 때는 in_a의 출력값이 4294967295가 나오는 이유는 
+in_a가 unsigned int로 선언되어있기에 -1의 2진수가 그대로 들어갔고 이것이 오버플로우 없이 그대로 출력되었기 때문이다.
+
+### The basic memory model in C 
+* automatic variable (자동변수)
+    * Declare a variable on first unsigned
+    * remove when it goes out of scope.
+#     
+* static variable (정적변수)
+    * exit in the same place throughout the life of the program.
+    * Array sizes are fixed at startup, but values can change
+    * Data is initialized before main starts, -and thus any initializations have to be done with constants that require no calculations.
+    * Variables declared outside of functions (in file scope) and inside functions with the static keyword are static.
+    * If you forget to initialize a static variable, it is initialized to all zeros (or NULL). 
+#
+* Manual 
+    * The manual type involves malloc and free, only type of memory where arrays can be resized after declaration.
+#    
+* const
+    * constant의 약자로 "변함없는" 이란 뜻으로 변수 앞에 붙이면 값을 변경하지 못하도록 하며, 해당 변수를 상수로 취급하게 된다.
+
+## Lecture 06
+
+### Linux command
+* clear
+    * 터미널의 텍스트 화면을 깨끗이 지우는 명령어
+* alias
+    * 자주 사용하는 명령어를 특정 문자로 입력해두고 간편하게 사용하기 위한 것으로 command alias라고 한다. 복잡한 명령어와 옵션을 짧은 문자열로 바꿔주는 명령어
+    * alias -p를 통해 확인 가능.
+    * unalias를 통해 해제 할 수 있다. unalias -a은 모든 alias 설정을 삭제.
+    * alias 설정한 것을 사용하고 싶지 않을 때는 \ls 처럼 \를 붙여 사용.
+* cc && a.out
+    * 컴파일 후 에러가 없을 경우 a.out을 실행하는 명령어.
+* cc ; a.out
+    * 컴파일 후 a.out을 실행하는 명령어. 이때 컴파일 에러가 발생하면 가장 최근에 컴파일 성공한 a.out의 결과를 출력. 
+* cc || echo "Errrr"
+    * 컴파일 에러가 날 경우 echo의 결과를 출력해주는 명령어.
+
+### Pointer Basic
+* &val - val의 주소.
+    * %lld로 받음.
+* *ptr - val 주소의 값.
+    * *&a는 a가 가리키는 주소의 값.
+
+
+* increment
+    * int *a;      // a++ increment by 4
+    * long long *b      // b++ increment by 8
+    * void *c      // c++ increment by 1
+
+
+### int an_array[ ] vs int *a_pointer 
+* int an_anrray[32]; (int로 저장되서 4 byte, an_array 자체는 8byte 공간에 저장.)
+    * Program will do;
+    * set aside a space on the stack big enough for 32 integers, 
+    * declare that an_array is a pointer, and
+    * bind that pointer to point to the newly allocated space.
+* int *a_pointer;
+    * Just pointer;
+    * a_pointer = malloc(32*4);
+
+```
+#include <stdio.h>
+
+void add(int *a, int *b, int *c)
+{
+        *c = *a + *b;
+}
+
+int main()
+{
+        const int a = 100;
+        int b = 200;
+        const int c = 999;
+
+        fprintf(stdout, "%d : %lld\n", a, &a);
+        fprintf(stdout, "%d : %lld\n", b, &b);
+        add(&a,&b,&c); //2
+//      c = a+b; //1
+        fprintf(stdout, "%d : %lld\n", c, &c);
+        int d=999;
+        fprintf(stdout, "%d :%lld  %lld\n", d, ((void *)(&d))+1, &d+1); // 3
+                }
+
+```
+위 코드의 경우 c를 1번과 같이 구할 경우와 2번으로 구하는 경우가 다르다. add함수로 갈 경우 c의 주소의 값을 수정하는 것이기 때문에 오류가 발생하지 않지만 1처럼 그냥 수정하려고 한다면 const int이기 때문에 오류가 발생한다. 3의 fprintf에서 자료형을 int에서 void로 바꾸어주는데 이 때문에 메모리 크기가 4에서 1로 바뀌고 &c+1 은 메모리 주소가 int와 다르게 1만 증가하게 된다.<br>
+또한 add 함수에서 *b = *(a+1) 와 같이 나타낼 수 있는 것은 이것들이 메모리 주소 형태로 들어왔기 때문에 가능하다.
+
+```
+#include <stdio.h>
+
+int sumArray3(int a[3], int sum)
+{
+        sum = *a;
+        a++;
+        sum += *a;
+        a++;
+        sum += *a;
+        fprintf(stdout, "%d : %lld %llx\n", sum, &sum, &sum);
+        return a[3];
+}
+
+int main()
+{
+        int a=100;
+        int b = 200;
+        int c = 999;
+        int arr[4] = {100,200,300,400};
+        int *parr;
+        parr = arr;
+        parr++;
+        fprintf(stdout, "%d : %lld %lld\n", *parr, parr, arr);
+        
+         c = sumArray3(arr, b);
+
+        fprintf(stdout, "%d : %lld %llx\n", b, &b, &b);
+        fprintf(stdout, "%d : %lld %llx\n", *arr, *arr, *arr);
+        fprintf(stdout, "%d : %lld %llx\n", &arr, &arr, &arr);
+        fprintf(stdout, "%d : %lld %llx\n", arr[2], &arr[2], &arr[2]);
+        fprintf(stdout, "%d : %lld %llx\n", arr[3], &arr[3], &arr[3]);
+        fprintf(stdout, "%d : %lld %llx\n", arr[4000], &arr[4000], &arr[4000]);
+
+}
+
+```
+위 코드를 처럼 arr 배열을 선언하여 출력하면 <br>
+![lec06](./Image/lec06.jpg) 
+* 위 사진과 같은 결과를 얻을 수 있다. 사진에서는 arr가 각각 %d, %lld로 출력될 때 각각 값이 200, 140722121785492이 출력된다. 
+* 또한 바로 밑에 arr[2]가 출력된 것을 보면 주소가 8 증가한 것으로 보아 int arr로 선언되었기에 메모리 값이 4씩 증가하는 것이 확인된다. 
+* main함수에서 sumArray3 함수로 arr, b를 보내지만 b의 값은 바뀌지 않고 sum이라는 변수가 하나 생기게 된다. 또한, a의 주소 변경을 통해 값을 바꿀 수 있는 것을 sum += *a; a++;을 통해 알 수 있다. 
+#
+  * **배열은 Call by reference, int는 Call by value로 전달되었다.**
+  * Call by reference와 Call by value는 각각의 특징이 있는데, Call by value의 경우 데이터(값)을 복사해서 함수로 전달하기 때문에 <br>
+    원본의 데이터(값)가 변경 될 가능성이 없지만, 인자를 넘겨줄 때마다 메모리의 공간을 할당하기 때문에 메모리 공간을 좀 더 잡아먹게 된다. <br>
+    Call by reference의 경우 메모리 공간 할당의 문제를 벗어나게 되었지만 원본의 데이터(값)를 훼손할 수 있다는 문제점이 있다. <br>
+    그러므로 상황에 맞게 적절히 사용해야겠다고 생각한다.   
+#
+* 마지막으로 arr은 const이기 때문에 arr++;처럼 직접 바꾸려고 하면 에러가 발생한다. 그러므로 int *parr과 같이 따로 포인터를 만들어서 해야된다.
+                
+### Pointer / Address
+
+* int const A constant integer
+* int const * A (variable) pointer to a constant integer
+* int * const A constant pointer to a (variable) integer
+* int * const * A pointer to a constant pointer to an integer
+* int const * * A pointer to a pointer to a constant integer
+* int const * const * A pointer to a constant pointer to a constant integer
+
+## Lecture 07
+
+### int const * 와 int * const의 차이
+ ```
+ #include <stdio.h>
+ void add(int *a, int *b, int *c)
+ {
+     *c = *a + *b;
+ }
+ int main()
+ {
+     int const a = 100;
+     int b = 200;
+     int c = 9999;
+     int const * p = &a;
+     fprintf(stdout, "a, b ,c : %d %d %d\n", p, b, c);
+     p = &b;
+     fprintf(stdout, "a, b ,c : %d %d %d\n", p, b, c);
+ }
+```
+* int const * 는 const int형을 가리키는 포인터로 포인터 값은 변경이 가능하므로 다른 것을 가리킬 수 있으나 내부의 int 값은 const로 선언되어 변경이 불가능하다.
+
+* int* const 는 const 포인터가 int형을 가리키고 있으므로 포인터의 값은 변경이 불가능하고 내부의 int형으로 표현된 값은 변경이 가능하다.
+
+### 함수의 Pointer
+
+```
+#include <stdio.h>
+#define FN_ADD 0
+#define FN_SUB 1
+#define FN_MUL 2
+#define FN_DIV 3
+
+void add(int *a, int *b, int *c)
+{ *c = *a + *b; }
+
+void sub(int *a, int *b, int *c)
+{ *c = *a - *b; }
+
+void mul(int *a, int *b, int *c)
+{ *c = (*a) * (*b); }
+
+void div(int *a, int *b, int *c)
+{ *c = (*a) / (*b); }
+
+int main()
+{
+        int a, b, c;
+        char ch;
+        int op = FN_ADD; // default is add
+
+        scanf("%d %c %d", &a, &ch, &b);
+
+        void (*fp[4])(int *, int *, int *) = {add, sub, mul, div};
+        switch (ch)
+        {
+                case '+':
+                        op = FN_ADD;
+                        break;
+                case '-':
+                        op = FN_SUB;
+                        break;
+                case '*':
+                        op = FN_MUL;
+                        break;
+                case '/':
+                        op = FN_DIV;
+                        break;
+                default :
+                        op = FN_ADD;
+                        break;
+        }
+
+        fp[op](&a,&b,&c);
+        fprintf(stdout, "%d \n", c);
+
+        fp[5](&a,&b,&c);
+        fprintf(stdout, "%d \n", c);
+
+        // int const * p = &a;
+        // int * const q = &a;
+}
+```
+* 함수의 주소를 저장했다가 해당 주소의 함수를 호출할 때 사용한다.
+
+* void (*fp)와 같이 선언한다.
+
+* 배열은 (*fp[4])와 같이 선언한다.
+
+* #define과 const의 차이점
+    * #은 preprocessor
+    * const는 타입을 가지므로 표현 범위와 구조에 대해 명확하게 된다.
+    * const에는 메모리가 할당된다. 컴파일러로 하여금 그 영역에 덮어쓰는 작업을 막도록 감시하게 해 줄 뿐이지 
+    주소를 직접 건드리면 const의 값 마저 변경될 수 있다.
+ 
+### gcc compile options
+![gcc](./Image/gcc.jpg)
+### gcc compile - for multiple file
+* extern
+    * 외부 파일에서 선언된 변수를 사용.
+<br>
+![multicom](./Image/multicom.jpg)<br>
+* 위 사진과 같이 코드를 짜고 gcc main.c func.c를 하게 되면 우선 #(preprocessing)이 일어나 stdio 와 func.h를 불러온다. 그래서 main함수에서 DF == ((a)*(a))가 되고 func.h에 있는 extern에 의해서 func.c에 있는 func1이 호출된다. 만약 extern이 없으면 func.c에 있는 함수를 사용할 수 없다.
+* cc -c main.c
+    * main.c를 main.o로 만들어주는 명령어.
+* .o 파일
+    * c 소스 프로그램을 컴파일 할 때 생기는 목적 코드 파일. 기계어로 이루어져있다.
+    * cc main.o func.o를 하여도 정상적으로 a.out이 생성된다. 왜냐하면 .o에서 링크 단계를 거치면 a.out이 생성되는 것이기 때문이다.
+
+### C Preprocessor (CPP)
+* Macro Processor for C, C++, Objective-C
+    * Include head files
+    * Define macro
+    * Conditional Compliation
+    * Line Control
+
+### CPP - include file
+* #include file as text
+    * #include <stdio.h> or "file.h"
+* gcc Option - I
+    * Include location - ./usr/include/
+    * Default include location
+* Prevent multiple include
+    * #pragma once 
+    * #ifndef _MATH_ <br>#include <math.h>
+    <br>#endif
+
+### CPP - Conditional Compilation
+* #if, #ifdef, #ifndef, #elif, #else, #endif
+
+* Select code with condtion
+```
+    * #ifdef _VERSION_<br>
+      #if _VERSION_ >= 3<br>
+            printf("Version is greater or equal than 3\n");
+      #elif _VERSTION_ == 2
+      #error VERSTION 2 IS NOT SUPPORTED
+      #endif
+      #endif // idfef _VERSION_
+```
+### Marco Definition
+![Marco](./Image/Marco.jpg)<br>
+
+### 과제: if문을 이용하여 조건부 컴파일하기
+```
+//func.c
+
+#include "func.h"
+
+extern int fun1(int x);
+extern int fun2(int x);
+
+#if __FUNC_ == 0
+int func1(int a)
+{
+        return(a*10);
+}
+
+#else 
+
+int func1(int a)
+{
+        return DF(a+1)*20;
+}
+
+#endif
+
+int func2(int a)
+{
+        return DF(a+1)*10;
+}
+
+```
+
+```
+// func.h
+
+#ifndef __FUNC_
+
+#define __FUNC_  0
+
+#if FUNCTION_NEGATIVE == 1
+#define DF(a) (-(a)*(a))
+#else
+#define DF(a) ((a)*(a))
+#endif
+
+extern int func1(int x);
+extern int func2(int x);
+
+#endif
+```
+```
+// main.c
+
+#include <stdio.h>
+#define FUNCTION_NEGATIVE 1
+#include "func.h"
+
+int main()
+{
+        printf("Func1 %d %d\n", func1(100), DF(10));
+
+        printf("Func2 %d %d\n", func2(100), DF(10));
+
+}
+```
+* #if와 endif는 항상 짝을 이루어야한다.
+* func.h에서 extern을 통해 func.c에 있는 func1, func2을 사용한다.
+* func.c에서 ```#if __FUNC_ == 0```과 #else를 통해 0일 때는 두 종료의 func1 중에 하나를 선언, 그 외에는 func2를 선언한다. 이때 ```__FUNC_``` 을 0 이라고 정의했기 때문에 두 번째 func1은 컴파일 되지 않는다. 
+* main.c에서 fun1, fun2의 함수에 대입하여 결과값을 출력한다.
+
+### GCC Optimization
+* -O0(기본값)
+    * 최적화를 수행하지 않는다.
+* -O, -O1
+    * 코드 크기와 실행 시간을 줄이는 것을 제외한 최적화는 실행하지 않는다.
+* -O2
+    * 메모리 공간과 속도를 희생하지 않는 범위내의 모든 최적화를 수행한다. (loop unrolling과 function inlining에 대한 최적화를 수행하지 않는다.)
+* -O3
+    * -O2 최적화에 인라인 함수와 레지스터에 대한 최적화를 추가로 수행한다.
+* -Os
+    * -O2 최적화 기능을 사용하지만, 코드 크기를 증가시키는 최적화는 생략한다.
+
+
+### C Compile and Execution 
+![C_Compile](./Image/C_Compile.jpg)
+
+### gcc option
+* gcc -o (실행파일명) (파일명)
+    * 실행파일명으로 실행파일을 만든다.
+* gcc -E
+    * 전처리 과정의 결과를 화면에 보이는 옵션 (전처리과정 중 발생한 오류를 검증)
+* gcc -S
+    * cc1으로 전처리된 파일을 어셈블리 파일로 컴파일까지만 수행하고 멈춘다. (*.s)
+
+* gcc -c
+    * as에 의한 어셈블까지만 수행하고 링크는 수행하지 않는다. 오브젝트 파일 생성 (*.o)
+
+### CPP processing
+![CPP](./Image/CPP.jpg)
+
+### Macro Definition (1)
+![Macro1](./Image/Macro1.jpg)
+
+### Macro Definition (2)
+![Macro2](./Image/Macro2.jpg)
+
+### Macro Definition (3) - Function like Macro
+* ```
+    #define min (X, Y) ((X) < (Y) ? (X) : (Y))
+    x = min(a,b); -> ((a) < (b) ? (a) : (b));
+    y = min(1,2); -> ((1) < (2) ? (1) : (2));
+    z = min(a + 28, *p) -> z = ((a+28) < (*p) ? (a+28) : (*p));
+     if문 보다 성능이 좋다.
+
+   * BAD Examples 
+    #define f(a) a*a <br>
+    b = f(20+13) // 20 + 13 * 20 + 13
+  * Omit parameter <br>
+    ![omit](./Image/omit.jpg)
+
+![lec08-1](./Image/lec08-1.jpg)
+
+* ```__LINE__```은 몇 번째 라인인지 알려주며, 재정의 할 경우 그 밑줄부터 다시 카운트한다.
+* ```__FILE__```은 파일명을 출력한다. 해당 파일의 경우 이름이 hello.c이기 때문에 hello.c를 출력한다.
+* &a와 &b가 long long으로 정의되면 %lld로 출력될 때 warning이 발생하지 않는다.
+* ERR_DATA를 1000이라고 했기 때문에 if 문에 걸리지 않고 else로 넘어가 waring문을 띄어준다.
+
+### cc 옵션
+* cc -g
+    * gdb에게 제공하는 정보를 바이너리에 삽입한다.
+    * -g 옵션을 사용하지 않고 gdb로 디버깅하면, 역어셈 → 어셈블리 코드로만 디버깅 가능하다.
+
+* cc -pg
+    * 프로파일을 위한 코드를 삽입한다. 
+    * -pg 옵션으로 컴파일 → gmon.out(프로파일 정보) → gprof로 gmon.out 파일 분석
+
+### 복습 
+* a.out &> output.txt의 의미 = a.out의 stdout과 stderr 둘 다 output.txt로 redirection 한다. 
+
+### Linux Command 
+* ps : 현재 실행중인 프로세스(job) 목록과 상태를 보여준다. 
+#
+* ps -l : 긴 포맷으로 보여준다. 
+#
+* fg : background에서 실행되고 있는 작업을 foreground로 옮기는 명령어
+#
+* bg : foreground에서 실행되고 있는 작업을 background로 옮기는 명령어
+
+### vi가 background로 돌 수 없는 이유 
+* vi 에디터는 stdin에서 입력을 받는다. 그러면 vi를 백그라운드로 돌리고 배쉬 작업을 하면(배쉬 작업도 stdin에서 명령을 받는다.) 이때 <br>
+사용자가 입력한 명령은 vi로 가는지 bash로 가는지 알 수 없다. 따라서 stdin을 쓰는 명령어나 프로그램, 앱은 background로 돌 수 없다. <br>
+stdin을 사용하는 프로세스가 만약 background로 실행되고 있는 와중에 scanf를 만나면 그 자리에서 멈춘다.
+
+## Lecture 14
+
+* 버퍼 : 하나의 장치에서 다른 장치로 데이터를 전송할 경우에 양자간의 데이터의 전송속도나 처리속도의 차를 보상하여 <br>
+양호하게 결합할 목적으로 사용하는 기억영역을 버퍼 또는 버퍼 에어리어라고 한다. 보통 중앙처리장치와 단말이나 다른 입출력장치사이의 <br>
+데이터 송수신에는 입출력 영역으로서 버퍼를 필요로 한다. <br>
+![lec14-1](../Image/lec14-1.jpg)
+
+* 가장 중요한 3가지 표준 버퍼 : stdin, stdout, stderr
+
+* POSIX (Portable Operating System Interface) : 다른 운영체제들 사이에서 호환성을 위해 IEEE에서 만든 표준이다. <br>
+
+* fifo (First in First Out) : 대기행렬에서의 선입선출 제어 방식이다. 복수의 신호 혹은 job이 처리대기로 되어 있을 경우 <br>
+처리의 우선순위를 붙이지 않고 먼저 도착한 순서로 처리하는 방식이다. 
+
+* stack : 스택은 컴퓨터에서 사용되는 기본 데이터 구조 중 하나로 데이터를 후입선출 구조로 유지하는 추상 데이터형을 말한다.
+
+### Understanding Buffer and stream
+* buffer control
+    * no
+    * line
+    * block <br>
+![lec14-2](./Image/lec14-2.jpg)