CS
[모두의 컴퓨터과학] 배열
KSWKSW
2021. 11. 14. 21:30
컴파일링
- stdio.h: 헤더파일, C언어로 작성되어 있으며 파일명이 .h로 끝나는 파일
- 컴파일을 하면 벌어지는 일은?
- preprocessing -> compiling - > assembling -> linking
preprocessing
- # 기호로 시작하는 줄을 실제 파일의 코드로 대체한다.
compiling
- 소스코드를 머신코드로 바꾸는 단계
- 소스코드를 어셈블리 코드로 바꾼다.
- 어셈블리 코드: CPU가 이해할 수 있는 코드
assembling
- 어셈블리 코드를 받아 0과 1로 이루어진 머신코드로 바꾼다.
- clang이 해주는 일
linking
- 라이브러리와 코드의 0과 1을 모아 하나의 파일로 만들어준다.
디버깅
- 버그: 의도하지 않은 프로그램 내 실수
- 문법적으로 나타나는 오류
- 논리적인 오류: printf 활용
IDE
통합 개발 환경
디버깅에 대한 추가기능을 제공한다.
ex) 코드 중간에서 멈추기, 한줄씩 실행하기
코드의 디자인
- 코드 작성시에는 다른 사람이 읽기 쉽도록, 유지보수가 쉽도록 작성해야 한다.
- 코드의 정확성과는 관련이 없다.
- 스타일 가이드를 따라야 한다.
- 소프트웨어로 평가할 영역이 아님
배열
- char를 입력할 때는 작은 따옴표가 필요하다. (문자열은 쌍따옴표)
형변환
#include <stdio.h>
int main(void)
{
char c1 = 'H';
char c2 = 'I';
char c3 = '!';
printf("%i %i %i", (int) c1, (int) c2, (int) c3);
}
- (int)를 이용해서 char를 int로 형변환한다.
- 컴퓨터 메모리는 c1, c2, c3를 각각 숫자로 한 칸에 저장해놓는다.
평균 내기
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int score1 = 72;
int score2 = 73;
int score3 = 33;
printf("Average : %i", (score1 + score2 + score3) / 3);
}
변수 하나하나를 각각 선언하여 3으로 나누는 것은 과목이 추가될 때 수정하기 어렵다 -> 배열 사용
배열: 같은 자료형의 값들이 같은 이름의 변수에 리스트로 저장된다.
3개의 값이 담긴 배열을 만들고 싶다면 대괄호 안에 3을 넣어 int scores[3];과 같이 선언한다.
그 후 scores[0] = 72; 와 같은 식으로 배열에 값을 넣어준다.
배열을 사용한 코드
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int scores[3];
scores[0] = 72;
scores[1] = 73;
scores[2] = 33;
printf("Average : %i", (scores[0] + scores[1] + scores[2]) / 3);
}
- 여전히 코드를 복사 붙여넣기 하고 있고, 항상 3으로만 나눌 수 있다는 단점이 있다.
- 프로그램 내부에서 변수가 바뀌지 않도록 선언하고 싶다면 코드 상단에 const int N = 3; 과 같은 식으로 선언할 수 있다. 변수명은 대문자로 적는다.(상수)
#include <cs50.h>
#include <stdio.h>
float average(int length, int array[]);
int main(void)
{
int n = get_int("Number of scores: ");
int scores[n];
for (int i = 0; i <n; i++)
{
scores[i] = get_int("score %i: ", i + 1);
}
printf("Average : %.1f", average(n, scores));
}
float average(int length, int array[])
{
int sum = 0;
for (int i = 0; i < length; i++)
{
sum += array[i]
}
return (float) sum / (float) length;
}
- C에선 정수를 정수로 나누면 정수가 나온다. 소수점 뒤 숫자들은 버려진다.
- 형변환을 이용해 해결한다.
- C는 자바나 파이썬과 달리 배열의 길이를 저장하지 않는다. 따로 선언해줘야 한다.
문자열과 배열
- 문자열(string): char의 배열
- 램에서 글자 수 만큼의 바이트를 차지한다.
- 문자열이 끝나는 메모리를 널문자(\0)로 나타낸다. 글자별로 저장할 때보다 1바이트가 추가된다.
- 문자열은 char의 배열이므로 대괄호를 두번 사용하면 글자별로 출력할 수 있다.
- 컴퓨터는 문자열을 출력할 때 앞 인덱스부터 메모리를 검사하면서 널 문자가 아니면 출력하고 널 문자이면 출력을 멈추는 식으로 출력한다.
문자열의 활용
입력받은 문자를 한 글자씩 출력하기
- 널 문자 사용
#include <stdio.h>
#include <cs50.h>
int main(void)
{
string s = get_string("Input: ");
printf("Output: ");
for (i = 0; s[i] != '\0'; i++)
{
printf("%c", s[i]);
}
printf('\n');
}
- 문자열의 길이 사용
#include <stdio.h>
#include <cs50.h>
#include <string.h> // strlen 함수가 있는 라이브러리
int main(void)
{
string s = get_string("Input: ");
printf("Output: ");
for (i = 0, n = strlen(s); i < n; i++)
{
printf("%c", s[i]);
}
printf('\n');
}
소문자를 대문자로 만들기
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h> // toupper 함수가 있는 헤더파일
int main(void)
{
string s = get_string("Before: ");
printf("After: ");
for (int i = 0, int n = strlen(s); i < n; i++)
{
printf("%c", toupper(s[i]));
}
printf("\n")
}
명령행 인자
- clang은 기본적으로 a.out이라는 프로그램을 출력하지만 "-o" 명령행 인자를 이용하며 프로그램의 이름을 바꿀 수 있다.
- int main(void)에 void 대신 int main(int argc, string argv[]) 라고 입력하면 명령 프롬프트에서 문자열을 바로 입력받을 수 있고 argc는 입력받은 인자의 갯수가 들어간다.
- 왜 main함수는 int 반환값이 있을까? -> main은 0을 반환한다. 0은 문제 없다는 의미
- 가끔 에러메시지에서 -42같이 숫자를 반환하는 것은 main함수가 특정 상황에 리턴하도록 설계된 숫자다.
- argv[0]에는 처음 입력하는 프로그램 이름이 저장됨
출처: 부스트코스 모두의 컴퓨터과학