본문 바로가기
DevOps/IT Knowledge

명동 스터디_컴퓨터 과학 기초_3

by ki._.w0n 2024. 7. 16.

명동 스터디 : 기초를 숙련한지 너무 오래되어 컴퓨터공학부 커리큘럼의 필수 과목과 관련된 공부를 통해 기초를 숙련하고 숙련된 기초를 통해 프로젝트 진행을 하기 위한 4명의 스터디 모임

 

기원 : ki-w0n.tistory.com

백범 : https://long-shift-6b9.notion.site/dbf9ea3ec9fd49379e43c127e470123a

찬형 : https://memo.chanhyung.kim/407d7b36c9204fb3813a42eac8674897

병묵 : https://manso98.notion.site/23723aa1c0bb44828b52fc57efa6639e

 

명동 스터디 첫번째 커리큘럼 일정(2024.07.29 ~2024.11.16)

- 컴퓨터 과학 기초(07.09 ~ 07.21)
- 이산수학(07.29 ~ 08.17)

- 자료 구조(08.19 ~ 09.07)

- 컴퓨터 구조(09.09 ~ 10.12)

- DB(10.07 ~ 10.26)
- 네트워크(10.28 ~ 11.16)

 

목차

     


     


    컴파일링

    전처리

    컴파일의 전체 과정은 4단계로 나눌 수 있습니다. 그 중 첫번째 단계가 전처리입니다.

    전처리기(Preprocessor)로 컴파일 전 코드를 적정한 상태로 준비하거나 처리하는 단계입니다.

    전처리 구문은 #으로 시작합니다.

    ex. #include<stdio.h>

    예시와 같이 헤더파일을 불러오거나 #define을 통해 매크로를 정의합니다.

     

    컴파일

    전처리기가 전처리 후 소스코드를 생성 후 다음은 컴파일을 합니다. '컴파일러'를 통해 C코드를 어셈블리어라는 저수준 프로그래밍 언어로 변환하여 컴파일합니다.

     

    어셈블

    소스코드가 어셈블리 코드로 변환되면, 어셈블 단계로 어셈블리 코드를 오브젝트 코드로 변환합니다.

    -> 오브젝트 파일(목적파일) 생성

     

    링크

    여러개의 파일로 나뉘어져 있는 파일을 하나의 오브젝트 파일로 합쳐야한다면 링크라는 컴파일의 마지막 단계가 필요합니다.

    링커는 여러개의 다른 오브젝트 코드파일을 싱행 가능한 하나의 오브젝트 코드 파일로 합쳐줍니다.

    즉 목적 프로그램을 라이브러리와 연결하여 실행 프로그램을 작성

     

    .c(소스파일) -> 전처리기 -> .i -> 컴파일러 -> .s -> 어셈블러 -> .o(목적코드)/.a(라이브러리 파일) -> 링커 -> .exe(실행 파일)

     


     

    버그와 디버깅

    버그(bug)는 코드에 들어있는 오류입니다.

    디버깅(debugging)은 코드에 있는 버그를 식별하고 고치는 과정입니다.

     

    int main(void)
    {
        printf("hello, world\n");
    }

    해당 파일을 컴파일해보면 오류가 뜹니다.

    이유는 printf함수를 사용하기 위해서는 stdio.h 라이브러리를 포함해야 한다는 것 입니다.

    #include <stdio.h>
    
    int main(void)
    {
        for (int i = 0; i <= 10; i++)
        {
            printf("#\n");
        }
    }

    이 코드 역시 에러는 발생하지 않으나 #이 11개나 출력되는 것을 확인할 수 있습니다.

    i<=이라는 조건은 실제로 11번 만족하기 떄문입니다.

    따라서 i<10으로 수정해야 #이 10회 출력됩니다.


     

    배열

    메모리

     

    컴퓨터 안에는 다음 사진과 같은 RAM이라는 물리적 칩이 메모리 역할을 합니다.

    여러개의 노란색 사각형은 메모리를 의미하며, 작은 사각형 하나가 1byte를 의미합니다.

     

    배열

    #include <cs50.h>
    #include <stdio.h>
    
    int main(void)
    {
        // Scores
        int scores[3];
        scores[0] = 72;
        scores[1] = 73;
        scores[2] = 33;
    
        // Print average
        printf("Average: %i\n", (scores[0] + scores[1] + scores[2]) / 3);
    }

     

    int scores[3]; 속 숫자3은 int 자료형 크기 3의 배열을 생성하는 것입니다.

    scores[0] = 72; 는 scores 배열의 첫번째 인덱스 안에 72를 대입하는 것 입니다. 마찬가지로 0, 1, 2 각각 72, 73, 33을 대입하였습니다. 이를 통해 배열에 들어있는 숫자의 평균을 구할 수 있습니다.

     

    전역변수

    #include <cs50.h>
    #include <stdio.h>
    
    const int N = 3; // 전역변수
    
    int main(void)
    {
        // 점수 배열 선언 및 값 저장
        int scores[N];
        scores[0] = 72;
        scores[1] = 73;
        scores[2] = 33;
    
        // 평균 점수 출력
        printf("Average: %i\n", (scores[0] + scores[1] + scores[2]) / N);
    }

     

    다음 코드에서 scores 배열의 크기를 정해주는 N이라는 변수를 새로 선언하는데 있어 N이 고정된 값(상수)라면 그 값을 선언할 떄 const를 앞에 붙여서 전역 변수, 즉 코드 전반에 거쳐 바뀌지 않는 값임을 지정할 수 있습니다.

    전역변수는 관례적으로 대문자로 표기합니다.

     

    문자열과 배열

    문자열(string) 자료형의 데이터는 문자(char) 자료형의 데이터들의 배열입니다.

    string s = "HI!";과 같은 문자열 s가 정의되어있는 경우

    s는 문자의 배열이기 때문에 메모리상에 다음과 같이 저장되고 인덱스로 각 문자에 접근할 수 있습니다.

    string names[4];
    
    names[0] = "EMMA";
    names[1] = "RODRIGO";
    names[2] = "BRIAN";
    names[3] = "DAVID";

     

    name에는 4개의 이름이 메모리에 저장 됩니다. 바로 아래와 같은 방식으로 말입니다.

     

    printf("%s\n", names[0]);
    printf("%c%c%c%c\n", names[0][0], names[0][1], names[0][2], names[0][3]);

     

    첫번째 printf(%s\n", names[0]);에서 문자열 [0]에 있는 EMMA가 출력되고

    두번째 printf("%c%c%c%c\n", names[0][0], names[0][1], names[0][2], names[0][3]);에서는

    %c 즉 문자가 출력되어 각각 E, M, M, A가 출력됩니다.