#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Có thể nối có STR3 == "s1" không? Bạn có thể làm điều này bằng cách chuyển args cho một hàm Macro khác. Nhưng có cách nào trực tiếp không?
#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
Có thể nối có STR3 == "s1" không? Bạn có thể làm điều này bằng cách chuyển args cho một hàm Macro khác. Nhưng có cách nào trực tiếp không?
Câu trả lời:
Nếu chúng là cả hai chuỗi, bạn chỉ có thể làm:
#define STR3 STR1 STR2
Bộ tiền xử lý tự động nối các chuỗi liền kề.
BIÊN TẬP:
Như đã lưu ý bên dưới, nó không phải là bộ tiền xử lý mà là bộ biên dịch thực hiện quá trình nối.
L"a"
và "b"
lấy L"ab"
, nhưng bạn có thể nối L"a"
và L"b"
lấy L"ab"
.
Bạn không cần loại giải pháp đó cho các ký tự chuỗi, vì chúng được nối ở cấp độ ngôn ngữ và nó sẽ không hoạt động bởi vì "s" "1" không phải là mã thông báo tiền xử lý hợp lệ.
[Chỉnh sửa: Để trả lời cho nhận xét không chính xác "Chỉ cho bản ghi" bên dưới mà không may nhận được một số phiếu tán thành, tôi sẽ nhắc lại tuyên bố ở trên và quan sát rằng phân đoạn chương trình
#define PPCAT_NX(A, B) A ## B
PPCAT_NX("s", "1")
tạo ra thông báo lỗi này từ giai đoạn tiền xử lý của gcc: error: việc dán "" s "" và "" 1 "" không cung cấp mã thông báo tiền xử lý hợp lệ
]
Tuy nhiên, để dán mã thông báo chung, hãy thử cách này:
/*
* Concatenate preprocessor tokens A and B without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define PPCAT_NX(A, B) A ## B
/*
* Concatenate preprocessor tokens A and B after macro-expanding them.
*/
#define PPCAT(A, B) PPCAT_NX(A, B)
Sau đó, ví dụ, cả hai PPCAT_NX(s, 1)
và PPCAT(s, 1)
tạo ra số nhận dạng s1
, trừ khis
được định nghĩa là một macro, trong trường hợp đó sẽ PPCAT(s, 1)
tạo ra <macro value of s>1
.
Tiếp tục chủ đề là các macro sau:
/*
* Turn A into a string literal without expanding macro definitions
* (however, if invoked from a macro, macro arguments are expanded).
*/
#define STRINGIZE_NX(A) #A
/*
* Turn A into a string literal after macro-expanding it.
*/
#define STRINGIZE(A) STRINGIZE_NX(A)
Sau đó,
#define T1 s
#define T2 1
STRINGIZE(PPCAT(T1, T2)) // produces "s1"
Ngược lại,
STRINGIZE(PPCAT_NX(T1, T2)) // produces "T1T2"
STRINGIZE_NX(PPCAT_NX(T1, T2)) // produces "PPCAT_NX(T1, T2)"
#define T1T2 visit the zoo
STRINGIZE(PPCAT_NX(T1, T2)) // produces "visit the zoo"
STRINGIZE_NX(PPCAT(T1, T2)) // produces "PPCAT(T1, T2)"
"s""1"
hợp lệ trong C (và C ++). Chúng là hai mã thông báo (chuỗi ký tự) mà trình biên dịch sẽ tự ghép nối và đe dọa như một mã thông báo.
"s""1" isn't a valid token
- điều đó chính xác; như bạn nói, nó là hai mã thông báo. Nhưng việc gộp chúng lại với nhau bằng ## sẽ khiến chúng trở thành một mã thông báo tiền xử lý duy nhất , không phải hai mã thông báo và do đó trình biên dịch sẽ không thực hiện ghép nối, thay vì lexer sẽ từ chối chúng (ngôn ngữ yêu cầu chẩn đoán).
STRINGIZE_NX(whatever occurs here)
mở rộng thành "bất cứ điều gì xảy ra ở đây", bất kể bất kỳ định nghĩa vĩ mô nào cho bất kỳ điều gì xảy ra, xảy ra hoặc ở đây.
if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- điều đó là sai và không giống như bài kiểm tra của bạn. Bạn đang cố gắng không hiểu hoặc hiểu đúng điều này và tôi sẽ không trả lời bạn thêm.
Gợi ý: STRINGIZE
Macro ở trên rất tuyệt, nhưng nếu bạn mắc lỗi và đối số của nó không phải là macro - bạn có lỗi đánh máy trong tên hoặc quên #include
tệp tiêu đề - thì trình biên dịch sẽ vui vẻ đặt tên macro có mục đích vào chuỗi không có lỗi.
Nếu bạn dự định rằng đối số STRINGIZE
luôn là macro có giá trị C bình thường, thì
#define STRINGIZE(A) ((A),STRINGIZE_NX(A))
sẽ mở rộng nó một lần và kiểm tra xem nó có hợp lệ không, loại bỏ nó và sau đó mở rộng lại thành một chuỗi.
Tôi đã mất một lúc để tìm ra lý do tại sao STRINGIZE(ENOENT)
lại kết thúc "ENOENT"
thay vì "2"
... tôi đã không bao gồm errno.h
.
,
nhà điều hành. :)
((1),"1") "." ((2),"2")
thay vì chỉ "1" "." "2")
STRINGIZE
định nghĩa ban đầu , "The value of ENOENT is " STRINGIZE(ENOENT)
hoạt động, trong khi "The value of ENOENT is" STRINGIZE_EXPR(X)
tạo ra lỗi.