본문 바로가기
  • 초부득3 - 어제보다 나은 내일을 위해
  • 꿈이 현실이 되는 날까지
인강/모두를 위한 컴퓨터 과학 cs50 2019

CS50 C언어

by 금의야행 2021. 6. 9.

https://www.boostcourse.org/cs112/lecture/119004/?isDesc=false 

 

모두를 위한 컴퓨터 과학 (CS50 2019)

부스트코스 무료 강의

www.boostcourse.org

https://sandbox.cs50.io/

 

CS50 Sandbox

Temporary programming environments for students and teachers.

sandbox.cs50.io

 

 

 

 

 

1) c 기초

 

 

input                                     output

source code    ->    complier     ->    machine code

c, c++, Java,          번역기                 컴퓨터가 이해하는 0,1 binary 형태

python 등등

 

$ 사인은 그냥 여기에 무언가를 입력하시오 라는 의미

 

= 프롬포트 혹은 쉘

 

clang 은 코드를 컴파일 하는 프로그램의 이름입니다.

 

언제나 텍스트에 " " 쌍따옴표로 감싸야 합니다.

 

문장의 끝에 마침표(.)를 붙이는 것 처럼 C에서는 세미콜론(;)을 붙여야 합니다.

 

 

 

간단 hello world 출력하기

1.

#include <stdio.h>

 

int main(void)

{

    printf("hello, world\n");  \n은 줄바꿈 코드

}

 

2. 위에 코드를 terminal 에서 clang 이라는 프로그램으로 컴파일 하기 

$ clang hello.c

 

3. 컴파일 된 머신코드 파일 a.out 실행하기

$ ./a.out ./ 는 '.' 현재 폴더잇는 녀석을 / 실행하기 라는 의미

 

4. hello, world$

                 \n을 추가하지 않았을경우

 

C언어 학습자료.pdf
0.37MB

 

 

 

 

 

 

2) 문자열

 

CS50 Sandbox에서는 스크래치의 ask함수와 가장 비슷한 것은 get_string 함수입니다.

 

String은 문자열 / 단어나 구절, 문장을 부르는 말입니다. (숫자와는 다른 종류의 데이터 입니다.)

쌍따옴표 안에 들어간 0개 이상의 문자 배열입니다.

 

 

 

c에서는 변수에 들어갈 정보가 무엇인지 조차 지정해줘야함

형식지정자   변수        함수 

       string answer = get_string("what's your name?\n");

 

 

우리가 일반적으로 사용하는 =은 같다 입니다.

하지만 프로그래밍 언어에서는 오른쪽에서 왼쪽으로 가는 화살표와 비슷하다고 생각해주시면 좋습니다.

쉽게 말하자면 오른쪽에 있는 것을 왼쪽에 지정한다는 것이죠. 이를 할당 연산자라고 합니다.

get_string 함수가 사용자의 이름을 반환하면 그 이름을 anwser이라는 변수에 저장하는 것입니다.

오른쪽에서 왼쪽으로 말이죠

 

 

string answer = get_string("what's your name?\n");

printf("hello, %s\n" , answer );

 

 

*야매설명* % (형식지정자)가 입력값을 받아내게 해주는역활 무엇을 받는지를 s (string)으로 지정 해줌. 

그리고 그뒤에 인자 answer, 에서 입력값을 가져옴

 

 printf는 우선

1. 쌍따옴표 안에 있는 하나의 문자열을 입력으로 받음

2. 그런데 거기에 형식 지정자(%) 가 있다면,  쉼표와 변수명을 같이 입력(위의 사례에선 , answer ) 함으로서 컴퓨터에게 가져와야할 값을 알려주는것.

 

더욱 많은 형식 지정자와 변수가 있을경우 왼쪽에서 오른쪽 순으로 지정됌

ex) printf ("%s, %s" , answer , question )

