#1. 수강 과목 : 컴퓨터 과학 기초(1~3과)
#2. 수강 콘텐츠 : 모두를 위한 컴퓨터 과학(CS50 2019)

  1. 컴퓨팅 사고
  • 2진법 : 껐다 켠다. 컴퓨터의 언어.
    2진법을 하나의 자릿수로 표현하는 단위를 비트, 8개로 표현한게 바이트(8비트).
  • 정보의 표현(컴퓨터가 문자, 사진, 영상 등 처리하는 방법)

문자 : ASCII 코드 이용해서 문자를 숫자 + 유니코드까지 사용(이모티콘 등)

(소문자는 다름, 아스키코드 링크)

색깔 : RGB & 그 정도의 수치 조합.(픽셀의 연속)

이미지 / 영상 : 여러 장의 이미지들의 연속.(2진법과 RGB의 연속)

음악 : 음표의 숫자 표현으로 이어지는 연속.

  • 알고리즘
    뭔가를 수행하는 단계적인 방법.(step by step, 전화번호부를 찾는 것과 같음) ; 효율적으로 나눠가며 스텝에 따라 문제를 해결해나가는 것. 규칙들의 순서적 나열.(정확성과 효율성을 바탕으로 알고리즘 평가)

의사코드(C, python....등의 코드 표현식을 예로 들면)
뭔가 하는 것 : 함수
if/else : 조건문
True/False로 답이 나오는 것 : Boolean
반복, 순환 : loop

코드의 원리, 코드의 효율성(줄이기, 추상화)


  1. C언어 기초(by CS50 Sandbox)
  • "hello, world"
#include <stdio.h>

int main(void){
    printf("hello wolrd!");
}

쌍 따옴표만 씀

소스코드를 머신코드로 인식해주는 것을 컴파일러라고 함.(소스코드 : c,python.., 머신코드 : 00001...)

터미널에서

clang hello.c(a.out 생성)
./a.out(실행)

줄바꿈도 시켜주려면?

#include <stdio.h>

int main(void){
    printf("hello wolrd!\n");
}

\n를 따로 써줘야 함(리 컴파일링 하고..)

최종 터미널

$ clang hello.c
$ ./a.out
hello wolrd!

a.out말고 다른거로 해보기

$ clang -o hello hello.c
$ ./hello
hello wolrd!

그 외는 ls, rm 등은 터미널에서 하는 것과 같음.(파일 확인, 지우기..)

  • 문자열 다루기 : 사전에 변수를 선언하고 해야 함.
#include <cs50.h>
#include <stdio.h>

int main(void){
string animal = get_string("what is your favorite animal?\n");
printf("my favorite animal is, %s\n", animal);
}

#뒤에 들어가는 것은 라이브러리임.(어떤 기능을 가능하게 하는 것, get... 등. 파이썬 import 같은 기능인 듯.)

%~ : 정규표현식이라 생각하면 됨.

큰 복잡한 것 없이 앞으로는

$ clang -o hello hello.c
$ ./hello

대신

make ~(파일명)
./~
결과 나오면 거기에 animal 값 입력
what is your favorite animal?
cat
my favorite animal is, cat

입력하면 앞에서 했던 것 안 해도 됨.
그리고 ./파일명 하면 컴파일러 자동으로 연결

  • 조건문과 루프
    조건문은 자바스크립트나 파이썬과 비슷
    for, while도 비슷
int i = 0;
while(i < 50)
{
    printf("hello, world\n");
    i += 1;
}

for (int i = 0 ; i < 10 ; i += 1) # ; 사이사이에 다 넣기
{
    printf("hello, world\n");
}
No rule to make target

에러가 나면 그냥 원래 clang 사용하면 풀림.

  • 데이터 타입(bool, char, double, float, int, long, string...)

기본 예제

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

int main(void){
int age = get_int("what's your age\n");
int days = age * 365;
printf("You are at least %i days old.\n", days);
}

what's your age
50
You are at least 18250 days old.

코드의 가독성 생각하기(int day는 줄일 수 있다 생각하기)

소수점은?

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

int main(void){
    float price = get_float("What's the price?\n");
    printf("Your total is %f.\n", price * 1.0625);
}

What's the price?
100
Your total is 106.250000.

여기서 2f로 수정하면 2자리만 나옴(파이썬 문자열 응용하기 정규표현식 생각하기)

if문으로 홀짝 가리는 프로그래밍 하기

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

