5. 상수(Constant)
1. 키워드
- 상수(Constant)
- 리터럴(Literal)
- 접미사(Suffix)
2. 상수와 리터럴
- 상수는 변하지 않는 값을 뜻한다.
- 변수는 한 번 선언하면 값을 계속 바꿀 수 있지만, 상수는 처음 선언할 때만 값을 할당할 수 있으며 그다음부터는 값을 바꿀 수 없다.
- 상수를 알아보기 전에 상수와 리터럴을 구분할 필요가 있다.
- 다음과 같은 코드가 있을 때
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
이므로8
과9
를 사용할 수 없고, 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
는 자료형 앞에 붙여도 되고, 자료형 뒤에 붙여도 된다.
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
타입처럼 정수 자료형으로 크기를 정할 수 있지만, 리터럴은 접미사를 활용하여 크기를 명시적으로 표기한다.
- 접미사는 대문자, 소문자를 모두 사용할 수 있으며
l
과u
를 조합하여 크기와 부호 유무를 표현한다. - 이때 대소문자를 섞어 쓸 수도 있다.
- 접미사를 생략하면
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
- 실수 리터럴 끝에
f
또는F
를 붙이면float
타입 크기가 되고,l
또는L
을 붙이면long double
타입 크기가 된다. - 그리고 접미사를 붙이지 않으면
double
타입 크기가 된다.