첫번쨰 %s는 첫번 째 쉼표 뒤의 변수 (answer)에 해당하고 두번째는 두번째. and so on.

 

 

 

에러가 났을 경우 언제나 첫번째 에러를 주목! 왜냐하면 그 이후의 에러들은 처음에서 나온 허상일 가능성이 큼.

 

io 는 input output 입출력을 의미

 

 

 

컴파일시 소스코드 상에 주어진 라이브러리를 명시해서 내 소스코드와 주어진 라이브러리가 링크 될 수 있게 해야함

 

eg) #include <cs50.h>

$clang -o string string.c  -> error

 

$clang -o string string.c -lcs50  -> good

 

-l (이 링크를 의미, cs50와 링크하라는 뜻)

 

 

 

이 모든 개념을 이해하고 앞으론 그냥 컴파일 할때 

 

 make string 으로 하면됌  그럼 알아서 string.c (소스코드)를 찾아서 string 이라는 머신코드를 만들어 낼거임.

 

make ~ 는 유닉스와 리눅스를 (운영체제) 사용하는 컴퓨터들에 포함되어 있는 일반적인 툴임.

 

 

 

 

 

 

3) 조건문과 루프

 

 

조건문 (if, else, else if)

scratch)

set counter to 0 ( 변수를 지정하는 코드)

 

C) 에서는 우리가 어떤 종류의 변수를 컴퓨터에 저장하고 싶은지 지정해줘야함.

counter = 0

가 아니라

 

int counter = 0 ;

 

where int ( integer 정수)

 

scratch)

change counter by 1

 

c)

counter = counter + 1 ;

 

(위에서 이야기 햇듯이 =은 오른쪽 값을 왼쪽에 복사하는 것과 같음 c에선. 

그렇기에 수학적으론 말이 안되지만, c에선 counter + 1 값을 counter 에 저장하라는 의미의 코드

여기선 int로 지정할 필요가 없음. 왜냐하면 이미 컴퓨터에게 counter 라는 변수안에 int 값을 저장한다고 알려줬기 때문)

 

똑같은 의미에 다르게 쓰는법

 

counter+ = 1;

counter++;

 

 

scratch) 

if x < y then 

say x is less than y

 

c)

if (x < y)

{

   printf("x is less than y\n") ;

}

 

 

scratch)

if x < y then

say x is less than y

else

say x is not less than y

 

c)

if (x < y)

{

   printf("x is less than y\n");

}

else

{

   printf("x is not less than y\n");

}

 

세미 콜론 (:)은 조건문 뒤엔 붙히지 않아도 됌. 어떤 행동을 지시하는 함수 뒤에 붙히기만 하면 됌. 이런 패턴에 익숙해지자.

 

scratch)

if x < y then

say x is less than y

else

 if x > y then

 say x is greater than y

 else

  if x = y then

  say x is equal to y

 

c)

if (x < y)

{

   printf("x is less than y\n");

}

else if (x > y)

{

   printf("xis not less than y\n");

}

else if ( x ==  y)

{

  printf("x is equal to y\n");

}

 

=은 같다란 의미가 아님으로 같음을 표기하는 기호는 == 를 사용함.일치 연산자라고 부름.

 

불리언 표현 == 답이 예/아니오 true/false 0/1으로 나뉠수 있는 질문.

 

위 경우 마지막 불리언 표현 (else if (x==y)) 는 필요 없는 질문. 왜냐하면 논리적으로 그 답 밖에 남지 않기 때문에.

더보기

최대한 효율적으로 ( 더 적은 데이터를 사용해서) 코드를 적는 과정은 중요함.

 

if (x < y)

{

   printf("x is less than y\n");

}

else if (x > y)

{

   printf("xis not less than y\n");

}

else

{

  printf("x is equal to y\n");

}

 

 

 

 

 

 

 

루프 (for, while)

1. while 루프

 

scratch)

forever

say hello, world

 

