컴퓨팅 사고력 기르기 (심화 편) (4)

productuidev·2022년 8월 25일
0

IT/CS 지식 쌓기

목록 보기
22/24
post-thumbnail

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

하버드대학의 최고 인기강좌, 데이비드 말란 교수님의 CS50입니다. 프로그래밍을 처음 공부하는 비전공자 분들도 쉽고 재미있게 학습하실 수 있습니다.

boostcourse 바로가기
https://m.boostcourse.org/cs112/

배열

컴파일링

  • 작성한 C 코드를 실행하기 위해서는 컴파일링을 해줘야 함
  • C문법로 작성된 텍스트 형식의 파일은 컴파일링시 구체적으로 어떤 단계를 거쳐서 컴퓨터가 해석 가능한 파일로 변환될까?

컴파일링 어셈블링 링킹

  • int main(void) : 프로그램의 시작점 = 실행 버튼 클릭
  • printf : 출력을 담당하는 함수, 이것을 쓰려면 stdio.h 라이브러리 필요

Clang 컴파일러

프로그램을 컴파일할 때 printf가 무엇인지 알려주는 역할
코드를 clang hello.c로 컴파일하면, ./a.out 명령으로 프로그램 실행 시
컴퓨터가 이해하는 0과 1로 가득찬 a.out이라는 파일을 생성해 실행 가능하게 함

  • clang -o hello hello.c : hello로 컴파일
  • clang -o hello hello.c -lcs50 : cs50 라이브러리를 사용한 프로그램 컴파일

명령어를 실행 시 일어나는 4가지 과정

1) 전처리(Precompile)

  • 전처리기에 의해 수행 : 실질적인 컴파일이 이루어지기 전에 무언가를 실행
  • #include는 전처리기에게 다른 파일의 내용을 포함시키라고 알려줌

2) 컴파일(Compile)

  • 전처리한 소스 코드를 어셈블리 코드로 변환시키는 단계
  • C 코드를 어셈블리어라는 저수준 프로그래밍 언어로 컴파일

3) 어셈블(Assemble)

  • 컴퓨터의 중앙처리장치가 프로그램을 어떻게 수행해야 하는지 알 수 있는 명령어 형태인 연속된 0과 1들로 바꿔주는 작업
  • 어셈블리 : C보다 연산의 종류가 훨씬 적지만, 여러 연산들이 함께 사용되면 C에서 할 수 있는 모든 것들을 수행할 수 있음. 컴퓨터가 이해할 수 있는 언어와 최대한 가까운 프로그램으로 만들어줌.
  • 어셈블러 : 변환작업을 수행하는 프로그램

4) 링크(Link)

  • 여러 개의 다른 오브젝트 코드 파일을 실행 가능한 하나의 오브젝트 코드 파일로 합쳐줌
  • 컴파일을 하는 동안에 CS50 라이브러리를 링크하면 오브젝트 코드는 GetInt()나 GetString() 같은 함수를 어떻게 실행할 지 알 수 있게 됨

생각해보기

만약 컴파일링 과정을 거치지 않기 위해 바로 머신코드로 우리가 원하는 프로그램을 작성하려고 한다면 어떤 문제가 있을까요?

디버깅

  • 버그 : 코드에 들어있는 오류, 프로그램의 실행에 실패하거나 프로그래머가 원하는 대로 동작하지 않게 될 때
  • 디버깅 : 코드에 있는 버그를 식별하고 고치는 과정
  • 디버거 : 디버깅을 고칠 때 사용하는 프로그램. 프로그램을 특정 행에서 멈출 수 있게 해주기 때문에 버그를 찾는데 도움. 멈춰진 그 지점(중지점)에서 무슨 일이 일어나는지 볼 수 있음.
  • 프로그래머는 디버거을 통해 프로그램이 내리는 모든 결정들을 단계별로 따라갈 수 있고, 이를 고치는 과정을 디버깅이라 할 수 있음

생각해보기

디버깅을 도와주는 프로그램은 어떤 경우에 더 큰 도움이 될까요? 만약 이런 프로그램의 도움 없이 직접 디버깅을 해야 한다면 어떻게 코드를 작성하는 것이 좋을까요?

코드의 디자인

코드의 정확성과 디자인

규모가 큰 프로그램을 작성할 때는 보통 한 사람이 아닌 여러 사람들이 함께 작업을 진행하게 된다. 이 때는 내가 기여한 부분이 프로그램에 오류를 발생시키지 않도록 주의를 기울여야 한다. 또한 코드의 내용 뿐만 아니라 그 형식도 신경써야 한다. 같은 내용이라 하더라도 어떻게 표현하느냐에 따라 코드를 이해하고 수정하는 속도가 달라질 수 있기 때문.

  • check50 : 자동 검사 프로그램
    각자가 수정한 코드가 전체 프로그램의 정확성을 해치지 않는지 쉽게 확인할 수 있음
  • style50 : 코드 심미적 검사 프로그램
    공백의 수나 줄바꿈과 같은 것들은 코드의 실행에 직접적으로 영향을 주지는 않지만 코드를 작성하는 사람들이 코드를 읽고 이해하는데 영향을 줌
  • 고무오리 : 무언가 대상이 되는 물체를 앞에 두고, 내가 작성한 코드를 한 줄 한 줄 말로 설명해주는 과정 (= 정적분석)

생각해보기

만약 여러 사람들이 함께 참여하는 프로젝트에서, 각자가 작성하는 코드 스타일 서로 다르다면 어떤 비효율적인 일이 발생할까요?

