C ön işlemci ise bir döngü yazmak
Bakış eğitim/hack noktası, (gerçekten böyle kod istemem) bu soruyu soruyorum.
C ön işlemci direktifleri kullanarak sadece döngü uygulamak mümkün. Makrolar yinelemeli olarak, bu nasıl gerçekleştirilebilir? genişletildi anlıyorum
Teşekkürler
CEVAP
Bir süre döngü uygulamak istiyorsanız, bu kadar basit özyineleme kullanmak gerekir. Özyineleme yapmak için en kolay yolu ertelenmiş bir ifade kullanmaktır. Ertelenmiş bir ifade daha tarar tamamen genişletmek için gerektiren bir ifadesidir:
#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(id) id DEFER(EMPTY)()
#define EXPAND(...) __VA_ARGS__
#define A() 123
A() // Expands to 123
DEFER(A)() // Expands to A () because it requires one more scan to fully expand
EXPAND(DEFER(A)()) // Expands to 123, because the EXPAND macro forces another scan
Neden bu kadar önemli? İyi bir makro taranmış ve genişliyor, devre dışı bırakılması, bir bağlam oluşturur. Bu devre dışı bırakılması kapsamında şu anda genişleyen makro için bir belirteç, mavi boyalı neden olur. Böylece, boyalı mavi bir makro artık genişleyecektir. Bu makrolar yinelemeli olarak genişletin. Ancak, devre dışı bırakılması, bir bağlam yalnızca bir tarama sırasında, yani mavi boyalı olma bizim makrolar önleyebiliriz bir genişleme ertelendiğinde var. Sadece ifade etmek için daha fazla tarama uygulamak için ihtiyacımız olacak. O EVAL
bu makro kullanarak yapabiliriz:
#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
#define EVAL5(...) __VA_ARGS__
Sonra, biraz mantık, vb gibi) için bazı operatörler tanımlayın:
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define CHECK_N(x, n, ...) n
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
#define NOT_0 ~, 1,
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
#define COMPL_0 1
#define COMPL_1 0
#define BOOL(x) COMPL(NOT(x))
#define IIF(c) PRIMITIVE_CAT(IIF_, c)
#define IIF_0(t, ...) __VA_ARGS__
#define IIF_1(t, ...) t
#define IF(c) IIF(BOOL(c))
Şimdi tüm bu makrolar WHILE
özyinelemeli bir makro yazabiliriz. Kendisi için geri yinelemeli olarak bakın WHILE_INDIRECT
makro kullanıyoruz. Bu farklı bir tarama(ve devre dışı bırakılması farklı bir bağlamda kullanarak) genişleyecektir beri mavi boyalı, olmaktan makro engeller. WHILE
makro yüklem bir makro, operatör bir makro ve bir devlet variadic bağımsız olan) alır. Yüklem makro false 0) dönünceye kadar makro bu operatör durumuna uygulayarak tutar.
#define WHILE(pred, op, ...) \
IF(pred(__VA_ARGS__)) \
( \
DEFER(WHILE_INDIRECT) () \
( \
pred, op, op(__VA_ARGS__) \
), \
__VA_ARGS__ \
)
#define WHILE_INDIRECT() WHILE
Gösteri amaçlı, sadece bağımsız değişken sayısı 1 olduğunda denetleyen bir dayanak oluşturmak için
#define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
#define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1)
#define IS_1(x) CHECK(PRIMITIVE_CAT(IS_1_, x))
#define IS_1_1 ~, 1,
#define PRED(x, ...) COMPL(IS_1(NARGS(__VA_ARGS__)))
Önümüzdeki iki belirteçleri herhangi bir parametre hangi bir operatör, yaratıyoruz. Biz de son çıktıyı işleyecek son bir operatör (M
olarak da adlandırılır) oluşturmak:
#define OP(x, y, ...) CAT(x, y), __VA_ARGS__
#define M(...) CAT(__VA_ARGS__)
Sonra WHILE
makro kullanarak:
M(EVAL(WHILE(PRED, OP, x, y, z))) //Expands to xyz
Tabii ki, yüklem veya operatör her türlü geçebilir.
Nasıl makefile döngü yazmak için?...
'iyi bir şekilde DateTime üzerine...
Neden boyutu(char)` eğer char standart...
C 11: menzil tabanlı nasıl kullanılır(...
Metin için string dosyası yazmak ve he...