C ディレクティブ 新しいページはコチラ

提供: yonewiki
移動: 案内, 検索
(#import)
(#include)
 
1行: 1行:
 +
[[C PlusPlus#Cにもあった技術|C++]]へ戻る
 +
 +
 
※このページではC言語にも存在していたという意味で記事タイトルがC ディレクティブになっていますが、<br />
 
※このページではC言語にも存在していたという意味で記事タイトルがC ディレクティブになっていますが、<br />
 
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br />
 
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br />
 
<br />
 
<br />
== '''ディレクティブ''' ==
+
<big><big>'''ディレクティブ'''</big></big>
 +
 
 +
 
 
ディレクティブとは日本語で指示するという意味でDirectiveは映画やドラマのDirectorでも同じような意味で制作指揮者・監督というような意味で使われます。プリプロセスを指示するための命令文がディレクティブであることについては[[C プリプロセッサ]]の項目で記述しました。
 
ディレクティブとは日本語で指示するという意味でDirectiveは映画やドラマのDirectorでも同じような意味で制作指揮者・監督というような意味で使われます。プリプロセスを指示するための命令文がディレクティブであることについては[[C プリプロセッサ]]の項目で記述しました。
  
12行: 17行:
  
  
*<nowiki>#</nowiki>include
+
*[[C ディレクティブ##include|#include]]
*<nowiki>#</nowiki>using
+
*[[C ディレクティブ##using|#using]]
*<nowiki>#</nowiki>import
+
*[[C ディレクティブ##import|#import]]
*<nowiki>#</nowiki>line
+
*[[C ディレクティブ##line|#line]]
*<nowiki>#</nowiki>error
+
*[[C ディレクティブ##error|#error]]
  
  
*<nowiki>#</nowiki>if
+
*[[C ディレクティブ##if/#elif/#else/#endif|#if]]
*<nowiki>#</nowiki>elif
+
*[[C ディレクティブ##if/#elif/#else/#endif|#elif]]
*<nowiki>#</nowiki>else
+
*[[C ディレクティブ##if/#elif/#else/#endif|#else]]
*<nowiki>#</nowiki>endif
+
*[[C ディレクティブ##if/#elif/#else/#endif|#endif]]
  
  
*<nowiki>#</nowiki>ifdef
+
*[[C ディレクティブ##ifdef/#ifndef|#ifdef]]
*<nowiki>#</nowiki>ifndef
+
*[[C ディレクティブ##ifdef/#ifndef|#ifndef]]
  
  
35行: 40行:
 
*<nowiki>#</nowiki>pragma
 
*<nowiki>#</nowiki>pragma
 
:詳細は[[C プラグマ]]に記述
 
:詳細は[[C プラグマ]]に記述
 +
  
  
 
== '''<nowiki>#</nowiki>include''' ==
 
== '''<nowiki>#</nowiki>include''' ==
 +
 
<nowiki>#</nowiki>includeディレクティブでは、インクルードファイルを検索して読み込む処理を記述します。以下のような2とおりの記述ができます。
 
<nowiki>#</nowiki>includeディレクティブでは、インクルードファイルを検索して読み込む処理を記述します。以下のような2とおりの記述ができます。
  
49行: 56行:
  
 
具体的には以下の優先順序になる。
 
具体的には以下の優先順序になる。
 +
 +
 +
  
  
63行: 73行:
  
  
incluedeファイルの入れ子は10レベルまでとなっているので、あまり階層(呼び出しの呼び出しの呼び出し…のような感じ)が深くならないようにディレクティブによるヘッダの呼び出しをするように組み込みましょう。絶対パスを指定した場合はその他のディレクトリは検索しないことになっていますので、次々と検索されるのを防ぐ必要がある場合には絶対パスが利用できます。但し、絶対パスにした場合、第三者にプログラムを再利用してもらう場合の配慮が必要になりますので、用途に応じた対応が必要になります。あえて絶対パスにして、自分以外のPCでは簡単にコンパイルされないようにする嫌がらせも可能です。原因がわからない人には使えないという試練を与えるドラマでいうところのなんだその変な胡散臭い試練はって奴になります。
+
 よく使われていたインクルードの宣言は#include <stdio.h>で、C++11という標準規格が制定された2011年くらいまでは、この方法でした。C++11以降はstdioに変わる新しいヘッダファイルcstdioに置き換わっています。VisualStudio2012あたりからcstdioが使われ始めています。他にも主要なヘッダファイルは先頭にcがついて、後ろの.hがないヘッダファイルに置き換わっています。VisualStudio2019ではC++20までの標準規格規格に対応しつつあり、メニュー{デバッグ}&gt;{(プロジェクト名)のデバッグ}で表示されるダイアログの左側ツリーから全般を選択したときに表示される{言語の標準規格の設定}でどの規格を使うかが設定できます。既定ではC++14になっています。C++14の設定でもC++17やC++20の一部の機能は使えます。つまり、VS2019ではもうとっくにC++11準拠なので、cstdioを使った方が良いという感じです。他のコンパイラでもそろそろ、cstdioが対応されていると思います。
 +
 
 +
 
 +
標準ヘッダファイルが新しくなったモノ一覧
 +
*<cassert>
 +
*<ccomplex>
 +
*<cctype>
 +
*<cerrno>
 +
*<cfenv>
 +
*<cfloat>
 +
*<cinttypes>
 +
*<ciso646>
 +
*<climits>
 +
*<clocale>
 +
*<cmath>
 +
*<csetjmp>
 +
*<csignal>
 +
*<cstdalign>
 +
*<cstdarg>
 +
*<cstdbool>
 +
*<cstddef>
 +
*<cstdint>
 +
*<'''cstdio'''>
 +
*<cstdlib>
 +
*<cstring>
 +
*<ctgmath>
 +
*<ctime>
 +
*<cuchar>
 +
*<cwchar>
 +
*<cwctype>
 +
 
 +
 
 +
 incluedeファイルの入れ子は10レベルまでとなっているので、あまり階層(呼び出しの呼び出しの呼び出し…のような感じ)が深くならないようにディレクティブによるヘッダの呼び出しをするように組み込みましょう。絶対パスを指定した場合はその他のディレクトリは検索しないことになっていますので、次々と検索されるのを防ぐ必要がある場合には絶対パスが利用できます。但し、絶対パスにした場合、第三者にプログラムを再利用してもらう場合の配慮が必要になりますので、用途に応じた対応が必要になります。あえて絶対パスにして、自分以外のPCでは簡単にコンパイルされないようにする嫌がらせも可能です。原因がわからない人には使えないという試練を与えるドラマでいうところのなんだその変な胡散臭い試練はって奴になります。
  
  
70行: 112行:
  
 
インクルードファイル名が重複する場合には、このあたりの優先度を理解してインクルードパスの指定をきっちりとしてやることが大事になってきます。
 
インクルードファイル名が重複する場合には、このあたりの優先度を理解してインクルードパスの指定をきっちりとしてやることが大事になってきます。
 
  
 
=='''<nowiki>#</nowiki>using'''==
 
=='''<nowiki>#</nowiki>using'''==
 
C++/CLIで使われる共通言語基盤のライブラリを読み込む場合に利用するものですので、説明を省略します。C++/CLIの項目で解説するかもしれません。
 
C++/CLIで使われる共通言語基盤のライブラリを読み込む場合に利用するものですので、説明を省略します。C++/CLIの項目で解説するかもしれません。
 +
 +
 +
 
  
 
=='''<nowiki>#</nowiki>import'''==
 
=='''<nowiki>#</nowiki>import'''==
92行: 136行:
 
*一意に決まるIDはGUID(Global Unique Identifer)と呼ばれています。GUID生成アルゴリズムによって作成されたGUIDは西暦5770年まで、1秒間に1000万個のIDを発番しても重複しないIDとして保障されているため個人が発番しても、有名企業が発番しても重複しないIDになるため自由に生成アプリを使って発番できるようになっています。もちろん誰かが発番したIDを横取りすれば重複してしまうので、横取りをすることは何も良いことはありません。プログラムが併用できなくなるため、横取りされたプログラムの関係者やプログラムのユーザに迷惑をかけるだけの結果になります。
 
*一意に決まるIDはGUID(Global Unique Identifer)と呼ばれています。GUID生成アルゴリズムによって作成されたGUIDは西暦5770年まで、1秒間に1000万個のIDを発番しても重複しないIDとして保障されているため個人が発番しても、有名企業が発番しても重複しないIDになるため自由に生成アプリを使って発番できるようになっています。もちろん誰かが発番したIDを横取りすれば重複してしまうので、横取りをすることは何も良いことはありません。プログラムが併用できなくなるため、横取りされたプログラムの関係者やプログラムのユーザに迷惑をかけるだけの結果になります。
  
:CLSID クラス識別子
+
:*CLSID クラス識別子
:DISPID ディスパッチ識別子
+
:*DISPID ディスパッチ識別子
:IID インターフェース識別子
+
:*IID インターフェース識別子
:ProgID(short for PROGrammatic IDentifier)日本語対応表現は不明もしくは存在しない。
+
:*ProgID(short for PROGrammatic IDentifier)日本語対応表現は不明もしくは存在しない。
 +
 
 +
 
 +
OLEview.exeでタイプライブラリの情報を閲覧できます。
 +
:OLEview.exeはC:\Program Files (x86)\Windows Kits\8.0\bin\x64にあります(VisualStudio2012の場合 ※インストールディレクトリによって異なる場合があります。)。
 +
 
 +
 
 +
guidgen.exeでGUIDの生成が出来ます。
 +
:guidgen.exeはC:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Toolsにあります(VisualStudio2012の場合 ※インストールディレクトリによって異なる場合があります。)。
  
  
134行: 186行:
  
 
=='''<nowiki>#</nowiki>error'''==
 
=='''<nowiki>#</nowiki>error'''==
 +
ディレクディブの後ろに半角スペースのトークンを挟んで、エラーメッセージを記述します。ただし、日本語SJISコードでプログラムを記述している場合には日本語コードの中の5Cが使われる文字がある場合、1行のディレクティブを複数の行で記述するための改行文字であると処理しようとするため、例えば、「表示」のような記述をする場合は、表\示として、改行の打消しをする必要があります。改行を宣言する \ をつかった後ろに文字コードがあるのはディレクティブ記述の違反となります。
  
 +
 +
<nowiki>#error</nowiki>ディレクティブは以下のような形式になります。
 +
 +
 +
'''#error エラーメッセージ'''
 +
 +
 +
仕様例としては、ディレクティブ処理におけるエラーになる何らかの条件を満たしたときにエラーを吐き出すために以下のような方法で利用されます。
 +
<syntaxhighlight lang="text">
 +
#if *****
 +
#error xxx.libタイプライブラリが読み込まれませんでした。
 +
#endif
 +
</syntaxhighlight>
 +
 
  
 
=='''<nowiki>#</nowiki>if/<nowiki>#</nowiki>elif/<nowiki>#</nowiki>else/<nowiki>#</nowiki>endif'''==
 
=='''<nowiki>#</nowiki>if/<nowiki>#</nowiki>elif/<nowiki>#</nowiki>else/<nowiki>#</nowiki>endif'''==
 
プリプロセッサの制御用構文です。プログラム内のif文とよく似ている制御構造を持つことが出来ますが、比較演算子に使われる変数はマクロとよばれる変数によってあらかじめ定義されていなければ、うまく比較することができないかったり、プログラム内と同等の複雑な比較演算はできないことが異なります。#ifはif、#elifはelse if、#elseはelseによく似ている働きに相当しますが、{ }による制御実行範囲の指定がないため、
 
プリプロセッサの制御用構文です。プログラム内のif文とよく似ている制御構造を持つことが出来ますが、比較演算子に使われる変数はマクロとよばれる変数によってあらかじめ定義されていなければ、うまく比較することができないかったり、プログラム内と同等の複雑な比較演算はできないことが異なります。#ifはif、#elifはelse if、#elseはelseによく似ている働きに相当しますが、{ }による制御実行範囲の指定がないため、
 
制御構造の終端に#endifと記述する必要があり、#if~#endifの間に記述されているないようがプリプロセッサの制御構造となります。制御構造内にあれば#elifは何度でも利用できて、#else~#endifはどれにもあてはまらない場合の処理区間となます。#elifと#elseは必要なければ、省略することが可能です。
 
制御構造の終端に#endifと記述する必要があり、#if~#endifの間に記述されているないようがプリプロセッサの制御構造となります。制御構造内にあれば#elifは何度でも利用できて、#else~#endifはどれにもあてはまらない場合の処理区間となます。#elifと#elseは必要なければ、省略することが可能です。
 +
 +
 +
プリプロセッサ演算子のdefined()を比較演算子の結果として利用することができるため
 +
<syntaxhighlight lang="cpp">
 +
#define __MYDIRECTIVE_MACRO__
 +
 +
 +
 +
 +
#if defined(__MYDIRECTIVE_MACRO__)
 +
    f = 1;
 +
#else
 +
    f = 0;
 +
#endif
 +
</syntaxhighlight>
 +
のように__MYDIRECTIVE_MACRO__というマクロが定義されているかどうかを判定するプリプロセッサ演算子を比較演算子に使うことができます。そのほかの比較演算子としては >=、<=、>、<、==、!= が利用できます。#ifディレクディブの後に続く部分に条件を記述しますが、条件としての比較演算子の演算結果が0なら偽:falseであり、それ以外なら真:trueとなります。条件は比較演算子以外にもマクロの値そのものでも良いです。 #if defined(__MYDIRECTIVE_MACRO__)を#ifdef __MYDIRECTIVE_MACRO__と書き換えることのできる#ifdefディレクティブや#ifndefディレクティブも存在します。
 +
 +
 +
この項目の記事はマクロについて理解していないと、わからないと思いますので、さらにマクロについての理解を深めることをお勧めします。
  
 
=='''<nowiki>#</nowiki>ifdef/<nowiki>#</nowiki>ifndef'''==
 
=='''<nowiki>#</nowiki>ifdef/<nowiki>#</nowiki>ifndef'''==
 +
<nowiki>#</nowiki>ifdefディレクティブや#ifndefディレクティブは#ifディレクティブの利用方法の一部の記述を簡略化するためのディレクティブです。
 +
<syntaxhighlight lang="text">
 +
#ifdef __MYDIRECTIVE_MACRO__
 +
 +
#endif
 +
</syntaxhighlight>
 +
 +
と記述した場合
 +
 +
 +
<syntaxhighlight lang="text">
 +
#if defined(__MYDIRECTIVE_MACRO__)
 +
 +
#endif
 +
</syntaxhighlight>
 +
 +
と同等の記述をしたことになります。#ifディレクティブやdefined()ディレクティブ演算子の動作内容については#ifの説明をした項目を参照して下さい。
 +
 +
 +
<nowiki>#</nowiki>ifndefはif nof defineを省略した意味を持っていて、
 +
 +
<syntaxhighlight lang="text">
 +
#ifndef __MYDIRECTIVE_MACRO__
 +
 +
#endif
 +
</syntaxhighlight>
 +
 +
と記述した場合
 +
 +
<syntaxhighlight lang="text">
 +
#if defined(__MYDIRECTIVE_MACRO__)
 +
#else
 +
 +
#endif
 +
</syntaxhighlight>
 +
 +
 +
という具合の#elseディレクティブの範囲の事象だけ実行する範囲として制御できます。もちろん、#ifndefの後に#elseを使うことは出来て、マクロが定義されている場合の制御構文についても記載できます。
 +
 +
<syntaxhighlight lang="text">
 +
#ifndef __MYDIRECTIVE_MACRO__
 +
 +
~  ※__MYDIRECTIVE_MACRO__ というマクロが定義されていない場合の処理
 +
 +
#else
 +
 +
~  ※__MYDIRECTIVE_MACRO__ というマクロが定義されている場合の処理
 +
 +
#endif
 +
</syntaxhighlight>
 +
 +
 +
<nowiki>#</nowiki>ifディレクティブの使い方とdefinedディレクティブ演算子とマクロの使い方を理解していないとこの項目は理解できないと思います。
 +
 +
 +
=='''<nowiki>#</nowiki>define/<nowiki>#</nowiki>undef'''==
 +
*[[C マクロ##define|#define]]
 +
*[[C マクロ##undef|#undef]]
 +
 +
詳細な説明は上記の個別記事の項目を参照して下さい。
 +
 +
=='''<nowiki>#</nowiki>pragma'''==
 +
*[[C プラグマ##pragma|#pragma]]
 +
 +
詳細な説明は上記の個別記事の項目を参照して下さい。
 +
 +
 +
[[C PlusPlus#Cにもあった技術|C++]]へ戻る

2020年7月15日 (水) 00:00時点における最新版



個人用ツール
名前空間

変種
操作
案内
ツールボックス