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

배열 Array

by 금의야행 2021. 6. 16.
#include <stdio.h>

int main(void)

  {
      printf("hello world\n");
      
  }

stdio.h 는 헤더 파일로, 남이 이미 작성한 코드인 라이브러리임. clang 컴파일을 할 때 prinf가 무엇인지 알려주는 역할

 

clang 

 

https://www.boostcourse.org/cs112/joinLectures/41487?isDesc=false 

 

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

부스트코스 무료 강의

www.boostcourse.org

 

 

 

 

1. 컴파일링

컴파일 / compiling 은 총 네개의 단계로 구성됌

 

eg)

hello.c

#include <cs50.h>

#include <stdio.h>

 

int main(void)

  {

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

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

  }

 

  • preprocessing (전처리 단계)

 

#include <cs50.h>

#include <stdio.h>

clang 혹은 make로 프로그램이 실행되면 #으로 시작되는 코드는 해당 파일(<cs50.h>) 안의 실제 코드로 대체됌.

#include <cs50.h> -> string get_string(string prompt); (와 기타등등)

 

 

  • compiling

프로그램이 컴파일 될 때, 전처리 단계를 거치고

소스 코드에서 어셈블리 코드로 (중간단계) 변환 됌

 

  • assembling

어셈블리 코드에서 0과 1로 이루어진 머신 코드로 변환하는 단계

 

 

  • linking

마지막 단계에서 머신 코드들을 하나의 파일로 합침 

예시의 코드 안에 총 3개의 파일, cs50.c, stdio.c, hello.c 가 있는데 모두 어셈블리 코드로 변환된 후

마지막 단계인 linking에서 하나의 큰 파일로 합쳐짐.

-> hello 아님 a.out

 

 

과거엔 01에서 어셈블리 언어 그리고 지금의 c, c++ , python 등의 프로그래밍 언어로 발전해옴.

 

소스 코드 (input) 에서 머신코드 (output) 사이에서 위와 같은 과정이 일어나고 있음.

 

 

컴파일링 학습자료.pdf
0.30MB
3. 배열 강의자료.pdf
0.39MB

 

2. 디버깅

 

컴퓨터 프로그래밍 수업에서 배울 수 있는 아주 중요한 기술은 코드 작성 뿐 아니라 코드를 디버깅하는 것이다.

 

문법적 버그

 

논리적 오류

 

논리 오류가 생길 경우 printf 함수를 통해 실제로 어떤게 발생하고 있는지 시각화해서 오류를 찾아내자. 

그냥 화면만 뚫어지게 쳐다보는게 아니라.

 

 

sandbox.cs50.io 에서 더 발전된 버젼인 cs50 ide 도입

https://ide.cs50.io/

 

CS50 IDE

integrated development environment for students and teachers

ide.cs50.io

 

 

디버거를 사용은 c 뿐만 아니라 다른언어에서도 평생 사용할 수 있는 기술

 

디버거를 사용해, 코드를 한 단계 한 단계식 실행해 실제로 프로그램이 어떻게 진행되고 있는지를 쪼개서 확인해가며 논리 오류가 생긴 지점을 시각적으로 발견할 수 있음.

 

 

디버깅 학습자료.pdf
0.27MB

 

3. 코드의 디자인

 

코드 작성만큼 중요한 것이 바로 코드가 정확한지를 확인하는 테스트를 만드는 것

 

코드 작성 시에는 나 자신과 다른 사람들이 읽기 쉽도록 그리고 무엇보다 유지보수하기 쉽게 작성해야함.

 

고무 오리

때로는 코드에 포함된 오류를 해결할 때 앞서 소개한 help50, debug50, check50과 같은 프로그램들이 존재하지 않거나, 있다 하더라도 디버깅에 큰 도움이 안 될 수 도 있습니다.

이 때는 먼저 한숨 돌리고 직접 곰곰히 생각해보는 수 밖에 없습니다.

한가지 유명한 방법으로 ‘고무 오리’와 같이 무언가 대상이 되는 물체를 앞에 두고, 내가 작성한 코드를 한 줄 한 줄 말로 설명해주는 과정을 거쳐볼 수 있습니다.

이를 통해 미처 놓치고 있었던 논리적 오류를 찾아낼 수도 있습니다.

 

 

 

 

 

4. 배열 (1)

메모리

C에는 아래와 같은 여러 자료형이 있고, 각각의 자료형은 서로 다른 크기의 메모리를 차지합니다.

  • bool: 불리언, 1바이트
  • char: 문자, 1바이트
  • int: 정수, 4바이트
  • float: 실수, 4바이트
  • long: (더 큰) 정수, 8바이트
  • double: (더 큰) 실수, 8바이트
  • string: 문자열, ?바이트

 

RAM

은 소프트웨어 구동 시에 정보가 저장되는 곳

 

 

배열 (array)

 

C에서 여러개의 값을 가진 하나의 변수를 만들고 싶을 때, 배열이라고 하는 걸 사용함.

배열은 값들의 리스트로 모두 같은 자료형의 값들이 같은 변수에 저장됌.

 

 