int main(void){
    int n = get_int("n: ");

    if (n % 2 == 0){
        printf("even\n");
    }
    else{
        printf("odd\n");
    }

}

else에 특별한 조건을 달지 않는 것도 파이썬과 동일하다.

주석은 // 로 달면 된다.
or은 ||을 쓰면 된다. &&는 and

  • 사용자 정의 함수 / 중첩 반복문
#include <cs50.h>
#include <stdio.h>

int main(void){

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

}

함수를 넣으면 이렇게 된다.

void cough(void){
        printf("cough\n");
}

int main(void)
{
    for (int i = 0; i < 3 ; i++)
    {
    cough();
    }
}

만든 함수가 cough 를 프린트 할 건데 (void위치) 조건은 아래 메인에 뒀다. 결과는 위의 반복문이 쓰인 것과 같으나 각각 자신의 역할에 집중할 수 있다고 한다.

코드가 길어질 경우 함수의 조건을 조금 더 명확하게 보기 위해서 한 조치

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

void cough(void); //위로 복사해서 올린다.

int main(void)
{
    for (int i = 0; i < 3 ; i++)
    {
    cough();
    }
}
void cough(void){
        printf("cough\n");
}

메인의 결과 값에 따라 값을 지정한 경우(원하는 횟수만큼 출력되게 main값에서 조작하기 ; cough 함수가 매개변수고 main함수가 인자가 되는 형태 같음.)


#include <stdio.h>

void cough(int n);

int main(void)
{    cough(3);
}
void cough(int n){
    for (int i = 0; i < n ; i++){
        printf("cough\n");
    }
}

음수면 리턴해서 값을 안 내고 양수일 때만 내는 do - while 예시

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

int get_positive_int(void);

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

int get_positive_int(void){
    int n;
    do
    {
        n = get_int("Positive Integer: ");
        
    }
    while(n < 1);
    return n;
}

슈퍼마리오 게임 이용한 중복 루프 : 파이썬 별 그리기와 비슷한 원리 같음.

  • 하드웨어의 한계 : 컴퓨터가 할 수 있는 일은 한계가 있다.(eg.렘 용량의 한계) 이를 오버플로우라고 한다.
#include <cs50.h>
#include<stdio.h>

int main(void)
{
    float x = get_float("x:");
    float y = get_float("y:");
    printf("x/y = %.50f\n", x / y);
}

x:0.34
y:0.56
x/y = 0.60714286565780639648437500000000000000000000000000

100% 정확하게 무한한 숫자를 계산하고 저장할 수 없으므로 1/10 부분까지 정확하게 하려고 한다.(하드웨어 자체의 한계)

무한 반복문도 마찬가지. 중간에 갑자기 에러남.


  1. 배열
  • 컴파일링(이런 과정을 거친다 정도만 끄덕끄덕)
    preprocessing(#include)->compling(여러 명령어들로 컴파일링)->assembling(0101010101010...)->linking(결과물)

  • 디버깅 : 버그를 해결하는 방법(버그 발생 시 help 50하면 버그 검색이 가능)

  • 코드의 디자인 : check 50 (코드 테스트), style50(코드의 심미적 상태 검사)

  • 배열 1 : 컴퓨터가 정보를 저장하는 방식

#include <stdio.h>

int main(void){
    char c1 = 'H';
    char c2 = 'I';
    char c3 = '!';
    printf("%c %c %c\n", c1, c2, c3);
}
H I !

만일 정수로 하려면?

#include <stdio.h>

int main(void){
    char c1 = 'H';
    char c2 = 'I';
    char c3 = '!';
    printf("%i %i %i\n", (int)c1, (int)c2, (int)c3);
}
72 73 33 // by 아스키코드

각 값이(c1, c2, c3) 한 칸 씩 저장된 거란 뜻.(실제론 2진법이지만 표현을 아스키 코드에 따라 출력한 것임)

숫자를 크기에 따라 렘에 정리하는 것까지 보았으니 실제로 리스트를 한 번 만들어보기로 함.

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

int main(void){
    int scores[3]; // 리스트와 인덱스 활용
    scores[0] = 72;
    scores[1] = 73;
    scores[2] = 33;

    printf("Average : %i\n", (scores[0]+scores[1]+scores[2]) / 3);

}
59
  • 배열 2

전역변수로 보기 쉽게 만들기

#include <stdio.h>
#include <cs50.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);

}

조금 더 효율성 있는 코드로 바꿔보기

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

