C言語プリプロセッシングコマンド

7557 ワード

まず、マクロ定義、ファイル含む、条件コンパイルコマンドの3つの形式のコマンドです.
マクロ定義は主に:define,#undef
#define PI 3.1415926                   /*        */
#define Max(a,b)  a>b?a:b              /*       */

次に、マクロFAILEDを定義してデータの正確性を検出する例を示す.
①# defineの応用:
#define FAILED(Status) ((Status)<0)
#include "stdio.h"
void main()
{
    int d;
    printf ("Please input a integer number(n>0)
"); do{ scanf("%d" ,&d); }while(FAILED(d)); }

ここで、while(FAILED(d))は、コンパイル前にwhile(d<0)に無条件に置き換えられる.マクロ定義と呼び出しは形式的に関数と似ているが、原理は異なる.
②# undefの応用:
#include "stdio.h"
void Test();
int main(int argc, char* argv[])
{
    #define CONST_NAME1 "CONST_NAME1"
    printf("%s
",CONST_NAME1); #undef CONST_NAME1 printf("%s
",CONST_NAME1); /* ,CONST_NAME1 */ { #define CONST_NAME2 "CONST_NAME2" printf("%s
",CONST_NAME2); } printf("%s
",CONST_NAME2); return 0; } void Test() { printf("%s
",CONST_NAME2); }

プログラムのコンパイルの時、システムは以下の情報error C 2065:'CONST_を提示しますNAME 1':undeclared identifier理由はマクロCONST_NAME 1は#undefでキャンセルされたので、コンパイルprintf("%s",CONST_NAME 1)ではCONST_が見つかりませんNAME 1の定義
2、ファイルの内容:
#include<ファイル名>は、システムが指定したファイルをコンパイルするための標準的な方法です.
#include「ファイル名」は、ユーザーが現在作業しているフォルダ内のファイルを検索し、存在しない場合は標準的にクエリーします.
3、条件コンパイル(一般的な3つの形式):
①第一の形式:
#if defined(またはifdef)
       
[#else
        ]
#endif
②第二の形式:
#if !defined(またはifndef)
       
[#else
        ]
#endif
③第3の形式はC++コンパイラによく用いられる.
#ifdef …
[#elif … ]
[#elif …]
#else …
 #endif
#if命令#if命令は、別のキーワードを製造した後の定数式を検出する.式が真である場合、後のコードをコンパイルし、#else、#elifまたは#endifが現れるまで知る.そうでなければコンパイルしません.
#endifコマンド#endifは、#if前処理コマンドを終了するために使用されます.#else命令else命令あるif命令に使用した後、前のif命令の条件が真でない場合、else後のコードをコンパイルする.endif命令は、上の条件ブロックを指します.
4、その他の条件コンパイルコマンド:
 ①#error:
構文フォーマットは、#error token-sequenceの主な役割は、コンパイル時にコンパイルエラー情報token-sequenceを出力し、プログラマがプログラムに現れたエラーをチェックしやすいことです.例えば次のプログラム
#include "stdio.h"
int main(int argc, char* argv[])
{
#define CONST_NAME1 "CONST_NAME1"
  printf("%s
",CONST_NAME1); #undef CONST_NAME1 #ifndef CONST_NAME1 #error No defined Constant Symbol CONST_NAME1 #endif { #define CONST_NAME2 "CONST_NAME2" printf("%s
",CONST_NAME2); } printf("%s
",CONST_NAME2); return 0; }

コンパイル時にコンパイル情報fatal error C 189:#error:No defined Constant Symbol CONST_NAME1
②#pragma
#pragmaは、コンパイラの状態を設定したり、コンパイラに特定の動作を完了させたりするC言語の前処理命令です.定義に基づいて、コンパイル指示はマシンまたはオペレーティングシステム固有であり、コンパイラごとに異なります.
一般的には、#pragma Para
ここでParaはパラメータですが、一般的なパラメータをいくつか見てみましょう.
  • messageパラメータ.

  • Messageパラメータは私の大好きなパラメータで、コンパイル情報出力ウィンドウで対応する情報を出力することができます.これはソース情報の制御にとって非常に重要です.使用方法は次のとおりです.
    #Pragma message(「メッセージテキスト」)
    コンパイラがこのコマンドに遭遇すると、コンパイル出力ウィンドウでメッセージテキストが印刷されます.プログラムで多くのマクロを定義してソースコードのバージョンを制御すると、これらのマクロが正しく設定されているかどうかを忘れてしまう可能性があります.このコマンドでコンパイル時にチェックすることができます.ソースコードのどこかで定義されているかどうかを判断したいとします.X 86このマクロは次の方法で使用できます.
    #ifdef _X86
    #Pragma message(“_X86 macro activated!”)
    #endif
    定義するとX 86マクロ以降、アプリケーションはコンパイル時にコンパイル出力ウィンドウに「
    X86 macro activated!”.自分が定義した特定のマクロを覚えていないからといって、耳かきをすることはありません.
    .
  • もう1つの比較的多く使用されているpragmaパラメータはcode_seg.フォーマット:
  • #pragma code_seg( ["section-name"[,"section-class"] ] )
    プログラムに関数コードが格納されているコードセグメントを設定でき、ドライバを開発するときに使用します.
  • #pragma once(比較的常用)
  • ヘッダファイルの最初にこの命令を加えるだけで、ヘッダファイルが一度コンパイルされることを保証することができ、この命令は実際にはVC 6にすでに存在しているが、互換性を考慮するとあまり使用されていない.
  • #pragma hdrstopは、プリコンパイルヘッダファイルがここまでであり、後のヘッダファイルがプリコンパイルされていないことを示す.BCBはヘッダファイルをプリコンパイルしてリンクを高速化することができますが、すべてのヘッダファイルがプリコンパイルされるとディスク領域が多すぎる可能性がありますので、このオプションを使用してヘッダファイルを除外します.

  • セルAがセルBに依存するなど、セル間に依存関係がある場合があるので、セルBはセルAより先にコンパイルされる.#pragma startupでコンパイル優先度を指定できます.#pragma package(smart_init)を使用すると、BCBは優先度の大きさに応じて前後してコンパイルされます.
  • #pragma resource"*.dfm"は*を表す.dfmファイルのリソースをプロジェクトに追加します.*dfmにはフォーム
  • が含まれる
    外観の定義.
  • #pragma warning( disable : 4507 34; once : 4385; error : 164 )

  • 次のように等価です.
    #pragma warning(disable:4507 34)/4507と34番の警告情報を表示しない
    #pragma warning(once:4385)/4385号警告メッセージは1回のみ報告
    #pragma warning(error:164)//164号警告情報をエラーとします.
    また、このpragma warningは以下のフォーマットをサポートしています.
    #pragma warning( push [ ,n ] )
    #pragma warning( pop )
    ここでnは警告レベル(1−−4)を表す.
    #pragma warning(push)は、すべての警告情報の既存の警告状態を保存する.
    #pragma warning(push,n)は、すべての警告情報の既存の警告状態を保存し、グローバル警告を行う
    レベルをnに設定します.
    #pragma warning(pop)スタックに最後の警告情報をポップアップし、スタックとアウトスタックの間で行う
    すべての変更がキャンセルされました.例:
    #pragma warning( push )
    #pragma warning( disable : 4705 )
    #pragma warning( disable : 4706 )
    #pragma warning( disable : 4707 )
    //.......
    #pragma warning( pop )
    このコードの最後に、47054706および4707を含むすべての警告情報を再保存します.
  • pragma comment(...)

  • このコマンドは、オブジェクトファイルまたは実行可能ファイルにコメントレコードを格納します.
    よく使われるlibキーワードは、ライブラリファイルに接続するのに役立ちます.
  • progma pack(n)

  • 構造体の位置合わせを指定します!pragma pack(n)は、変数をnバイトで位置合わせするように設定する.nバイトアライメントとは、変数が格納される先頭アドレスのオフセット量の2つのケースがある.第1に、nが変数が占有するバイト数以上である場合、オフセット量はデフォルトのアライメント方式を満たさなければならない.第2に、nが変数のタイプが占有するバイト数未満である場合、オフセット量はnの倍数であり、デフォルトのアライメント方式を満たさない.構造の合計サイズにも制約があり、nがすべてのメンバー変数タイプが占有するバイト数より大きい場合、構造の合計サイズは、占有空間が最大の変数が占有する空間数の倍数でなければならない.
    そうでなければnの倍数でなければなりません.次に、その使い方を例に挙げて説明します.
    #pragma pack(push)/位置合わせ状態の保存
    #pragma pack(4)//4バイト揃えに設定
    struct test
    {
    char m1;
    double m4;
    int m3;
    };
    #pragma pack(pop)/位置合わせ状態の復元
    この機能をテストするにはsizeof()を使用して構造体の長さをテストします!
    ③#line
    このコマンドは、主にコンパイラに指定された行番号でソースプログラムのコードの再番号を強制し、デバッグ時にこの規定に従ってエラーコードの正確な位置を出力することができます.形式1構文形式は、#line constant“filename”です.その後のソースコードを指定した行番号constantから番号付けし直し、現在のファイルの名前をfilenameと名付けます.例えば、次のプログラムは、#include"stdio.h"void Test();line 10 "Hello.c"int main(int argc, char* argv[]) { #define CONST_NAME1 "CONST_NAME1"printf("%s",CONST_NAME1); #undef CONST_NAME1 printf("%s",CONST_NAME1); { #define CONST_NAME2 "CONST_NAME2"printf("%s",CONST_NAME2); } printf("%s",CONST_NAME2); return 0; } void Test() { printf("%s",CONST_NAME2); } ヒント:Hello.c(15) : error C2065: 'CONST_NAME 1':undeclared identifierは、現在のファイルの名前がHelloとみなされていることを示す.c,#line 10"Hello.c"が存在する行は10行目とみなされるため、15行目のエラーが提示される.形式2構文形式は次のとおりです.
    #line constant:コンパイル時にエラーコードがある場所(行番号)を正確に出力し、ソースプログラムに行番号が現れないため、プログラマーの正確な位置決めを容易にする役割を果たします.
    ④演算子#と##は、ANSI Cでプリコンパイル命令に対して2つの演算子を定義します.#と##です.の役割は、#define HI(x)printf("Hi,"#x")などのテキスト置換を実現することである.void main() {     HI(John); } プログラムの実行結果:Hi,Johnはプリコンパイル処理時に,「#x」の役割はxを代表する文字列に置き換えることである.本プログラムではxがJohnなので、新しい列「Hi,John」を構築します.の役割は直列接続です.例えば#define CONNECT(x,y)x##y void main(){int a 1,a 2,a 3;CONNECT(a,1)=0;CONNECT(a,2)=12;a 3=4;printf("a 1=%dta 2=%dta 3=%d",a 1,a 2,a 3);}プログラムの実行結果は,a 1=0 a 2=12 a 3=4コンパイル前にCONNECT(a,1)がa 1,CONNECT(a,2)がa 2に翻訳される.
    ⑤事前定義定数_LINE__:現在のソースコードの行番号、整数定数
    __FILE__:現在のコンパイラファイルの名前、文字列
    __DATE__:コンパイラファイルの日付は、文字列("MMDD YYYY"形式、例えば"Jan 19 1993")
    __TIME__:コンパイラファイル時間、文字列("hh:mm:ss"形式、例えば"08:30:23")
    __stdC__:ANSI Cフラグ、整数定数1は、このプログラムがANSI C規格に互換性があることを示しています.