CS50x 2023 - Lecture 2 - Arrays
- Compiling
사실 이 make 라는 컴파일 명령어를 매뉴얼하게 풀면 아래와 같다.
clang 컴파일러를 써서 -o(for output) 옵션으로 hello를 hello.c로 컴파일 한다는것이고, cs50 library를 쓴다는 것이다. 참고로 저렇게 hello.c라고 명명해주지 않으면 그냥 디폴트로 a.out이란 파일이 생긴다.(a for assemble)
Compiling의 4단계는 다음과 같다.
1. preprocessing: 코드에서 가장 먼저 처리해야될 부분을 찾아 처리하는것. #등 특수문자로 시작되는 헤더파일 등을 코드에서 찾아 실제 위치에서 가져온 뒤, 현재 작업중인 파일로 복붙한다. 그래서 해당 코드가 헤더파일(대체로 library)에서 쓰는 함수들을 온전히 쓸 수있도록. 이렇게 복붙하는 과정은 컴파일 로그에 보이진 않고 뒷단에서 진행되는 것이다.
위의 예시에서 맨 윗 두줄이 #include~로 시작하여 header file을 불러오는 부분인데, 첫번째 줄이 #include <cs50.h>를 preprocess하여 실제 코드에서 쓰이는 함수의 정의를 가져온 모습이다. 전통적으로 저런 헤더파일들은 usr/include에 위치한다.
2. compiling: c code, python code등을 assembly code로 변환하는것이다. assembly code는 CPU가 직접 이해하고 실행할 수 있는 machine code로 변환되기 전의 텍스트 형태로 된 저수준 프로그래밍 언어이다. machine code보다는 사람이 이해하기 쉽게 만들어진 형태이지만, 여전히 고수준 언어(예: C, Python 등)보다는 낮은 수준의 언어로 분류된다.
위의 예시가 hello.c를 asembly code로 나타낸 모습이다. 각 명령어가 해당 CPU의 명령어 세트와 일치하며, 메모리 주소, 레지스터 등의 하드웨어 요소를 직접 조작할 수 있다.
3. assembling: assembly code를 CPU가 읽을 수 있는 0과 1로 이루어진 machine code로 변환하는 단계이다.
4. linking: 이렇게 변환된 machine code와 파일를 실행하기 위해 불러온 헤더파일들의 machine code를 linking하는 단계이다.
Decompiling: machine code를 c, python등 고수준 언어로 변환하는것(되돌려놓는것). Reverse Engineering에 속하며, 소프트웨어의 소스 코드가 없거나 원본 소스 코드를 소유하고 있지 않을 때, 프로그램의 동작을 이해하거나 수정해야 할 때 사용된다.
Debugging: print함수를 써서 코드 중간중간의 변수 값이 어떤지 확인해보거나, debugger를 써서 breaking point를 정하여 해당 시점까지의 변수값 변화를 확인해보는 식으로 debugging을 할 수 있음. (+rubber duck debugging)
Array: 함수 안에 array를 써서 평균값 내는 계산기 만드는 예시를 보여줌
19번째 줄처럼 빈 array를 함수 정의 안에 넣을 수 있다는게 key take away라고 함
String: String은 integer, char등 다른 type들과 달리 정해진 byte가 없기 때문에, 끝에 null값(\0)이 자동으로 붙음. 그 string의 끝을 명시하여 byte를 한정해서 주기 위함.
아래의 입력된 string의 문자들을 모두 uppercase로 바꿔주는 예시에서 string을 array처럼 다루는 것을 보여줌.
그렇게 찾은 소문자를 ASCII코드에 기반하여 숫자처럼 연산해서(-32) 대문자로 바꿔줄수 있음.
Command-line arguments: 아래의 예시에서 여태 int main(void)였던부분을 4번째 줄처럼 바꿈으로써 파일을 실행할때 arguments 받을 수 있게 했음.
이렇게 하면 command line에서 ./greet David 처럼 파일을 실행시키면서 바로input을 넣을수 있게 됨.
- 터미널에서 echo $? 을 치면 마지막으로 실행한 파일의 exit status를 알 수 있다. 보통은 0을 return하는데, 코드에서 return값을 조건에 따라 다르게주어 원하는 return값을 내보일 수 있다.