float average(int length, int array[]);
int main(void){

    int n = get_int("Number of scores: ");
    int scores[n];
    for (int i = 0; i<n; i++){
        scores[i] = get_int("Score %i:", i + 1);
    }
    printf("Average : %f\n", average(n, scores));

}

float average(int length, int array[]){
    int sum = 0;
    for (int i = 0; i<length; i++){
        sum += array[i];
    }
    return (float) sum / (float) length;
}

함수 만들고 위에 이름 올려준 뒤 계산(정수가 인식되어 계산되므로 값이 정수가 될 것임. 소수점만 붙음. 그래서 float를 붙여줌)

  • 문자열과 배열
    문자열(string)은 char의 배열(한 글자 한 글자의 배열. 그래서 시퀀스형인 것이었음)

문자열이 끝나는 정보는 null, \0로 종단 문자라고도 불림.(길이에 따른 크기)
HI! -> 3+1바이트(종단문자도 포함)

1차원 배열 + 2차원 배열(알파벳 하나 하나 나오게 인덱싱 ; 문자열 출력 원리 보기) ; 파이썬에서 for i in ~~ 로 문자열 하나 하나 빼서 인덱스로 정리하는 것 생각하면 됨.

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

int main(void){
    string names[4];
    names[0] = "EMMA";
    names[1] = "RORY";
    names[2] = "BRIAN";
    names[3] = "DAVID";

    printf("%s\n", names[0]);
    printf("%c%c%c%c\n", names[0][0], names[0][1], names[0][2], names[0][3]);
}
EMMA
EMMA
  • 문자열 활용(문자열 안에 문자 검색 / 다른 문자로 바꾸기)

문자열 char 하나씩 나열해서 꺼내는 식1

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

int main(void){
    string s = get_string("Input: ");
    printf("Output: ");
    for (int i = 0; s[i] != '\0' ; i++){
        printf("%c", s[i]);
    }
        printf("\n");
}
Input: EMMA
Output: EMMA

식2

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

int main(void){
    string s = get_string("Input: ");
    printf("Output: ");
    for (int i = 0; i < strlen(s) ; i++){
        printf("%c", s[i]);
    }
        printf("\n");
}

개선의 여지 :

    for (int i = 0,  n = strlen(s); i < n ; i++)

그 외 문자열 내에 문자를 변경하는 것 : 맥북 업데이트 이후에 안 되는 에러가 뜨는 듯. 일단 코드만 알아두자.

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

int main(void)
{
    string s = get_string("Before: ");
    printf("After:  ");
    for (int i = 0, n = strlen(s); i < n; i++)
    {
        printf("%c", toupper(s[i]));
    }
    printf("\n");
}

이게 뭐 입력하면 아스키 코드에 맞게 계산해서 대문자로 변경해주는 그런 식이라고 하는데 잘 모르겠다. 일단 적기만 하자.(여기는 패스)

  • 명령행 인자 : int main(void)에 대한 설명
    만일 명령행 인자를 받을 경우(eg. ./argv David ; 인자 받아서 출력하는 경우)
# include <cs50.h>
# include <stdio.h>

int main(int argc, string argv[]){

    if (argc == 2){
        printf("hello, %s\n", argv[1]);
    } else {
        printf("hello, world\n");
    }
}
$ ./argv David
hello, David

main함수는 기본적으로 반환값을 갖는다. (0, 문제 없음)

왠지 다른 함수에서 자기 자신을 첫 반환값(self)로 하는 것 같은 이유가 보이는 c언어 함수 예시

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

int main(int argc, string argv[]){

    if (argc !=2){
        printf("missing~\n");
        return 1;
    }
        printf("hello, %s\n", argv[0]);
        return 0;
}

$ ./exit
missing~
$ ./exit david
hello, ./exit

그냥 출력했을 때는 기본 리턴값을 나타내는데 값을 입력한 리턴값은 그 집어 넣은 값(여기서는 david)을 1번째로 하고 그 전에 return 0으로 낸다 하는 최초 의 값 ./exit를 냄. 이게 왠지 다른데에서 첫번째 인자는 자기 자신, self의 의미와 뭔가 연관이 있어 보이는 개념임.

문제까지 다 풀고나니 방전..ㅋㅋ 일단 복습은 내일 코드 직접 다시 쳐보며 해봐야겠다. c언어 다 이해 못 하더라도 일단 개념만 잡고 가자.

profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

0개의 댓글