Bỏ qua để đến nội dung

Hằng số: const & constexpr

C++ cho phép khai báo hằng số thực sự bất biến - một khi đã khởi tạo, giá trị không thể bị thay đổi, và trình biên dịch sẽ báo lỗi nếu bạn cố tình gán lại.

#include <iostream>
int main() {
const double PI = 3.14159;
const int MAX_USERS = 100;
std::cout << PI << " " << MAX_USERS << std::endl;
// PI = 3.14; // LỖI BIÊN DỊCH! Không thể gán lại giá trị cho biến const
return 0;
}

Một biến const phải được khởi tạo giá trị ngay khi khai báo, vì sau đó không thể thay đổi.

constexpr: hằng số tại thời điểm biên dịch

Phần tiêu đề “constexpr: hằng số tại thời điểm biên dịch”

constexpr mạnh hơn const: giá trị của nó phải được tính toán được ngay khi biên dịch, không phải lúc chạy chương trình. Điều này giúp trình biên dịch tối ưu hóa tốt hơn.

constexpr int MAX_SIZE = 100; // OK - giá trị biết trước khi biên dịch
constexpr int DOUBLE_SIZE = MAX_SIZE * 2; // OK - biểu thức hằng, tính được lúc biên dịch
int user_input;
std::cin >> user_input;
// constexpr int x = user_input; // LỖI! user_input chỉ biết được lúc CHẠY chương trình
const int y = user_input; // OK - const chấp nhận giá trị biết lúc chạy
  • Dùng constexpr khi giá trị chắc chắn biết trước lúc biên dịch (kích thước mảng cố định, các hằng số toán học…)
  • Dùng const khi giá trị chỉ biết được lúc chạy chương trình nhưng không muốn nó bị thay đổi sau khi gán (ví dụ: giá trị nhập từ người dùng, tham số hàm không muốn bị sửa đổi bên trong hàm)

Một cách dùng const rất phổ biến: đảm bảo hàm không sửa đổi tham số truyền vào (đặc biệt khi truyền bằng tham chiếu, sẽ học ở bài sau):

void print_message(const std::string& message) {
std::cout << message << std::endl;
// message += "!"; // LỖI! Không thể sửa đổi tham số const
}
  • const: giá trị không đổi sau khi khởi tạo, có thể nhận giá trị biết lúc chạy chương trình
  • constexpr: hằng số phải tính được ngay lúc biên dịch, giúp tối ưu hiệu năng
  • Nên dùng const/constexpr bất cứ khi nào có thể - giúp code an toàn hơn và thể hiện rõ ý định của người viết