상수와 리터럴
상수의 개념
상수(Constant)는 프로그램 실행 중 그 값이 변하지 않는 데이터를 의미합니다.
상수를 사용하면 코드의 가독성을 높이고, 의도치 않은 값 변경을 방지할 수 있습니다.
const 키워드
C++에서는 const
키워드를 사용하여 변수를 상수로 선언할 수 있습니다.
const int MAX_STUDENTS = 30;
const double PI = 3.14159;
const
변수는 선언과 동시에 초기화해야 하며, 이후에 값을 변경할 수 없습니다.
함수 매개변수에서도 const
를 사용할 수 있습니다.
void printArray(const int arr[], int size) {
for (int i = 0; i < size; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
이 경우, 함수 내에서 arr
의 요소를 변경할 수 없습니다.
constexpr 키워드 (C++ 11)
C++11에서 도입된 constexpr
키워드는 컴파일 시간 상수를 정의합니다.
constexpr int DAYS_IN_WEEK = 7;
constexpr int SQUARE(int x) { return x * x; }
constexpr
함수는 컴파일 시간에 평가될 수 있어야 합니다.
리터럴의 개념
리터럴(Literal)은 소스 코드에 직접 표현된 값을 의미합니다.
정수 리터럴
- 10진수 : 42
- 8진수 : 052 (0으로 시작)
- 16진수 : 0x2A (0x로 시작)
- 2진수 (C++ 14) : 0b101010 (0b로 시작)
정수 리터럴의 타입 지정
int a = 42; // int
long b = 42L; // long
unsigned c = 42U; // unsigned int
부동소수점 리터럴
- 소수점 표기 : 3.14
- 지수 표기 : 3.14e-2 (3.14 × 10^-2)
float f = 3.14f; // float
double d = 3.14; // double
long double ld = 3.14L; // long double
문자 및 문자열 리터럴
- 문자 리터럴 :
'A'
,'\n'
,'\x41'
- 문자열 리터럴 :
"Hello, World!"
- Raw 문자열 (C++ 11) :
R"(String with "quotes")"
auto s1 = "Hello"; // const char*
auto s2 = u8"Hello"; // const char* (UTF-8 인코딩)
auto s3 = u"Hello"; // const char16_t* (UTF-16 인코딩)
auto s4 = U"Hello"; // const char32_t* (UTF-32 인코딩)
auto s5 = L"Hello"; // const wchar_t*
불리언 리터럴
C++에서는 true
와 false
를 사용합니다.
bool isTrue = true;
bool isFalse = false;
널 포인터 리터럴
C++11부터는 nullptr
을 사용하여 널 포인터를 표현합니다.
int* ptr = nullptr;
사용자 정의 리터럴 (C++ 11)
C++ 11부터는 사용자가 직접 리터럴을 정의할 수 있습니다.
long double operator"" _kg(long double x) { return x * 1000; }
auto weight = 3.5_kg; // 3500 그램
실습
다양한 타입의 상수 선언 및 사용
#include <iostream>
int main() {
const int MAX_VALUE = 100;
constexpr double PI = 3.14159;
std::cout << "MAX_VALUE: " << MAX_VALUE << std::endl;
std::cout << "Circle area with radius 5: " << PI * 5 * 5 << std::endl;
return 0;
}
리터럴 타입 접미사 활용
#include <iostream>
int main() {
auto i = 42; // int
auto l = 42L; // long
auto f = 3.14f; // float
auto d = 3.14; // double
auto ld = 3.14L; // long double
std::cout << "Types:\n";
std::cout << "i: " << typeid(i).name() << std::endl;
std::cout << "l: " << typeid(l).name() << std::endl;
std::cout << "f: " << typeid(f).name() << std::endl;
std::cout << "d: " << typeid(d).name() << std::endl;
std::cout << "ld: " << typeid(ld).name() << std::endl;
return 0;
}
constexpr 함수 작성 및 사용
#include <iostream>
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
int main() {
constexpr int fact5 = factorial(5);
std::cout << "5! = " << fact5 << std::endl;
return 0;
}
주의사항
const
와 #define
의 차이
const
는 타입 체크를 수행하지만,#define
은 단순 텍스트 치환const
는 디버깅 시 더 유용함
constexpr
의 제약 사항
constexpr
함수는 순수 함수여야 함 (부작용 없음)- 컴파일 시간에 평가 가능해야 함
연습 문제
- 원의 넓이와 둘레를 계산하는 프로그램을 작성하세요.
PI
값은constexpr
을 사용하여 선언하세요. - 다음 코드의 출력 결과를 예측해보세요.
const int x = 5;
int arr[x] = {1, 2, 3, 4, 5};
constexpr int y = x + 1;
std::cout << y << std::endl;
- 섭씨 온도를 화씨 온도로 변환하는
constexpr
함수를 작성하세요.
참고자료
- C++ 상수 표현식 : https://en.cppreference.com/w/cpp/language/constant_expression
- C++ 리터럴 : https://en.cppreference.com/w/cpp/language/expressions#Literals
- C++ Core Guidelines (상수 사용) : http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rconst-const