[CS50] 컴퓨팅 사고와 C 기초

Gyuwon Lee·2022년 6월 11일
0

42 Seoul 7기

목록 보기
1/6

42서울 7기 라피신을 대비하여 정리한 CS50 2019 과정을 간략히 복기하여 재업로드한 내용입니다.

1. 🖥 컴퓨팅 사고

1) ✌️ 2진법

  • 오직 0과 1로만 표현하는 것
    • 컴퓨터의 표현 방식
    • 각 자릿수가 2의 거듭제곱을 의미함
    • 전기를 통해 연산하는, 즉 전기를 켜고 끄는 방식으로 작동하는 컴퓨터에게 적합한 방법
    • 컴퓨터에는 굉장히 많은 스위치(트렌지스터)가 있고 on/off 상태를 통해 0과 1을 표현한다.

👾 비트와 바이트

  • 비트: Binary Digit를 줄인 말.
    • 정보라고 취급할 수 있는 가공된 데이터(자료)들을 나타내는 최소 단위
  • 바이트: 비트 8개의 묶음

2) 💬 문자의 표현

🔡 ASCII와 유니코드

  • 1바이트(8비트)를 사용하여, 알파벳 대소문자 및 일부 특수문자를 고유한 숫자에 대응시킨 체계
  • 유니코드: 영어를 제외한 외국어, 이모지 등 다른 체계의 문자도 표현하기 위해 등장한 ASCII의 상위 집합
    • 8이나 16, 24, 32비트까지도 사용 가능

🎨 RGB

  • Red, Green, Blue의 조합을 숫자로 표현하여 색상을 나타내는 체계

📌 "CS50을 2진법으로 표현해보세요."
1000011(C) 1010011(S) 110010(50) 이라고 표현했는데, 다른 사람의 답댓글을 보니 "CS50은 한 단어로 데이터 형이 여러개일 수 없기 때문에 모두 문자로 표현" 했다고 한다. 그럼 50은 각각 110101, 110000으로 표현된다.


3) ⚙️ 알고리즘과 의사코드

🔣 알고리즘

  • 문제를 해결하기 위한 절차나 방법
  • 어떠한 행동을 하기 위해서 만들어진 명령어들의 유한 집합(finite set)
  • "사람이 이미 갖고 있는 직관이나 생각들을 기계나 다른 사람들이 이해할 수 있는 방식으로 번역하는 것"

🌐 의사코드

  • 자연어를 이용해 만든 문장을 프로그래밍 언어와 유사한 형식으로 배치한 코드
  • 문장 하나 하나는 자연어에 가까운 표현을 사용하지만 그걸 실제 프로그래밍과 비슷하게 실행 순서를 명시해 나열함으로써 두 언어의 장점을 적절히 취한 것
  • 알고리즘을 특정 프로그래밍 언어에 종속되지 않고 보다 일반적으로 표현할 수 있게 한다

2. 🐥 C 기초

1) 🔄 코드의 기본적 구성과 컴파일러

  • int main(void) { }
  • printf()
  • ;
  • #include
  • 확장자 .c
  • 프롬프트 $

🛠 컴파일러

  • 사용자가 작성한 “소스 코드”를 2진수로 작성된 “머신 코드”로 변환하는 프로그램
  • clang, gcc
    • 디폴트로 a.out 실행파일이 생성됨
    • Command-line Argument (명령행 인자) 를 사용하여 파일명을 변경하는 등의 옵션 조작이 가능

🖥 command-line argument

  • 프로세스를 실행하면서 전달하는 인자
  • 사용자가 명령행에서 명령을 실행할 때 해당 명령과 함께 지정하는 인자
  • 일반적으로 명령의 옵션이나 옵션의 인자, 명령의 인자로 구성됨

2) 🔡 문자열

  • = : 할당 연산자
    • 오른쪽의 값을 왼쪽에 할당한다.
  • % : 형식 지정자
  • 문자열: 따옴표 안에 들어간 0개 이상의 문자 배열
include <stdio.h>

int main(void){
  char answer[];

  scanf("좋아하는 동물을 알려주세요", &answer);
  printf("내가 좋아하는 동물은 %s", answer);
}

3) 🔄 조건문과 루프

  • syntactic sugar : 새로운 기능을 추가해주지는 않지만 기존 기능을 더욱 보기 좋고 간결하게 활용하도록 해 줌
  • if - else : 조건문을 boolean 값으로 평가한 결과에 따라 실행
  • while, for
include <stdio.h>

int main(void){
  for (int i = 0; i++; i < 10){
    printf("개발 공부는 재미있다!");
  }
}

4) 🔣 자료형, 형식 지정자, 연산자

  • bool, char, double, float, int, long, string ...
  • %c, %f, %i, %li, %s ...

5) ♻️ 사용자 정의 함수, 중첩 루프

#include <cs50.h>
#include <stdio.h>

// 프로토타입 선언
int get_positive_int(void);

int main(void)
{
    int i = get_positive_int();
    printf("%i\n", i);
}

// int: 리턴값 (n)에 따른 자료형 명시. "출력의 종류"
// void: "입력의 종류"
int get_positive_int(void)
{
    int n; // 변수 선언 (초기화 X)
    do // do-while loop. 무조건 한 번은 실행 후 아래 while문의 조건에 따라 실행
    {
        n = get_int("Positive Integer: ");
    }
    while (n < 1);
    return n;
}
#include <cs50.h>
#include <stdio.h>

int main(void)
{
    int n;

    do
    {
        n = get_int("Size: ");
    }
    while (n < 1);

    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("#");
        }
        printf("\n");
    }
}

6) 💾 메모리와 오버플로우

  • 오버플로우 : 컴퓨터의 정수 연산의 계산 결과가 허용 범위를 초과할 때 발생하는 오류
    • 정수 오버플로우
      • 컴퓨터의 메모리가 8비트의 데이터를 저장할 수 있다고 하고, 편의상 부호는 없는 양수인 경우만 고려해 보자.
      • 가장 작은 값은 0000 0000 (=0) 이며, 1씩 증가시키면 0000 0001 (=1)을 거쳐 최댓값인 1111 1111 (=255)에 도달하게 된다.
      • 여기에서 1을 다시 한번 더하게 되면 최댓값의 범위를 넘어서게 되고, 최솟값인 0000 0000 (=0) 으로 되돌아가게 된다.
    • 스택 오버플로우
      • 함수는 변수 등을 저장하기 위해 스택이라는 메모리 공간을 만드는데, 이 함수가 재귀적으로 계속 실행되면 스택이 점점 생겨난다.
      • 이러면 어느 순간 메모리가 모자라는 순간이 되는데, 이때 생기는 오류다.
    • 버퍼 오버플로우
      • 할당된 범위의 메모리를 벗어난 주소로 접근하게 되는 것
profile
하루가 모여 역사가 된다

0개의 댓글