ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Loops, functions | CS50 Week 1
    Computer Science/CS 50 Harvard 2021. 11. 6. 23:30

    Harvard CS50 강의를 한글로 정리한것입니다.

     

    야옹(meow)하고 세번 프린트 하는 코드를 어떻게 만들 수 있을까?

    #include <stdio.h>
      
    int main(void)
    {
        printf("meow\n");
        printf("meow\n");
        printf("meow\n");
    }

    세번 프린트 하면 된다! 컴파일을 하고 돌려보자.

    > make meow
    clang     meow.c  -lcs50 -o meow
    > ./meow
    meow
    meow
    meow

    잘 돌아간다. 하지만 100번 프린트하고싶다면? 1000번, 10000번은? 이를 위해서 loop을 이용해서 더 나은 디자인의 코드를 완성해보자.

     

    while

    Scratch 블락과 같은 동작을 할 수 있는 while loop을 이용하면, 조건에 따라서 영원히 또는 어떤 경우에 괄호안 동작을 하게끔 할 수 있다.

    while (true)
    {
        printf("meow\n");
    }

    while loop은 괄호안 조건이 true일때만 동작하는데, 위의 예시는 항상 true이기 때문에, 멈추지않고 meow를 프린트하게 된다. 그렇기때문에 아래와같이 3이라는 조건을 만들어서 3번만 loop을 돌게 만들 수 있다.

    int counter = 0;
    while (counter < 3)
    {
        printf("meow\n");
        counter = counter + 1;
    }

    counter라는 variable을 만들어서 0으로 설정해놓고, loop이 돌때마다, 몇번째 loop인지 카운팅을 하는 용도이다. while 의 조건을 counter < 3 으로 바꿔줘서, counter가 3보다 작을때만 동작을 하게끔 설정해준다. 매번 loop이 반복을 할 때 마다, 우리는 "meow"라는 문장을 보게될것이고, 이때마다 counter는 1씩 더해진다. 이 코드를 아래와같이 조금 단순화 시킬 수 있다.

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

    기계만 알아들으면 되기 때문에, 간단하게 i 로 바꾸어주고, 짧게 i++ 로 바꾸어줬다.

     

     

    for

    for loop을 이용해서 똑같은 동작을 하는 프로그램을 만들수도 있다.

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

    while loop에서 사용했던 로직과 거의 비슷하지만 시작과 끝이 어디인지 정확히 알 때 사용을 많이 한다. for loop에게는 3가지 정보를 세미콜론(;)으로 나눠서 알려주어야한다. 처음은 i를 만들어서 0으로 만든다는 정보를 주고 (int i = 0), 매 loop마다 조건이 맞는지 체크하기 위한 정보를 주고 (i < 3), 그리고 loop이 한차례 끝나면 변경시킬 것을 알려준다. 여기서는 i를 1씩 더해준다고 명시했다.

     

    while loop과 다른점중 하나는, for loop에서는 for loop에서 만들어진 variable은 loop 안에서만 사용하고 접근할 수 있다. 반면에, while loop 밖에서 선언했던 i는 while loop이 끝나도 사용할 수 있다.

     

    loops에 대해서는 추가 영상 자료도 준비되어있었다.

     

    function

    Scratch에서 custom block을 만들었던것처럼, C에서도 function을 만들어서 사용할 수 있다.

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

    meow라는 단어를 프린트하는 meow라는 프로그램을 만들어서 main method에서 부를 수 있다. void meow(void)에서, 첫번째 void는 return값이 없다는 뜻이고, parentheses 안에 있는 void의 뜻은 이 함수(function)은 어떠한 argumetns 또는 input을 받지 않는다는 뜻이다. 프로그램을 컴파일하고 실행시켜보자.

    > make meows
    clang     meows.c  -lcs50 -o meows
    > ./meows
    meow
    meow
    meow

    잘 동작한다. 하지만 meow function을 아래쪽으로 옮기면 어떨까?

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

    코드를 수정하고 다시 컴파일 후 돌려보았다.

    > make meows
    clang     meows.c  -lcs50 -o meows
    meows.c:7:9: error: implicit declaration of function 'meow' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
            meow();
            ^
    meows.c:11:6: error: conflicting types for 'meow'
    void meow(void)
         ^
    meows.c:7:9: note: previous implicit declaration is here
            meow();
            ^
    2 errors generated.
    make: *** [meows] Error 1

    에러가 발생한다. 첫번째로, "implicit declaration"라는 에러인데, meow라는 함수를 사용했으나, 그게 무엇인지 알 수 없다는 내용이다. 이 함수가 무엇인지 정의되기 전에 사용되는것이 허용되지 않는다. 컴파일러는 우리 코드를 위에서부터 아래로 읽기 때문에 meow라는 함수가 존재하는지 모른다. 이 문제를 prototype을 선언해주는것으로 해결할 수 있는데, 컴파일러에게 "우리가 이런 function을 나중에 정의할것인데 이런 타입을 리턴할것이고 argument들은 이런것을 주는 함수이다" 라고 알려주는것이다.

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

    수정한 코드는 위와 같다. void meow(void라는 prototype을 main 전에 선언해주는것이다. 이 라인을 읽을때까지는 아직 코드가 실행되는것이 아니다.

     

    이후, meow function을 조금 발전시켜서, argument를 받을 수 있게 수정할수도 있다.

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

    void meow(int n) 으로 수정해서 아무것도 안 받던 함수에서 integer인 input, n을 받는 구조로 바꾸었다. 그리고 loop에서는 i < 3 대신 i < n 으로 바꿔줌으로써, 0부터 n 전까지, 즉 n 회의 loop을 돌게 할 수 있다. 그리고, main에서 meow를 부르고, 숫자를 줌으로써 위 코드에서는 3회가 프린트된다.

     

    우리가 사용하고있는 header files (.h 로 끝나는 파일들)은 위와같은, void meow(int n),와 같은 prototypes들을 담고있다. 그리고 library files들은 실제 이 함수들의 implementation을 담고있다. 추후에 main이 어떻게 inputs를 받고 outputs를 보내는지에 대해서 다룰것이다.

     

     

    Reference

     

    댓글

Designed by Tistory.