C言語 - マクロ(ターンます。https://blog.csdn.net/hairetz/article/details/4785047)

多くのC ++の本は、マクロC言語は最初にすべての悪のですが、我々はそれが悪いだろうと思ったとして、物事いつものように良い、ちょうど後藤同じとして私たちをお勧めします。Acerは持っている
大きな役割を自動的に私たちのためのコードを生成することです。テンプレートは、私たちのためのコードの他のタイプ(交換しないタイプ)の多様性を生成することができた場合は、
マクロは、実際に私たちのために、シンボルの新しいコード(すなわち、シンボル置換、増加)を生成することができます。

マクロの問題の構文の一部については、Googleで見つけることができます。あなたが考えるマクロの全く理解するためにあなたはそんなに、私を信じて。あなたがいる場合
知っていると#の##はありません、あなたはマクロが十分ではありません理解する必要があり、プレスキャンのか分かりません。

私は少しはマクロでいくつかの文法的な問題を説明しなかった(たとえば、文法の問題が間違っているようですが、マクロプリプロセッサとはわずか約しかし、意味解析とは何の関係も):

1.マクロは、例えば、関数のように定義することができる
の#define分(X、Y)(X -が、実際の使用において、唯一の書き込み分()は、括弧内に追加する必要があり、minはマクロとして展開、またはしないであろう任意の処理を行います。

2.マクロにパラメータが必要な場合は、コンパイラは(マクロの引数は十分ではありません)あなたに警告を与えるだろうが、これはエラーになります、渡すことはできません。このような記述としてC ++ブックとして
上記、コンパイラ(プリプロセッサ)マクロ構文チェックでは十分ではありませんので、より多くのあなたは、自分自身のための作業を確認する必要があります。

3.多くのプログラマは###と分からない
#記号列に直接入れシンボル、例えばを:
の#define STRING(X)#Xがある
のconstのchar * strの= STRING(test_string); strの内容は、 "test_string"であります、それは#記号が続くだろう
、二重引用符で直接。
##例えば、新たなシンボル(語彙階層)を生成する、2つのシンボリックシンボルに接続される。
SIGNを#defineする(X)X ## _ INT
(1)SIGNをint型、マクロが展開されることになります。int INT_1。

4.マクロ変化するパラメータ、あなたが同様のマクロを定義することができるように、比較的涼しい:
LOG(フォーマット、...)のprintf(フォーマット、__VA_ARGS__中)#defineし
LOG( "%のSの%のD"、STR、COUNTを);
__VA_ARGS_ _事前定義されたマクロシステムで、パラメータリストが自動的に交換されます。

5.場合はマクロ呼び出し自体、何が起こりますか?例:
TEST(X-)(X- + TEST(X-))#defineし
TEST(1);はどうなりますか?無制限の拡張再帰を防ぐために、文法は、起動時にマクロ会う彼女を停止することを提供する、つまり
TESTは、(1)これは、テストされます、プロセスはTESTを発見展開し、展開されたときに、言うこと一般的なシンボルとして。(1)TESTは、
1つの+ TEST(1):最終的に拡大しました。

プレスキャン6.マクロのパラメータは、
マクロのパラメータはマクロ本体の中に置かれたときに、マクロがすべての最初のパラメータを拡張している(例外は、以下を参照してください)。マクロのパラメータはマクロ本体の拡張に入れているときは、
プリプロセッサ新しい拡張されたマクロボディは、第二のスキャンで、拡大を続けています。たとえば、次
の#define PARAM(X)X
の#define ADDPARAM(X)X ## _ INT
PARAM(ADDPARAM(1));
ADDPARAMは、(1)マクロのパラメータPARAMので、(1)第一ADDPARAMように展開されるようにINT_1、その後、PARAMにINT_1。

例外は、#を使用して、PARAMマクロ##又はマクロパラメータは、マクロパラメータが拡張されない場合である:
の#define PARAM(X-)#X
の#define ADDPARAM(X-)## INT _ X-
PARAM(ADDPARAM(1) );それは"ADDPARAM(1)"に拡張します。

そのような規則を使用することは、あなたは非常に興味深い技術を作成することができます。マクロが展開された後、あなたは簡単にコードを分析できるように、道のプリントアウト:
の#define to_stringに(X-)TO_STRING1(X-)
の#define TO_STRING1(X-)が#X
最初TO_STRING Xすべての今、あなたが行うことができ、(xはマクロの単語の場合)展開し、その後TO_STRING1を文字列に変換渡します:
のconstのchar * strの= to_stringに(PARAM(ADDPARAM(1)));拡張PARAMを探求します後に見えます。

7. A付加非常に重要:私は上記第一の点で前記のように、関数が使用中のマクロブラケットのように表示されない場合、プリプロセッサだけ
ではない一般的な記号処理(処理として、このマクロ)。


マクロは、私たちは、自動的にコードを生成を支援する方法を体験してみましょう。私が言ったように、マクロコードシンボルレベルで生成されます。私は、Boost.Functionの分析
私も、コードを理解していなかった原因、それは、マクロの多く(マクロのネスト、再び巣)を使用しているため、時間モジュールを。その後私は、小さなテンプレートライブラリのTTLを発見したと述べた
(ブーストがあまりにもないので、正当な理由である)小さな部品の数の開発は、ブーストの一部を交換すること。同様に、ライブラリーはまた、関数ライブラリが含まれています。
ここで私は数子前に言及した関数です。ttl.functionカレーは、自動的にマクロを使用し、類似したコードの多くを生成するには:

TTL_FUNC_BUILD_FUNCTOR_CALLER用の#define(N)/
テンプレート<R&LT型名、TTL_TPARAMS(N - )> /
構造体functor_caller_base N - ## /
/// ...
マクロの究極の目的である:同様のTTL_FUNC_BUILD_FUNCTOR_CALLERを呼び出すことによって、(1)自動的に生成します多くfunctor_caller_baseテンプレート:
テンプレート構造体functor_caller_base1
テンプレート構造体functor_caller_base2の
テンプレート構造体functor_caller_base3
/// ...
次いで、TTL_TPARAMS(n)は、このマクロは、このマクロは、最終的に製造されることがわかる前記コア部:
型名Tlの
型名Tlの、T2の型名の
型名Tlの、型名T2、T3の型名は
/// ...
私たちは、プロセスTTL_TPARAMS(n)は、Aを分析してみましょう。私は上記の点のいくつかを把握するために、メインのマクロ分析。次の手順では、私はあなたがTTLコードをめくったことを示唆している
function.hpp、macro_params.hpp、macro_repeat.hpp、macro_misc.hpp:関連するコードファイル 、macro_counter.hppを。

そう、ここで行きます

分析、ドリルダウン、ドリルダウン、例えばTTL_TPARAMS(1):

TTL_TPARAMS用の#define(N-)TTL_TPARAMSX(N、T)
=> TTL_TPARAMSX(1、T)
の#define TTL_TPARAMSX(N、T)TTL_REPEAT(N、TTL_TPARAM、TTL_TPARAM_END、T)
=> TTL_REPEAT(1、TTL_TPARAM、TTL_TPARAM_END、T)
TTL_TPARAM用の#define(N、T)は、n-型名T ##、
の#define TTL_TPARAM_END(N、T)T ##、N-型名
の#define TTL_REPEAT(N、M、L、P)TTL_APPEND(TTL_REPEAT_、TTL_DEC(N))(M 、L、P)TTL_APPEND(TTL_LAST_REPEAT_ 、N)(L、P)
ノート、TTL_TPARAM、TTL_TPARAM_ENDそれはまた、2個のマクロを有しているが、それらは引数TTL_REPEATマクロ通りであり、プレスキャン規則に従って、最初と思われる
マクロ展開のこれら二つの再送のTTL_REPEATへ。しかし、私は先に強調されているように、これら2つのマクロは、関数のようなマクロは、括弧を使用する必要が
括弧付きでない場合は、ないマクロ処理として。TTL_REPEATを拡大したときにこのように、それがあるべきである:
=> TTL_APPEND(TTL_REPEAT_、TTL_DEC(1))(TTL_TPARAM、TTL_TPARAM_END、T)TTL_APPEND(TTL_LAST_REPEAT_ ,. 1)(
TTL_TPARAM_END、T)
マクロ本体は二つの部分に分けることができ、慎重に分析下で、複雑に見える:
(。TTL_REPEAT_、TTL_DEC(1))TTL_APPEND(TTL_TPARAM、TTL_TPARAM_END、T)と
TTL_APPEND(TTL_LAST_REPEAT_、1)(TTL_TPARAM_END 、T)
第一の部分解析に:
// Xは、YとXを展開するための#define TTL_APPEND(x、y)はTTL_APPEND1(x、y)は、Y接続
の#define TTL_APPEND1(X、Y)X ## Y用
の#define TTL_DEC(N-)TTL_APPEND(TTL_CNTDEC_ 、n)は
第一展開パラメータに、最初TTL_DEC(1)拡大する
=> TTL_APPEND(TTL_CNTDEC_ ,. 1)=> TTL_CNTDEC_1用
の#define TTL_CNTDEC_1 0注、TTL_CNTDEC_は、TTL_CNTDEC_1マクロマクロではありません。
=> 0、すなわち、(1)最終的に0に展開され、TTL_DECあります。バック部TTL_APPEND:
=> TTL_REPEAT_0(TTL_TPARAM、TTL_TPARAM_END、T)
の#define TTL_REPEAT_0(M、L、P)
TTL_REPEAT_0このマクロは、その後、空である上記第1の部分が、今は第二の部分を無視される。
TTL_APPEND (TTL_LAST_REPEAT_、1)(TTL_TPARAM_END、 T)
=> TTL_LAST_REPEAT_1(TTL_TPARAM_END、T) // TTL_APPEND 1及びTTL_LAST_REPEAT_マージ
の#define TTL_LAST_REPEAT_1(M、P)M(1、P)
=> TTL_TPARAM_END(1、T)
の#define TTL_TPARAM_END(N、T)Tの型名をN - ##
=>のTl型名が完了し展開します。
---------------------
著者:猫が持ち帰ってきた
出典:CSDN
オリジナルます。https://blog.csdn.net/hairetz/article/details/ 4785047
免責事項:この記事はブロガーのオリジナルの記事、再現され、ボーエンのリンクを添付してください!

おすすめ

転載: www.cnblogs.com/ptfe/p/11222977.html