[CS50 2019] 2. Array
모두를 위한 컴퓨터 과학
1. 컴파일
소스코드를 오브젝트 코드(기계어)로 변환시키는 과정
1️⃣ 전처리 (Precompile)
- 컴파일의 첫번째 단계로, 전처리기에 의해 수행
- #으로 시작되는 C 소스 코드는 전처리기에게 실질적인 컴파일이 이루어지기 전에 무언가를 실행하라고 알려줌
- ex.
#include <stdio.h>
2️⃣ 컴파일 (Compile)
- C 코드를 어셈블리어라는 저수준 프로그래밍 언어로 컴파일
- 컴파일러라는 프로그램이 수행
- 이 단계에서 오류가 발생하면 컴파일러는 오류 메세지를 출력하고 프로그램을 생성하지 않음
3️⃣ 어셈블 (Assemble)
- 어셈블리 코드를 오브젝트 코드로 변환시키는 것
- 컴퓨터의 중앙처리장치가 프로그램을 어떻게 수행해야 하는지 알 수 있는 명령어 형태인 연속된 0과 1들로 바꿔주는 작업
- 어셈블러라는 프로그램이 수행
4️⃣ 링크 (Link)
- 링커는 여러 개의 다른 오브젝트 코드 파일을 실행 가능한 하나의 오브젝트 코드 파일로 합쳐줌
- 컴파일을 하는 동안 외부 라이브러리를 링크하면 함수나 변수의 정의와 참조 해결
2. 버그와 디버깅
✔ 버그 (bug)
- 코드에 들어있는 오류
- 버그로 인해 프로그램의 실행에 실패하거나 프로그래머가 원하는 대로 동작하지 않음
✔ 디버깅 (debugging)
- 코드에 있는 버그를 식별하고 고치는 과정
- 프로그래머는 디버거라는 프로그램을 사용하여 디버깅을 하게 됨
- 디버거는 프로그램을 특정 행에서 일시 중지 할 수 있으며 이를 통해 디버깅을 도움
3. 메모리
- C에는 여러 자료형이 있고, 각각의 자료형은 서로 다른 크기의 메모리를 차지한다.
- 컴퓨터 안의 RAM이라고 하는 물리적 칩이 메모리 역할을 한다.
✔ 자료형에 따른 메모리 할당
- bool: 불리언, 1byte
- char: 문자, 1byte
- int: 정수, 4byte
- float: 실수, 4byte
- long: (더 큰) 정수, 8byte
- double: (더 큰) 실수, 8byte
- string: 문자열, ?byte
4. 배열 (Array)
같은 자료형의 데이터를 메모리 상에 연이어서 저장하고 이를 하나의 변수로 관리하기 위해 사용
배열의 선언
int ages[5];
- 배열에 저장되는 자료의 유형을 명시
- 배열의 이름 지정
- 이름 뒤의 대괄호 안에는 배열의 크기가 들어감
인덱스 (index)
- 배열 안에 들어있는 특정 값에 접근하기 위해 쓰이며, 몇 번째 값인지를 가리킴
- 배열의 인덱스는 0으로 시작
- 배열 인덱스의 값은 일반 변수와 같이 취급 (연산이나 할당 연산자 적용 가능)
- 배열의 각 값은 인덱스 숫자로 참조하기 때문에 배열을 반복문으로 돌리기 쉬움
✔ 예시 코드
#include <stdio.h>
float average(int length, int array[]);
int main(void)
{
// 사용자로부터 점수의 갯수 입력
int n;
printf("Scores: ");
scanf("%d", &n);
// 점수 배열 선언 및 사용자로부터 값 입력
int scores[n];
for (int i = 0; i < n; i++)
{
printf("Score %i: ", i + 1);
scanf("%d", &scores[i]);
}
// 평균 출력
printf("Average: %.1f\n", average(n, scores));
return 0;
}
// 평균을 계산하는 함수
float average(int length, int array[])
{
int sum = 0;
for (int i = 0; i < length; i++)
{
sum += array[i];
}
return (float) sum / (float) length;
}
average
함수: 매개변수로 배열의 길이length
와 배열 자체array
를 받아서 평균값을 반환main
함수: 사용자로부터 점수의 갯수n
을 입력받아 배열의 크기를 동적으로 할당
5. 문자열
- 문자열은 char 값들(문자 자료형 데이터)의 배열을 나타냄
- 문자열의 마지막 인덱스는 널(null)로 끝나며,
\0
으로 나타냄- 널 종단(null-terminator): 문자열에게 문자열이 끝났고 더 이상의 문자가 남아있지 않다고 말하는 문자
✔ 예시 코드
#include <stdio.h>
int main(void)
{
// 문자열 배열 선언 및 초기화
char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
// 배열 전체 출력
printf("%s\n", greeting);
// 각 문자 개별 출력
printf("%c%c%c%c%c\n", greeting[0], greeting[1], greeting[2], greeting[3], greeting[4]);
return 0;
}
>>
Hello
Hello
문자열 처리 함수
6. 명령행 인자
- 프로그램이 실행될 때 프로그램에 전달되는 값들을 의미
- 프로그램이 실행되면 운영체제는 명령행 인자를 사용하여 프로그램에 추가적인 정보를 전달
argc
& argv[]
argc
: main 함수가 받게 될 입력의 개수argv[]
: 그 입력이 포함되어 있는 배열- 프로그램은 명령행에서 실행하므로, 입력은 문자열로 주어진다. 즉,
argv[]
는 string 배열
✔ 예시 코드
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc == 2)
{
printf("hello, %s\n", argv[1]);
}
else
{
printf("hello, world\n");
}
return 0;
}
이 코드는 명령행 인자를 사용하여 프로그램을 실행했을 때, 명령행 인자의 개수가 2이면 두 번째 인자를 출력하고, 그렇지 않으면 “hello, world”를 출력
- 예를 들어, 위 프로그램을 “my_program.c” 라는 이름으로 저장하고
./my_program
로 실행한다면, “hello, world” 출력- 하지만,
./my_program John
로 프로그램을 실행한다면, “hello, John” 출력