Toán tử đặc biệt '#' và '##' bên trong định nghĩa #define
Bên trong định nghĩa macro, hai toán tử đặc biệt có thể được sử dụng:
- Một ký hiệu thăng đơn '#' trước tên của một tham số macro biến nội dung của tham số đó thành một chuỗi; nó chỉ được phép trong các macro hàm.
- Một ký hiệu thăng đôi '##' giữa hai từ (token) kết hợp chúng lại, và nếu token là một tham số macro, thì giá trị của nó được thay thế, nhưng nếu token là tên macro, nó được thay thế nguyên trạng, không mở rộng macro; nếu kết quả của việc "dán" tạo ra một tên macro khác, thì macro đó sẽ được mở rộng.
Trong các ví dụ trong cuốn sách này, chúng ta thường sử dụng macro sau:
#define PRT(A) Print(#A, "=", (A))
Nó gọi hàm Print
, trong đó biểu thức được truyền vào được hiển thị dưới dạng chuỗi nhờ #A
, và sau dấu "bằng", giá trị thực tế của A
được in ra.
Để thể hiện '##', hãy xem xét một macro khác:
#define COMBINE(A,B,X) A##B(X)
Với nó, chúng ta thực sự có thể tạo ra một lời gọi đến macro SQN
đã được định nghĩa trước đó:
Print(COMBINE(SQ,N,2)); // 4
Các giá trị nguyên văn SQ
và N
được nối lại, sau đó macro SQN
mở rộng thành ((2)*(2))
và cho ra kết quả 4.
Macro sau cho phép tạo định nghĩa biến trong mã bằng cách tạo tên của nó dựa trên các tham số của macro:
#define VAR(TYPE,N) TYPE var##N = N
Sau đó, dòng mã:
VAR(int, 3);
tương đương với:
int var3 = 3;
Việc nối các token cho phép triển khai một cách viết tắt vòng lặp qua các phần tử mảng bằng macro.
#define for_each(I, A) for(int I = 0, max_##I = ArraySize(A); I < max_##I; ++I)
// mô tả và điền dữ liệu vào mảng x theo cách nào đó
double x[];
// ...
// thực hiện vòng lặp qua mảng
for_each(i, x)
{
x[i] = i * i;
}
2
3
4
5
6
7
8
9
10