Skip to content

5. 상수(Constant)


1. 키워드

  • 상수(Constant)
  • 리터럴(Literal)
  • 접미사(Suffix)


2. 상수와 리터럴

  • 상수는 변하지 않는 값을 뜻한다.
  • 변수는 한 번 선언하면 값을 계속 바꿀 수 있지만, 상수는 처음 선언할 때만 값을 할당할 수 있으며 그다음부터는 값을 바꿀 수 없다.


  • 상수를 알아보기 전에 상수와 리터럴을 구분할 필요가 있다.
  • 다음과 같은 코드가 있을 때 con1은 상수, 10은 리터럴이다.


//         ↓ 상수
const int con1 = 10;
//               ↑ 리터럴


  • 리터럴은 "문자 그대로"라는 뜻인데, C에서는 값 그 자체를 뜻한다.
  • 그리고 상수는 변수처럼 리터럴이 저장된 공간이다.
  • 프로그램을 작성할 때 고정되어 있어야 할 값을 변수에 저장해서 사용하다 보면 실수로 값을 바꿀 가능성이 있다.
  • 따라서 상수는 값을 바꾸는 것을 방지하기 위해 사용하며, 코드의 의도를 명확하게 만들 수 있다.


3. 리터럴 사용하기

  • 다음 내용을 입력한 뒤 실행해 보자.


#include <stdio.h>

int main()
{
    printf("%d\n", 10);              // 정수 리터럴
    printf("%f\n", 0.1f);            // 실수 리터럴
    printf("%c\n", 'a');             // 문자 리터럴
    printf("%s\n", "Hello, world!"); // 문자열 리터럴

    return 0;
}

// 10
// 0.100000
// a
// Hello, world!


  • 여기서는 값을 변수에 저장하지 않고, printf 함수에서 바로 출력했다.
  • 이렇게 10, 0.1f, 'a', "Hello, world!"처럼 값을 그대로 입력한 것이 리터럴이다.
  • 리터럴은 반드시 표기 방법을 지켜야 한다.
  • 숫자는 숫자 그대로 사용해도 되지만 문자는 반드시 ''로 묶어주어야 하고, 문자열은 ""로 묶어준다.
  • 문자나 문자열을 따옴표로 묶어주지 않으면 변수, 함수 등으로 인식되므로 주의해야 한다.
  • ""로 묶은 문자열을 출력하려면 printf 함수에서 서식 지정자로 %s를 사용한다.


  • 이번에는 정수 리터럴 표기 방법을 알아보자.


#include <stdio.h>

int main()
{
    printf("%d\n", 19);     // 10진 정수 리터럴
    printf("0%o\n", 017);   // 8진 정수 리터럴
    printf("0x%X\n", 0x1F); // 16진 정수 리터럴

    return 0;
}

// 19
// 017
// 0x1F


  • 10진수는 숫자 그대로 표기하면 되고, 8진수는 숫자 앞에 0을 붙이고, 16진수는 0x를 붙인다.
  • 이때 printf에서 8진수를 출력하려면 서식 지정자로 %o를 사용한다.
  • 여기서 %o는 8진수 숫자만 출력되므로 10진수와 구분하기 힘들다.
  • 그래서 보통 %o 앞에 0을 붙여서 017 형태로 출력한다.
  • 8진수는 최댓값이 7이므로 89를 사용할 수 없고, 16진수는 9 다음에 알파벳 대소문자로 A부터 F까지 사용할 수 있다.


  • 실수 리터럴 표기 방법은 다음과 같다.


#include <stdio.h>

int main()
{
    printf("%f\n", 0.1f);    // 실수 리터럴 소수점 표기
    printf("%f\n", 0.1F);    // 실수 리터럴 소수점 표기
    printf("%f\n", 1.0e-5f); // 실수 리터럴 지수 표기법
    printf("%f\n", 1.0E-5F); // 실수 리터럴 지수 표기법

    return 0;
}

// 0.100000
// 0.100000
// 0.000010
// 0.000010


  • 실수 리터럴이 float 타입 크기라면 끝에 f 또는 F를 붙이고, long double 타입 크기라면 l 또는 L을 붙인다.
  • 그리고 지수 표기법은 e 또는 E와 지수를 표기한다.


4. 상수 사용하기

  • 이번에는 자료형 앞에 const를 붙여서 상수를 사용해 보자.


#include <stdio.h>

int main()
{
    const int con1 = 1;      // 상수. 선언과 동시에 초기화
    const float con2 = 0.1f; // 상수. 선언과 동시에 초기화
    const char con3 = 'a';   // 상수. 선언과 동시에 초기화

    printf("%d %f %c\n", con1, con2, con3); // 1 0.100000 a

    return 0;
}


  • 상수를 선언하는 방법은 변수를 선언하는 방법과 같으며 자료형 앞에 const만 붙여주면 된다.
  • 단, 상수는 반드시 선언과 동시에 값을 할당하여 초기화해 주어야 하며 초기화를 하지 않으면 컴파일 에러가 발생한다.
  • 물론 상수도 변수처럼 printf에서 상수 이름을 사용하여 저장된 값을 출력할 수 있다.


  • 그럼 const를 붙여서 상수가 된 상태에서 값을 할당해 보자.


