icon안동민 개발노트

상수와 리터럴


상수의 개념

 상수(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++에서는 truefalse를 사용합니다.

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 그램

실습

  1. 다양한 타입의 상수 선언 및 사용
#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;
}
  1. 리터럴 타입 접미사 활용
#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;
}
  1. 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;
}

주의사항

 1. const#define의 차이

  • const는 타입 체크를 수행하지만, #define은 단순 텍스트 치환
  • const는 디버깅 시 더 유용함

 2. constexpr의 제약 사항

  • constexpr 함수는 순수 함수여야 함 (부작용 없음)
  • 컴파일 시간에 평가 가능해야 함

연습 문제

  1. 원의 넓이와 둘레를 계산하는 프로그램을 작성하세요. PI 값은 constexpr을 사용하여 선언하세요.
  2. 다음 코드의 출력 결과를 예측해보세요.
const int x = 5;
int arr[x] = {1, 2, 3, 4, 5};
constexpr int y = x + 1;
std::cout << y << std::endl;
  1. 섭씨 온도를 화씨 온도로 변환하는 constexpr 함수를 작성하세요.

 참고자료