Bài 19.222 phút đọc
define và macro đối tượng
Sau bài này bạn sẽ làm được
- Định nghĩa hằng số bằng define và hiểu nó chỉ là thay thế văn bản
- So sánh macro với const và enum trên bốn tiêu chí
- Biết phạm vi của macro là từ chỗ định nghĩa tới cuối đơn vị dịch
- Dùng undef đúng lúc và biết vì sao ít khi cần tới
Macro đối tượng là dạng đơn giản nhất của #define: một cái tên, và đoạn văn bản thay vào chỗ cái tên đó. Đơn giản tới mức nhiều người dùng nó cho việc mà C đã có công cụ tốt hơn.
#Định nghĩa và thay thế
#define TEN noi_dung_thay_the
#define PI 3.14159265358979
#define BO_DEM_CO 1024
#define TEN_APP "Quan ly sinh vien"
#define GO_LOI /* khong co gia tri */Macro đối tượng
Macro không có tham số. Mỗi lần tên nó xuất hiện như một token riêng trong mã, preprocessor thay bằng phần văn bản đứng sau tên trong dòng
#define.terminal
cat thu.c
#define BO_DEM_CO 1024 #define TEN_APP "Quan ly" char bo_dem[BO_DEM_CO]; const char *ten = TEN_APP; int nua = BO_DEM_CO / 2;
gcc -E -P thu.c
char bo_dem[1024]; const char *ten = "Quan ly"; int nua = 1024 / 2;
#Phạm vi của macro
void f(void) {
#define TAM 10 /* dinh nghia ben trong ham */
int a = TAM;
}
void g(void) {
int b = TAM; /* VAN DUNG DUOC: macro khong theo khoi lenh */
}#Macro, const hay enum
| Tiêu chí | #define | const | enum |
|---|---|---|---|
| Có kiểu | Không | Có | Có, kiểu int |
| Trình gỡ lỗi thấy được tên | Không | Có | Có |
| Dùng làm kích thước mảng | Được | Không trong C | Được |
| Dùng trong nhãn case | Được | Không | Được |
| Tuân theo phạm vi khối | Không | Có | Có |
| Dùng được cho số thực | Được | Được | Không |
| Dùng được cho chuỗi | Được | Được | Không |
#undef và định nghĩa lại
#define TAM 100
/* ... dung TAM ... */
#undef TAM /* huy dinh nghia */
int TAM = 5; /* gio hop le tro lai */#Quy ước đặt tên
| Loại | Kiểu tên | Ví dụ |
|---|---|---|
| Macro thường | CHU_HOA_GACH_DUOI | BO_DEM_CO, PHIEN_BAN |
| Macro của một module | TIEN_TO_TEN | SV_MSSV_CO, QL_TOI_DA |
| Header guard | TEN_TEP_H | SINHVIEN_H, QUANLY_LOI_H |
| Macro nội bộ, không phải giao diện | TIEN_TO_GACH_DUOI_TEN | SV_NOI_BO_KIEM |
Bộ hằng số của một module trông như thế nào
sinhvien.h
#ifndef SINHVIEN_H
#define SINHVIEN_H
/* Kich thuoc: dung enum vi chung la kich thuoc mang */
enum {
SV_MSSV_CO = 16,
SV_TEN_CO = 64,
SV_LOP_CO = 16,
SV_SO_MON = 5,
};
/* Nguong diem: dung enum vi chung la so nguyen nhan 100 */
enum {
SV_NGUONG_XUAT_SAC = 900,
SV_NGUONG_GIOI = 800,
SV_NGUONG_KHA = 650,
SV_NGUONG_TB = 500,
};
/* Phien ban dinh dang tep: dung define vi #if can thay */
#define SV_PHIEN_BAN 1
#endif /* SINHVIEN_H */Tự làm thử
- Định nghĩa
#define N = 10;có dấu bằng và dấu chấm phẩy, dùng nó làm kích thước mảng, rồi đọc thông báo lỗi. - Định nghĩa
#define max(a,b) ...chữ thường rồi khai báo một biến tênmax, xem chuyện gì xảy ra. - Thử
const int N = 10;rồiint a[N];ở phạm vi tệp và giải thích lỗi. - Viết mẫu
#ifndef ... #define ... #endifcho một hằng số cấu hình, rồi ghi đè nó bằng cờ-D. - Đổi một nhóm bốn
#definesố nguyên thành một khốienumvà xác nhận chương trình vẫn chạy như cũ.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
#definechỉ là thay thế văn bản, không có dấu bằng và không có dấu chấm phẩy.- Macro sống từ dòng định nghĩa tới cuối đơn vị dịch, không tuân theo phạm vi khối lệnh nào.
- Vì vậy macro phải viết hoa hết, và tên bắt đầu bằng gạch dưới là của thư viện chứ không phải của bạn.
consttrong C không phải hằng số biên dịch, nên kích thước mảng và nhãncasephải dùngenumhoặc#define.- Quy tắc thực dụng:
enumcho số nguyên,constcho số thực và chuỗi,#definekhi preprocessor phải nhìn thấy.