Các chú thích bị xóa trong giai đoạn 3 của quá trình dịch chương trình 1 : mỗi chú thích được thay thế bằng một ký tự khoảng trắng. vì vậy nhận xét /*nt*/
chắc chắn không phải là một mã thông báo.
Nếu không có int
, main
, i
, a
hoặc return
được định nghĩa là tiền xử lý macro, phân tích các chương trình sản xuất 14 thẻ (không phải 13):
int
main
(
)
{
i
a
=
10
;
return
0
;
}
Trừ khi i
được định nghĩa là kiểu có typedef
câu lệnh, nếu không sẽ xảy ra lỗi cú pháp do i a
không khớp với quy tắc trong ngữ pháp C.
Vì vậy bạn không thể viết bình luận bên trong tên biến, bình luận chia mã định danh thành 2 mã thông báo riêng biệt. Điều này đúng với bất kỳ tiền xử lý nào và mã thông báo ngôn ngữ C 2 .
Tuy nhiên, lưu ý rằng bạn có thể chèn chú thích ở những vị trí bất thường như giữa các toán tử một ngôi và toán hạng của chúng hoặc giữa #
và chỉ thị tiền xử lý và các đối số của nó:
#include<stdio.h>
#defineSTAT(a)-1
#ifdefSTAT
intmain(){
inta=+1;
printf("Hello ""world!\n");
returnSTAT;
}
#endif
Nhưng định nghĩa macro ở trên không xác định macro giống hàm mà là macro thông thường STAT
mở rộng thành ( a ) - 1
.
Các tên biến, giống như bất kỳ mã thông báo nào khác có thể được chia theo dòng mới thoát. Dòng mới đã thoát là các chuỗi hoặc \
ngay sau đó là một dòng mới. Các trình tự này được loại bỏ khỏi mã nguồn trong giai đoạn 2 của quá trình dịch chương trình. Mục đích chính của chúng là phá vỡ các định nghĩa macro dài trên nhiều dòng.
Dưới đây là đoạn mã 3 tạo ra 14 mã thông báo giống nhau:
\
i\
nt\
ma\
in()
{\
i/\
*nt\
*/a \
= 10;
r\
et\
urn\
0;}
Hãy để ý cách trình tô màu mã bỏ sót các từ khóa được cắt lát và cắt hạt lựu và nhận xét :)
1) Hành vi này đã được chỉ định trong ANSI-C hay còn gọi là C89. Một số trình biên dịch cổ đại có hành vi khác biệt một cách tinh vi dẫn đến việc dán mã thông báo, nhưng những đặc thù như vậy chỉ quan tâm đến lịch sử.
2) Bạn gần như có thể chèn chú thích bên trong một hằng chuỗi bằng cách tận dụng thực tế là các hằng chuỗi liền kề được nối với nhau trong giai đoạn 6 của quá trình dịch chương trình: printf("Hello "/* my name is Luca */"world!\n");
3) Phong cách trình bày Cây thông Giáng sinh này không được sử dụng trong các chương trình thực, nó minh họa cách lạm dụng khả năng xử lý đầu vào của C. Các thủ thuật phức tạp hơn đã giành chiến thắng trong Cuộc thi Mã C Obfuscated Quốc tế
cpp -traditional
triển khai , nó sẽ mở rộng thànhia = 10;
.