c) (위의 코드와 완전히 같은 의미를 가지진 않지만)

 

while ( 불리언 표현)

while (true) <-(이곳에 불리언 표현 중에 계속해서 참 1 인 질문이 들어가야 위의 forever와 같이 끊임없이 반복                        하는 루프를 만들 수 있음. 기본적으로 while ( 불리언 표현) 형태. ex) 1==1, 2>1, 이런 종류도 가능하지만

                  가장 간단하게 표현하는 방법이 (true) 왜냐하면 참은 언제나 참이니까.

{

  printf("hello, world");

}

 

 

2.

scratch)

repeat 50

say hello, world

 

c)

int counter = 0;

or int i = 0;

while ( i < 50 )

{

  printf("hello, world");

  i  = i + 1; or i++

}

 

여기서는 c가 이 코드를 해석하는 방식에 따라 자동으로 첫번쨰 줄로 돌아감.

 

or

 

 

 

 

3. for 루프

 

c) 

for (int i = 0; i < 50 ; i=  i + 1 )

{

  printf("hello, world")

}

 

for ( 루프의 경우엔 여기에 총 3개의 입력이 들어감. 입력을 구분은 ' ; ' 세미콜론으로)

for ( 변수를 받아오기 ; 계속 묻고자하는 불리언 표현 ; 앞의 질문의 답이 참일때 변수를 어떻게 수정할 것인가) ;

 

조건문 학습자료.pdf
0.38MB

 

 

 

 

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

데이터 종류

bool       (참/거짓 값을 가짐)

char       (딱 한개의 문자를 나타냄)

double    (더 많은 아주 많은 소수점을 가지는 수. float 의 long 버젼이라 생각하면 됌.)

float        (실수 , real number 소수점이 있는 수)

int          (정수)

long        (더 많은 비트를 사용해 더 큰 수를 나타넴)

string      (문자열)

...

 

함수

get_string

get_char

get_float

get_int

get_long

...

이는 모두 사용자에게 특정 값을 물어보고, 그들이 입력한 값을 사용할 수 있도록 해줌

like ask in scratch

 

 

형식 지정자

%c   char

%f    float, double

%i     int

%li    long

%s    string

...

 

int main(void) 는 초록 깃발이 클릭되면(프로그램이 시작을 의미하는 코드)

 

 

 

 

코드 연습

 

더보기

#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);

}

 

 

하지만 {} 사이의 두번째 줄은 줄일 수 있다.

 

{

  int age = get_int("what's your age?\n");

  printf("you are at least %i days old.\n", age * 365);

}

 

디자인적인 선택이 들어갈 수 있음

 

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

 

$ ./float
what's the price?100
Your total is 106.25. 

 

.2 는 소수점 자리를 2까지만 표기하라는 코드. 안쓸경우

$ ./float
what's the price?10000 
Your total is 10625.000000.

이런식으로도 나옴

 

 

홀짝 구분하는 프로그램 (parity)

더보기

#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");
    }
}

 

$ ./parity
n: 50
even

$ ./parity
n: 23141244
even

 

주석

 

// c에선 이거임

 

||  or

&& and

 

 

~c언어 라이브러리 관련 링크들~

 

https://opentutorials.org/module/3921/23557

 

입력과 출력1 - [c언어 기초]

printf () printf()는 사용가가 원하는 값을 화면에 출력하는 라이브러리 함수이며, 는 printf()가 미리 정의되어 있는 헤더 파일입니다.  printf()함수의 사용 규칙에 관한 다음 코드를 직접 작성

opentutorials.org

https://cs50.readthedocs.io/libraries/cs50/c/

 

CS50 Library for C

Installation: Ubuntu:$ curl -s https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh | sudo bash $ sudo apt install libcs50 Fedora:$ curl -s https://packagecloud.io/install/repositor...

cs50.readthedocs.io

https://ko.wikipedia.org/wiki/C_%ED%91%9C%EC%A4%80_%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC

 

