프로그래밍

변수와 자료형

값을 저장하기 전에 저장할 공간의 크기부터 정해야 합니다.
C가 파이썬과 처음으로 달라지는 점입니다.

학습 목표

  1. 변수를 선언한다는 것의 의미를 알고, 자료형을 지정해 변수를 선언할 수 있다.
  2. 대입문은 오른쪽을 먼저 계산한다는 것을 알고, 값이 바뀌는 순서를 따라갈 수 있다.
  3. 정수·실수·문자를 구별하고 각각에 맞는 자료형과 서식 지정자를 고를 수 있다.
  4. 정수끼리의 나눗셈에서 소수점 아래가 사라지는 이유를 설명하고, 형 변환으로 이 문제를 해결할 수 있다.

값을 저장하는 변수

C에서는 변수를 만들 때 어떤 자료형의 값을 저장할지 먼저 밝힙니다.

계산 결과를 다음 줄에서 다시 쓰려면 어딘가에 저장해 두어야 합니다. 값을 저장해 두고 이름으로 다시 꺼내 쓰는 메모리 공간을 변수(variable)라고 합니다.

선언(declaration)

C는 변수를 만들 때 어떤 값을 저장할 변수인지 먼저 적습니다. 그 「어떤 값」에 해당하는 것이 자료형이고, 이렇게 자료형과 이름을 적어 변수를 만드는 것을 선언이라고 합니다. 자료형이 정해지면 변수가 메모리에서 차지할 크기도 함께 정해집니다.

int score = 90;              // 정수를 저장할 변수를 선언하고 90으로 초기화한다
double height = 170.5;       // 실수를 저장할 변수
char grade = 'A';            // 문자 하나를 저장할 변수

printf("%d\n", score);       // 90
printf("%.1f\n", height);    // 170.5
printf("%c\n", grade);       // A

=는 수학의 「같다」가 아닙니다. 오른쪽 값을 왼쪽 변수에 저장하라는 명령이고, 이것을 대입(assignment)이라고 합니다.

위 코드처럼 변수를 선언하면서 처음 값을 함께 저장하는 것은 초기화(initialization)라고 합니다.

여기서 쓴 printf는 저장된 값을 화면에 출력해 눈으로 확인하는 명령입니다. %d·%f·%c는 그 위치에 어떤 자료형의 값을 출력할지 알려 주는 표시로, 서식 지정자(format specifier)라고 합니다. 지금은 값이 제대로 저장되었는지 확인하는 용도로만 씁니다.

코드를 감싸는 기본 구조

C 코드는 정해진 구조 안에 있어야 실행됩니다. 지금까지 본 코드는 설명을 위해 핵심 부분만 떼어 놓은 것이고, 실제로 실행하려면 이렇게 감싸야 합니다.

#include <stdio.h>

int main(void) {
    int score = 90;
    printf("%d\n", score);   // 90
    return 0;
}

이 구조가 무엇을 하는지는 지금 몰라도 됩니다. 안쪽에 쓴 줄들이 위에서 아래로 차례로 실행된다는 것만 알면 됩니다. 이 강의노트의 다른 예시 코드도 모두 이 안에 넣어야 실행됩니다.

이름을 아무렇게나 붙일 수는 없습니다

규칙 되는 예 / 안 되는 예
영문자·숫자·밑줄만 쓴다 score, student_count / my-score는 뺄셈으로 읽힌다
숫자로 시작하지 않는다 score1 / 1score
대문자와 소문자는 다른 이름 score와 Score는 서로 다른 변수다
C 문법에 쓰는 단어(예약어)는 쓸 수 없다 int, if, return 등

규칙만 지키면 프로그램은 실행됩니다. 그래도 무엇을 저장했는지 알아볼 수 있는 이름을 붙이는 편이 좋습니다. 코드는 한 번 쓰고 끝나지 않고, 며칠 뒤의 자신이 다시 읽기 때문입니다.

스스로 확인

초기화하지 않고 int score;라고만 선언하면 score에는 어떤 값이 들어 있을까요? 0일까요, 아니면 알 수 없는 값일까요?

대입은 오른쪽을 먼저 계산한다

이 한 가지만 기억하면 값이 바뀌는 순서가 보입니다.

처음 배울 때 흔히 헷갈리는 줄이 바로 이것입니다.

int count = 10;
count = count + 1;           // 오른쪽 10 + 1을 먼저 계산해 11을 count에 대입한다
printf("%d\n", count);       // 11

수학에서 count = count + 1은 성립하지 않는 식입니다. 어떤 수도 자기 자신보다 1 크지 않으니까요. 하지만 C에서 이 줄은 등식이 아니라 순서가 있는 명령입니다.

한 줄이 처리되는 순서

  1. 오른쪽을 먼저 계산한다 — count에 저장된 10을 꺼내 1을 더해 11을 얻는다.
  2. 그 결과를 왼쪽 변수에 저장한다 — count가 11이 된다.

오른쪽을 계산하는 동안 count는 아직 10입니다. 값은 마지막 단계에서 바뀝니다.

왼쪽과 오른쪽은 하는 일이 다릅니다