전역 변수(global variable)

 

함수 바깥에서 선언하는 변수

 

 

 

 

 

5. 문자열과 배열

 

문자열 (string)은 문자들(char)의 배열임. 

eg) string name = "string"

s[0] == s

s[1] == t

...

s[4] == g

엄밀히 따지면 틀린 말. 

 

string 은 글자 수 만큼 바이트가 증가

그러면 문자가 언제 끝나는지 컴퓨터에 알려줘야함.

 

이를 널 문자라고 부름  \0

 

그래서 길이가 3인 문자열은 사실 4바이트를 차지.

 

 

코드 예시

더보기

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

int main(void){


string names[4];

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

엠마이름을출력하고 싶을때

1.
printf("%s\n", names[0]);  

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

}

 

~/ $ make names
clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow    names.c  -lcrypt -lcs50 -lm -o names
~/ $ ./names
EMMA
EMMA
~/ $ 

2번이 바로 string 문자열을 출력할 때 거치는 단계를 직접 지정한 형태

 

메모리의 관점에서 프로그램이 실행 됄 때

E M M A \0 이렇게 총 5바이트를 사용해 메모리에 저장함. (RAM)

 

메모리의 구체적인 위치를 지정하기만 하면 그 메모리 칸에 어떤 데이터가 들었는지 얼마든지 알 수 있음.

 

이를 통해 printf 나 get_string 같은 함수가 마법같이 발생하는게 아니라, 이런식으로 물리적인 영역을 분명히 거치며 조작을 통해 실행됨을 이해하기만 하면됌.

 

배열과 문자열 학습자료.pdf
0.35MB

 

 

 

 

 

 

7. 문자열의 활용

 

메모리를 더 사용할 것이냐 vs 프로그램 시간을 단축시킬 것이냐.

 

더보기

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

int main(void)
{
    string s = get_string("Input: ");
    printf("Output:\n");

 

1. for (int i = 0, i < strlen(s); i++) strlen은 string.h 에서 문자열의 길이로 정의된 코드

이경우 반복적으로 프로그램은 strlen(s)가 몇인지 확인하고 확인하고 그럼. 시간이 더 오래걸림

 

2.    let n = strlen(s)

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

이경우 변수가 추가되어 메모리가 더 할당 되지만, for 문 이전에 이미 값이 정의되서 시간이 덜걸림 (큰차이가 아니더라도)

 

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

마지막으론 2번을 그냥 보기 좋기 적은 버젼


    { 
        printf("%c\n", s[i]);
    }
}

 

terminal

~/ $ make names
clang -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow    names.c  -lcrypt -lcs50 -lm -o names
~/ $ ./names
Input: emma
Output:
e
m
m
a
~/ $ 

 

 

매우 기계어에 가까운 방식으로 소문자를 대문자로 바꾸기

 

더보기

#include <cs50.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++)
    {
        if (s[i] >= 'a' && s[i] <= 'z') 만약단어가a부터z사이에존재한다면(소문자라면)
        {
            printf("%c", s[i] - 32); ascii 코드에서 대응하는 십진법 숫자값에 32를 뺸 값의 char 문자를 출력해라
        }
        else
        {
            printf("%c", s[i]);
        }
    }
    printf("\n");
}

 

하지만 이미 존재하는 라이브러리를 사용하면 고작 한줄의 코드로 바꿀 수 있음. 

남들이 써둔 코드를 잘 써먹자~

 

 

 

 

 

9. 명령행 인자

 

명령행 인자는 보통 실행하고자 하는 프로그램 뒤에 적는다

ex) clang hello.c -o hello

 

 

우리가 여태껏 많이 사용해온 main 함수를 보다 자세히 들여다볼 때가 왔습니다.

main도 그 형태를 보면 하나의 함수임을 알 수 있는데요, 이젠 더이상 main() 안에 기계적으로 void 라고 입력하는 대신 아래 코드와 같이 argc, argv 를 정의해보겠습니다.

 

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

 

 

여기서 첫번째 변수 argc는 main 함수가 받게 될 입력의 개수입니다.

그리고 argv[]는 그 입력이 포함되어 있는 배열입니다. 프로그램을 명령행에서 실행하므로, 입력은 문자열로 주어집니다.

따라서 argv[]는 string 배열이 됩니다.

 

argv[0]는 기본적으로 프로그램의 이름으로 저장됩니다.

만약 하나의 입력이 더 주어진다면 argv[1]에 저장될 것입니다.

예를 들어 위 프로그램을 “arg.c”라는 이름으로 저장하고 컴파일 한 후 “./argc”로 실행해보면 “hello, world”라는 값이 출력됩니다.

명령행 인자에 주어진 값이 프로그램 이름 하나밖에 없기 때문입니다.

하지만 “./argc David”로 실행해보면 “hello, David”라는 값이 출력됩니다.

명령행 인자에 David라는 값이 추가로 입력되었고, 따라서 argc 는 2, argv[1] 은 “David”가 되기 때문입니다.

 

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

CS50 C언어  (0) 2021.06.09

댓글