배열

특정 자료형의 변수를 선언하면 이는 메모리상 어딘가에 특정 크기만큼의 자리를 차지하게 됩니다. 만약 비슷한 종류의 값을 모아서 저장하고 싶다면 어떻게 해야 할까요? 메모리상에서 여러 값을 연이어서 저장하고 사용하는 방법과 그 이점을 알아보겠습니다.

C의 자료형 메모리

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

RAM

  • 물리적 칩이 메모리 역할을 함
  • 쉽게 생각하면 아래 사진에서 여러 개의 노란색 사각형이 메모리를 의미하고, 작은 사각형 하나가 1바이트를 의미한다고 볼 수 있다
  • char 타입의 변수를 하나 생성하고, 그 값을 입력한다고 하면 위 사진에서 한 사각형 안에 그 변수의 값이 저장

배열을 사용하는 이유

세 개의 점수를 저장하고 그 평균을 출력하는 프로그램

  • 점수의 개수가 더 많아진다면 이 프로그램은 많은 부분을 수정해줘야 함. 이 때 활용할 수 있는 것이 배열의 개념
  • 배열은 같은 자료형의 데이터를 메모리상에 연이어서 저장하고 이를 하나의 변수로 관리하기 위해 사용

  • int scores[3] : int 자료형을 가지는 크기 3의 배열을 scores 라는 이름으로 생성하겠다는 의미
  • 배열의 인덱스는 0부터 시작하기 때문에, scores의 인덱스는 0, 1, 2 세 개가 있음
    이 인덱스를 변수명 뒤 대괄호 [ ] 사이에 입력하여 배열의 원하는 위치에 원하는 값을 저장하고 불러올 수 있음

전역 변수

  • 코드 전반에 거쳐 바뀌지 않는 값

생각해보기

  • 실생활의 어떤 데이터를 배열로 표현할 수 있을까요?

문자열과 배열

string 자료형을 사용하였습니다. ‘문자열’이라는 단어는 다시 말해 문자가 ‘나열되어 있다’ 또는 ‘배열되어 있다’ 라는의미로 추측해 볼 수 있습니다. 이런 관점에서 봤을 때 string 자료형은 C에서 정확히 어떻게 정의되어 있을까요?

  • string s = “HI!”; 과 같이 문자열 s가 정의되어 있다고 생각해보면 s는 문자의 배열이기 때문에 메모리상에 아래 그림과 같이 저장되고, 인덱스로 각 문자에 접근할 수 있다. ‘\0’은 문자열의 끝을 나타내는 널 종단 문자이다.

생각해보기

널 종단 문자는 왜 필요할까요?

문자열의 활용

문자열 안에 포함되어 있는 문자를 검색하기 위해서는 어떻게 해야 할까요? 또 특정 문자를 다른 문자로 바꾸기 위해서는 어떻게 해야 할까요?

문자열의 길이 및 탐색

  • 인덱스의 문자가 널 종단 문자, 즉 ‘\0’와 일치하는지 검사하는 것
  • s라는 문자열이 있다고 할 때 for (int i = 0; s[i] != ‘\0’; i++) { ..} 과 같은 루프를 사용

문자열 탐색 및 수정

  • s의 길이만큼 for 루프를 돌면서, 각 인덱스에 해당하는 문자가 ‘a’보다 크고 ‘z’보다 작은지 검사 (소문자인지 검사)
  • 문자의 대소비교가 가능한 이유는 ASCII값, 즉 그 문자가 정의되는 ASCII 코드 상에서의 숫자값으로 비교할 수 있기 때문
  • 알파벳의 ASCII 값을 잘 살펴보면 각 알파벳의 소문자와 대문자는 32씩 차이가 남을 확인할 수 있음
  • 각 문자가 소문자인 경우 그 값에서 32를 뺀 후에 ‘문자’ 형태로 출력하면 대문자가 출력

생각해보기

string.h와 ctype.h의 라이브러리에 다른 어떤 함수가 있는지 확인해 보고, 어떤 함수를 어떻게 활용해 볼 수 있을지 생각해봅시다.

  • string.h와 ctype.h를 검색해보시면 사람들이 잘 정리한 글을 찾을 수 있을 것입니다. 코딩에서 자기가 검색해서 공부해보는 것도 매우 중요하기 때문에 직접 찾아보도록 하겠습니다.

명령행 인자

make나 clang과 같은 프로그램을 실행할 때 컴파일하고자 하는 코드 외에도 컴파일 후 저장하고자 하는 파일명과 같이 추가적인 정보를 함께 줄 수도 있습니다. 이런 정보들을 명령행 인자 라고 부릅니다. 우리가 작성하는 프로그램에서도 명령행 인자를 받을 수 있도록 설계할 수 있습니다.

  • argc : main 함수가 받게 될 입력의 개수
  • argv[] : 그 입력이 포함되어 있는 배열 (string 배열)

  • argv[0] : 기본적으로 프로그램 이름으로 저장
  • argv[1] : 하나의 입력이 추가되면 거기에 저장됨
  • 컴파일한 후 만약 ./argc David로 실행하면 "hello, David"라는 값이 출력됨. 명령행 인자에 David라는 값이 추가로 입력되었고, argv[1]에는 David가 들어감

생각해보기

명령행 인자는 프로그램의 확장성에 어떤 도움이 될까요? 구체적인 예시를 떠올려보세요.


개발자 시그니처를 고양이에서 오리로 바꿔야 할 거 같은...

profile
필요한 내용을 공부하고 저장합니다.

0개의 댓글