CS50

3. 배열

mingul 2020. 8. 31. 17:22

 

부스트코스에서 진행한 '모두를 위한 컴퓨터 과학(CS50 2019)'을 수강한 뒤 작성한 내용입니다.

몰랐던 내용을 위주로 정리했기 때문에 빠진 부분이 많을 수 있습니다.

 

1. 컴파일링

메인함수는 시작버튼을 누르는 것과 같다.

<stdio.h>는 헤더파일(라이브러리)

파이썬은 자동으로 컴파일된다.

make나 clang을 사용(컴파일)할 때의 작업 처리 단계

1. preprocessing(전처리) : #_____라이브러리의 실제 코드로 대체된다.

2. compiling : 소스코드를 머신 코드로 바꾸는 단계. 어셈블리어로 변경. 어셈블링(0과 1로 이루어진 머신 코드로 바뀌는 과정). clang이 수행하며, 어셈블리어를 입력으로 받는다.

3. linking : hello.c, cs50.c, stdio.c를 하나로 뭉친다.

  • 강의에서 궁금했던 점

stdio.h의 h는 헤더파일이라고 했는데, 그럼 hello.c 같은 파일도 헤더파일로 쓸 수 있나요? 

hello.c 와 같은 코드도 헤더 파일로 사용 가능합니다. .so 혹은 .a 파일은 이미 다른 누군가가 적어둔 코드가 있고 이 코드를 라이브러리 형태로 만들어 둔 것입니다. 그럼 링커는 어떻게 이런 라이브러리 파일을 찾아갈까요? 우리 컴퓨터 내부 어딘가에 모든 라이브러리가 모여있는 폴더(예, /usr/lib in Linux)가 있습니다. 사용자가 새로운 라이브러리를 설치할 때 해당 라이브러리의 .so 혹은 .a 파일이 이 폴더에 저장됩니다. 컴퓨터는 이미 라이브러리가 모여있는 이 폴더의 위치를 알고 있기 때문에 어떤 프로그램을 컴파일할 때 알아서 이 폴더를 찾아갑니다. 만약 이 폴더에 없는 특정 라이브러리를 사용하고 싶다면 컴파일할 때 옵션으로 사용하고 싶은 라이브러리의 경로를 줄 수도 있습니다. 즉, 여러분이 적은 hello.c와 같은 코드도 hello.so로 커파일 하면 충분히 가능합니다.

 

2. 디버깅

논리적 오류는 printf를 사용하여 확인하고, 문법적 오류는 에러 메시지를 확인한다.

IDE에서 디버깅 할 때, 행의 번호를 클릭하면 나오는 빨간점은 여기서 멈춘 뒤 사용자가 한 단계씩 진행할 수 있도록 미리 말해주는 것이다.

debug50이라는 프로그램을 사용할 때는 debug50 ./buggy2 로 실행.

노란색 줄은 디버거가 프로그램을 이 지점에서 멈췄으니 여기저기 살펴볼 수 있다는 의미이다.

스텝 오버 : 프로그램 실행 과정을 느리게 만드는 것으로 메모리 안에서 벌어지는 일을 실행 도중에 확인 가능하다.

 

3. 코드의 디자인

코드를 작성할 때는 나와 다른 사람들이 알아보기 쉽게, 유지보수하기 쉽도록 해야 한다.

 

4. 배열 1

문자 → 정수(ASCII) → 이진법

형변환 : 하나의 자료형을 다른 종류로 바꾼다. 

형변환은 형식지정자를 바꿔준다.

 

5. 배열 2

실수로라도 변하지 않는 값을 만들고 싶다면 상수를 사용하고, 메인함수 위에 작성한다. (ex. const int N = 3;) 이런 상수를 전역 변수(상수 바깥에서 선언하는 변수)라고 한다.

프로토타입은 메인함수 위에 반환값 함수명 (입력값); 으로 작성한다.

C에서 정수를 정수로 나누면 정수가 출력된다 → 형변환으로 처리

C의 배열은 스스로의 길이를 기억하지 않는다.

반올림이 가능하다.

  • 강의에서 궁금했던 점

자바나 파이썬은 배열 스스로의 길이를 기억하나요? 예시가 궁금합니다.

자바나 파이썬은 배열의 길이를 스스로 기억할 수 있습니다. C는 메모리에 값을 적고 그 값을 얼마큼 읽고 어떻게 해석하는지가 모두 프로그래머에게 달려있습니다. 하지만, 자바나 파이썬의 경우 객체 기반으로 구현되어 있습니다. array A를 만들면 프로그램은 A를 계속 배열로 인식합니다. 그리고 A에 대한 메타정보 또한 들고 있습니다. 따라서 자바에서는 A.length로 파이썬에서는 len(A)로 배열의 길이를 알 수 있습니다. 사진에서 보이듯 파이썬은 A라는 변수의 타입을 type(A)를 통해 확인할 수도 있습니다.

 

6. 문자열과 배열

배열 내 원소의 순서는 바이트 수와 무관하다. int가 4바이트라고 해서 0번째, 4번째, 8번째처럼 셀 필요가 없다.

string은 char의 배열이다.

string은 정해진 크기를 가질 수 없다.

널문자 \0, 8개의 비트가 모두 0을 나타내는 상태이며 문자열의 끝을 나타낸다. 예를 들어, HI!는 H, I, !, \0의 4바이트가 필요하다. 즉, 글자수+1 바이트만큼의 공간을 차지한다.

문자열의 출력방식에서 printf가 하는 일은 일종의 루프를 만들어 첫번째 글자부터 반복해서 확인한다.(널문자가 아니면 출력, 맞으면 break)

문자열의 길이 제한은 컴퓨터가 가진 메모리의 용량만큼이다.

 

7. 문자열의 활용

'\0'으로 쓰는 이유는 \n처럼 하나로 묶여있기 때문이다. 

프로그래밍이란 추상화를 이용해서 복잡한 기계어를 간단하게 처리하는 것이다. 

for문 안에 (strlen(s))처럼 함수를 넣으면 계속 함수가 호출되기 때문에 좋지 않은 디자인이다.

for문 괄호 안에 두 변수의 타입이 같다면 뒤에 오는 하나는 타입 선언을 생략해도 된다.

 

8. 명령행 인자

-o : 원하는 파일로 출력을 바꿀 수 있다.

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

argv는 관습적인 표현, 인자 벡터를 의미, 인자들의 배열이라는 뜻이다.

argc는 인자 갯수를 의미한다.

C에서 프로그램 이름 뒤에 단어를 입력하면 그 단어들은 argv라는 배열에 들어간다.

argc에는 단어의 갯수가 저장된다.

메인 함수에 반환값이 있는 이유는 기본적으로 반환값을 가지며, 특별한 이유가 없으면 0을 반환한다. 0은 보통 문제 없음을 의미한다.

프로그램을 중단하려면 아무 문제 없다는 의미인 return 0을 반환하고, 문제가 있다면 다른 값을 반환한다.

argv에서는 처음에 입력하는 프로그램의 이름이 argv[0]에 저장된다. 그 다음에 첫번째로 입력하는 인자가 argv[1]이다.

return 값이 생략되어도 main함수에서는 암묵적으로 0을 반환한다.