#include <stdio.h>

int main()
{
    const int con1 = 1;

    con1 = 2; // 상수에 값을 할당하면 컴파일 에러 발생

    printf("%d\n", con1);

    return 0;
}

// error: cannot assign to variable 'con1' with const-qualified type 'const int'


  • 상수에 값을 할당한 뒤 컴파일해 보면 컴파일 에러가 발생한다.
  • 즉, const를 붙여서 상수가 되면 더 이상 값을 할당할 수 없다.
  • 다른 값을 사용하려면 새 상수를 선언해야 한다.


const의 위치

  • const는 자료형 앞에 붙여도 되고, 자료형 뒤에 붙여도 된다.


int const con1 = 1;
float const con2 = 0.1f;
char const con3 = 'a';


5. 정수 리터럴 접미사 사용하기

  • 리터럴의 크기를 명확하게 표현하기 위해 접미사를 사용할 수도 있다.


#include <stdio.h>

int main()
{
    printf("%ld\n", -10L);                    // long 타입 크기의 정수 리터럴
    printf("%lld\n", -1234567890123456789LL); // long long 타입 크기의 정수 리터럴

    printf("%u\n", 10U);           // unsigned int 타입 크기의 정수 리터럴
    printf("%lu\n", 1234567890UL); // unsigned long 타입 크기의 정수 리터럴

    printf("%lu\n", 10UL);                    // unsigned long 타입 크기의 정수 리터럴
    printf("%llu\n", 1234567890123456789ULL); // unsigned long long 타입 크기의 정수 리터럴

    return 0;
}

// -10
// -1234567890123456789
// 10
// 1234567890
// 10
// 1234567890123456789


  • 변수를 선언할 때는 long, long long, unsigned long 타입처럼 정수 자료형으로 크기를 정할 수 있지만, 리터럴은 접미사를 활용하여 크기를 명시적으로 표기한다.


001


  • 접미사는 대문자, 소문자를 모두 사용할 수 있으며 lu를 조합하여 크기와 부호 유무를 표현한다.
  • 이때 대소문자를 섞어 쓸 수도 있다.
  • 접미사를 생략하면 int 타입 크기가 된다.


  • 10진수뿐만 아니라 8진수와 16진수에도 접미사를 사용할 수 있다.


#include <stdio.h>

int main()
{
    printf("0%lo\n", 017L);          // long 타입 크기의 8진 정수 리터럴
    printf("0%lo\n", 017UL);         // unsigned long 타입 크기의 8진 정수 리터럴
    printf("0x%lX\n", 0x7FFFFFL);    // long 타입 크기의 16진 정수 리터럴
    printf("0x%lX\n", 0xFFFFFFFFUL); // unsigned long 타입 크기의 16진 정수 리터럴

    return 0;
}

// 017
// 017
// 0x7FFFFF
// 0xFFFFFFFF


6. 실수 리터럴 접미사 사용하기

  • 이번에는 실수 리터럴에 접미사를 사용하여 크기를 정해 보자.


#include <stdio.h>

int main()
{
    printf("%f\n", 0.1f);  // float 타입 크기의 실수 리터럴
    printf("%f\n", 0.1F);  // float 타입 크기의 실수 리터럴
    printf("%f\n", 0.1);   // double 타입 크기의 실수 리터럴
    printf("%Lf\n", 0.1l); // long double 타입 크기의 실수 리터럴
    printf("%Lf\n", 0.1L); // long double 타입 크기의 실수 리터럴

    printf("%f\n", 1.0e-5f);  // float 타입 크기의 실수 리터럴
    printf("%f\n", 1.0e-5F);  // float 타입 크기의 실수 리터럴
    printf("%f\n", 1.0e-5);   // double 타입 크기의 실수 리터럴
    printf("%Lf\n", 1.0e-5l); // long double 타입 크기의 실수 리터럴
    printf("%Lf\n", 1.0e-5L); // long double 타입 크기의 실수 리터럴

    return 0;
}

// 0.100000
// 0.100000
// 0.100000
// 0.100000
// 0.100000
// 0.000010
// 0.000010
// 0.000010
// 0.000010
// 0.000010


002


  • 실수 리터럴 끝에 f 또는 F를 붙이면 float 타입 크기가 되고, l 또는 L을 붙이면 long double 타입 크기가 된다.
  • 그리고 접미사를 붙이지 않으면 double 타입 크기가 된다.

References