C 표준 라이브러리 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. C 표준 라이브러리(C standard library)는 C 언어를 위한 표준 라이브러리로서, ANSI C 표준에 의해 명시되었다.[1] 이것은 상위 집합인 C POSIX 라이브러리와 동시에 개

ko.wikipedia.org

 

 

 

 

 

 

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

 

더 좋은 코드를 써보는 과정

 

cough0

더보기

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

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

 

$ ./cough0
cough
cough
cough

 

cough1

더보기

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

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

 

$ ./cough1
cough
cough
cough

 

사용자 정의 함수 1

더보기

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

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

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

 

하지만 사용자 정의 함수를 항상 위에 놔두면 정작 Main 이 아래로 밀리기에 이 순서를 바꾸는 방법이 있음

이는 디자인적으로 더욱 뛰어난 방향

 

예시

더보기

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

void cough(void); 

c언어는 위에서 아래로 왼쪽에서 오른쪽으로 밖에 못읽음. 그렇기에 단순히 사용자 정의 함수를 아래 쪽에 배치할 경우, 그것이 무엇인지 당장은 이해 할 수 없음. 그렇기에 위와 같은 코드를 미리 입력해서, 컴퓨터에게 이러한 이름의 사용자정의함수가 있음을 알려주고, 그다음에 컴퓨터가 그 함수를 발견했을때, 정의를 아직 읽지 못했음에도, 이러한 함수가 있음을 인지한 상태이기에 코드를 끝까지 읽어 정의 함수의 세부 내용을 파악하고 나서 결과를 도출하게 해줌.

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

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

 

cough3

발전된 사용자 정의 함수

 

더보기

#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;  우선컴퓨터에게 n이란 변수가 존재함을 명시해줌. 이것은 쓰레기 변수로 변수의 실제 값은 안중요
    do     do while 루프로, 먼저 행동을 한뒤에 조건을 받기에 유용함. 
    {
        n = get_int("Positive Integer: "); int 값을 사용자한테 받고 그걸 변수 n에 저장
    }
    while (n < 1);  만약 변수 n이 1보다 작을경우. (클 경우는 false이기에 코드는 여기서 스톱.
    return n;  n 값을 반려해라. 그리고 while 함수를 이용했기에(루프) 자동적으로 다시 코드를 처음부터 실행. 
}

 

 

마리오 블럭을 출력해보자

 

#######
#######
#######
#######
#######
#######
#######

 

더보기

#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++) 왼쪽에서오른쪽으로#을 n개만큼 출력하고
        {
            printf("#");
        }
        printf("\n"); 출력된가로#을 n줄만큼 아래로 출력해라
    }
}

 

$ ./mairo0
size: 7
#######
#######
#######
#######
#######
#######
#######
$

 

 

 

 

6) 하드웨의 한계

 

interger overflow 라고하는 하드웨어 한계에 의해 값이 망가지는 현상

 

ex) 3비트 환경에서 1씩 증가 하고 있을때, 111 (7) 에서 1이 추가되는 순간 000 으로 오류가 나는 하드웨어 한계에 의한 오류 현상.

 

코드 예시

1.

더보기

#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);
}

$ ./float
x: 1
y: 10
x / y = 0.10000000149011611938476562500000000000000000000000

2.

더보기

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

int main(void)
{
  for (int i =1; ; i *= 2)
  {
      printf("%i\n" ,  i);
      sleep(1);
  }
}

 

$ ./overflow
1
2
4
8
16
32
64

....

 

...

67108864
134217728
268435456
536870912
1073741824
overflow.c:7:22: runtime error: signed integer overflow: 1073741824 * 2 cannot be represented in type 'int'
-2147483648
0
0
0
0

...

 

 

 

 

'인강 > 모두를 위한 컴퓨터 과학 cs50 2019' 카테고리의 다른 글

배열 Array  (0) 2021.06.16

댓글