10 = count;라고 쓰면 오류가 납니다. 왼쪽에는 값을 저장할 변수가 와야 하는데 10은 변수가 아니라 값이기 때문입니다. =의 양쪽은 서로 바꿔 쓸 수 없습니다.

스스로 확인

a = 3;, b = a;를 한 뒤 a = 5;로 바꾸면 b는 얼마일까요? 「한 줄이 처리되는 순서」의 두 단계를 그대로 따라가 보세요.

자료형마다 크기가 정해져 있다

자료형을 미리 밝히면 저장할 수 있는 값의 범위도 함께 정해집니다.

자료형(data type)

값이 어떤 종류인지를 나타냅니다. 자료형이 정해지면 그 값으로 무엇을 할 수 있는지, 그리고 메모리에서 얼마나 큰 공간을 차지하는지도 함께 정해집니다.

자료형 저장하는 값 서식 지정자 예
int 정수 %d 90, -17, 0
double 실수 %f 3.14, 170.5
char 문자 하나 %c 'A', '7' — 한글 한 글자는 저장할 수 없다

따옴표 두 종류를 구별합니다

'A'는 작은따옴표로 감싼 문자 하나이고, "A"는 큰따옴표로 감싼 문자열(string)입니다. 문자열은 문자를 차례로 이어 놓은 값이라, 글자가 하나뿐이어도 문자 하나와는 저장되는 방식이 다릅니다. 파이썬은 두 따옴표를 구별하지 않지만 C는 구별합니다.

저장할 수 있는 값에는 한계가 있습니다

int 변수는 메모리에서 차지하는 크기가 정해져 있어서 아주 큰 수는 저장할 수 없습니다. 범위를 넘어도 대개 오류로 멈추지 않고 그대로 실행되므로, 믿을 수 없는 결과가 나와도 알아채기 어렵습니다. 정확한 범위는 컴퓨터와 컴파일러에 따라 다르므로 「범위에 한계가 있다」는 것부터 기억해 두면 됩니다.

스스로 확인

char grade = 'A';는 되는데 char grade = "A";는 왜 안 될까요?

자료형이 다른 값이 만날 때

C에서 자주 발목을 잡는 것이 정수끼리의 나눗셈입니다.

자료형이 다른 값이 한 식에서 만나거나 다른 자료형의 변수에 대입되면 C가 알아서 자료형을 맞춥니다. 이것을 자동 형 변환(implicit type conversion)이라고 합니다.

int a = 3;
double b = a;                // 정수 3이 실수 3.0으로 자동 형 변환된다
printf("%f\n", b);           // 3.000000

double x = 3.7;
int n = (int) x;             // 실수를 정수로 바꿀 때는 강제 형 변환을 직접 적는다
printf("%d\n", n);           // 3    소수점 아래는 잘린다

정수를 실수 변수에 저장하면 표현 범위가 더 넓은 자료형으로 바꾸는 것이라 값이 그대로 유지됩니다. 반대로 실수를 정수 변수에 저장하면 소수점 아래가 잘립니다. 반올림이 아닙니다. C가 알아서 잘라 저장하기는 하지만, 이렇게 좁은 자료형으로 바꿀 때는 (int)처럼 직접 적어 「의도한 변환」임을 밝힙니다. 이것을 강제 형 변환(type casting)이라고 합니다.

5 / 2는 2.5가 아니라 2입니다

printf("%d\n", 5 / 2);            // 2    정수끼리 나누면 소수점 아래가 사라진다
printf("%f\n", 5.0 / 2);          // 2.500000
printf("%f\n", (double) 5 / 2);   // 2.500000   한쪽을 실수로 바꾼 것

양쪽이 모두 정수이면 C는 정수끼리의 나눗셈을 합니다. 소수점 아래는 잘려 나가고 정수 부분만 남습니다. 소수점 아래가 필요하면 한쪽을 실수로 바꾸어 주어야 합니다.

평균을 구하는 코드가 자꾸 소수점 아래가 없는 값만 출력한다면 원인은 대개 정수끼리의 나눗셈입니다. 오류로 멈추지 않고 그럴듯한 값이 나오기 때문에 찾기가 어렵습니다.

스스로 확인

학생 세 명의 점수 합이 250일 때 250 / 3은 얼마로 나올까요? 참값과 얼마나 다른가요?

핵심 정리

선언

변수를 만들 때 저장할 값의 자료형을 먼저 적는다. 자료형이 정해지면 변수가 메모리에서 차지할 크기도 함께 정해진다.

대입의 순서

오른쪽을 먼저 계산하고 그 결과를 왼쪽 변수에 저장한다. 오른쪽을 계산하는 동안 왼쪽 변수는 아직 이전 값을 가지고 있다.

자료형과 서식 지정자

int %d, double %f, char %c. 'A'는 문자 하나, "A"는 문자열로 서로 다르다.

정수끼리의 나눗셈

양쪽이 정수면 소수점 아래가 잘린다 (5 / 2는 2). 소수점 아래가 필요하면 한쪽을 실수로 바꾼다. 오류로 멈추지 않으므로 찾기 어렵다.

확인 퀴즈

배운 내용을 확인해 봅시다.

1. int n = 4; 다음에 n = n * n;을 실행하면 n은 얼마인가?

2. printf("%d", 7 / 2);의 결과는?

3. 다음 중 틀린 설명은?