Macro hàm trong C có thể nhận số lượng đối số thay đổi bằng cú pháp ... ở cuối danh sách tham số, và trong thân macro, __VA_ARGS__ được thay bằng toàn bộ các đối số "thừa" (sau các tham số cố định), nối với nhau bởi , (dấu phẩy và một khoảng trắng).
Điểm khó khi phân tích lời gọi macro là: các đối số được phân tách bởi dấu phẩy ở cấp lồng ngoặc cao nhất (cấp 0) — dấu phẩy nằm bên trong một cặp ngoặc đơn (...) lồng bên trong một đối số (ví dụ do gọi hàm f(a,b) làm đối số) không được coi là dấu phân tách đối số.
Cho macro có k tham số cố định và thân gồm t token (mỗi token là: tên một tham số cố định, chuỗi __VA_ARGS__, hoặc một token cố định khác). Cho phần bên trong dấu ngoặc của lời gọi macro dưới dạng một chuỗi duy nhất, trong đó các đối số cấp cao nhất được phân tách bởi , (dấu phẩy + đúng 1 khoảng trắng), và có thể chứa ngoặc đơn lồng nhau bên trong một đối số.
Hãy: (1) phân tích chuỗi lời gọi thành danh sách đối số ở cấp cao nhất (dùng bộ đếm độ sâu ngoặc); (2) gán k đối số đầu tiên cho các tham số cố định theo đúng thứ tự khai báo; (3) các đối số còn lại (có thể là 0 đối số) là phần biến đổi, nối lại bởi , để thay cho __VA_ARGS__; nếu không có đối số biến đổi nào thì __VA_ARGS__ được thay bằng chuỗi rỗng và bị loại hoàn toàn khỏi kết quả (không để lại token nào ở vị trí đó); (4) in ra thân macro sau khi thay thế, các token/đoạn cách nhau đúng 1 khoảng trắng.
Ví dụ: macro 1 tham số cố định fmt, thân printf ( fmt , __VA_ARGS__ ), lời gọi với chuỗi "x=%d", x, foo(1,2). Phân tích cấp cao nhất cho 3 đối số: "x=%d", x, foo(1,2) (dấu phẩy bên trong foo(1,2) không tách đối số vì nó ở độ sâu ngoặc 1). Với k=1: fmt = "x=%d"; phần biến đổi là x và foo(1,2), nối lại: x, foo(1,2). Kết quả: printf ( "x=%d" , x, foo(1,2) ).
Dòng 1: tên macro (không dùng đến). Dòng 2: số nguyên k (0≤k≤5) — số tham số cố định. Dòng 3: k tên tham số cách nhau bởi khoảng trắng (nếu k=0, dòng này rỗng). Dòng 4: số nguyên t (1≤t≤30) — số token trong thân macro. Dòng 5: t token của thân macro cách nhau bởi đúng 1 khoảng trắng. Dòng 6: một chuỗi duy nhất — phần bên trong ngoặc của lời gọi macro (có thể rỗng nếu lời gọi không có đối số nào), các đối số cấp cao nhất cách nhau bởi , , có thể chứa ngoặc đơn (,) lồng nhau bên trong một đối số. Dữ liệu đảm bảo số đối số cấp cao nhất luôn ≥k và ngoặc trong dòng 6 luôn cân bằng.
In ra một dòng duy nhất — thân macro sau khi thay thế tham số cố định và __VA_ARGS__ như mô tả, các token/đoạn cách nhau đúng 1 khoảng trắng.
Ví dụ:
Đầu vào:
SUM_ALL
0
4
sum ( __VA_ARGS__ )
1, 2, 3, 4
Đầu ra:
sum ( 1, 2, 3, 4 )
Đầu vào:
LOG
1
fmt
6
printf ( fmt , __VA_ARGS__ )
"x=%d", x, foo(1,2)
Đầu ra:
printf ( "x=%d" , x, foo(1,2) )
Đang tải editor...