Type Qualifier (Chỉ định kiểu) là gì?
Từ khóa thêm thuộc tính đặc biệt cho kiểu dữ liệu. C có 3: const, volatile, restrict (C99).
const - Hằng (Read-only)
Biến được khai báo const không thể sửa đổi sau khi khởi tạo.
3 loại hằng trong C
1. Literal Constant (Hằng chữ)
int a = 10 + 5; // 5 là literal constant
printf("Hello"); // "Hello" là string literal
2. Defined Constant (Hằng macro)
#define PI 3.14159
#define MAX 100
// Xử lý bởi preprocessor, không có kiểu dữ liệu
3. Memory Constant (Hằng bộ nhớ - const qualifier)
const float PI = 3.14159f; // Có kiểu, có địa chỉ, read-only
const int MAX_SIZE = 100;
Cú pháp const
const int a = 10; // int const a = 10; (tương đương)
const int *p; // Con trỏ TO const int (pointer to constant)
int *const p = &a; // Const pointer TO int (constant pointer)
const int *const p = &a; // Cả hai đều const
Chương trình demo 3 loại hằng
#include <stdio.h>
#define PI_DEFINE 3.14159 // Defined constant
int main() {
const float PI_CONST = 3.14f; // Memory constant
printf("Literal constant: %.2f\n", 3.14);
printf("Defined constant: %.5f\n", PI_DEFINE);
printf("Memory constant: %.2f\n", PI_CONST);
// PI_CONST = 3.15; // LỖI COMPILE: assignment of read-only variable
return 0;
}
Kết quả
Literal constant: 3.14
Defined constant: 3.14159
Memory constant: 3.14
Const với Con trỏ (Chi tiết)
| Khai báo | Đọc từ phải sang trái | Ý nghĩa |
|---|---|---|
const int *p | p trỏ đến (int const) | Dữ liệu const, con trỏ đổi được |
int *const p | p là (const con trỏ đến int) | Con trỏ const, dữ liệu đổi được |
const int *const p | p là const con trỏ đến const int | Cả hai const |
Const với Function Parameter
// Cam kết không sửa mảng
void inMang(const int *arr, int n) {
for (int i = 0; i < n; i++) printf("%d ", arr[i]);
}
// Cam kết không sửa struct
void inSinhVien(const struct SinhVien *sv) {
printf("%s - %d\n", sv->ten, sv->tuoi);
}
// Const cho giá trị (vô nghĩa cho pass by value, nhưng rõ ý đồ)
void tinh(int const x) { ... }
Const với Struct
struct Diem {
int x, y;
};
int main() {
const struct Diem p = {10, 20};
// p.x = 5; // LỖI: assignment of read-only member
struct Diem *ptr = &p;
// ptr->x = 5; // LỖI: cannot assign to member of read-only struct
return 0;
}
Const vs #define
| Tiêu chí | const | #define |
|---|---|---|
| Kiểu dữ liệu | Có (type safety) | Không (text replacement) |
| Scope | Tuân theo block scope | File scope từ điểm define |
| Địa chỉ bộ nhớ | Có (là biến) | Không |
| Debug | Xem được trong debugger | Không (bị thay thế trước) |
| Kích thước | sizeof() hoạt động | Không áp dụng |
Lưu ý
constkhông tạo hằng số compile-time cho kích thước mảng (C89):const int n = 5; int a[n];→ VLA (C99) hoặc lỗi (C89)- Dùng
enum { SIZE = 100 };cho hằng số compile-time constbiến toàn cục có internal linkage mặc định (khácextern)- String literal:
char *s = "abc";→ deprecated, dùngconst char *s
Quy tắc vàng: Mặc định dùng const cho mọi biến/tham số không cần sửa đổi. Chỉ bỏ const khi thực sự cần ghi.