「C言語/前処理指令」の版間の差分

削除された内容 追加された内容
Ef3 (トーク | 投稿記録)
タグ: 2017年版ソースエディター
Ef3 (トーク | 投稿記録)
cleanup
タグ: 2017年版ソースエディター
1 行
このページでは前処理指令を網羅したが、
よく使われるのは、「インクルードガード」または「#paragma once」、「ソースファイル取り込み」、「マクロ置き換え」くらいで、
他は読み飛ばしてもかまわないだろう。
== 前処理指令の基本 ==
前処理指令( ''preprocessing directive'' )は、以下の条件を満たす前処理トークン( ''preprocessing tokens'' )のシーケンスで構成されます<ref name="jtc1-sc22-wg14-n2596-6.10">{{cite book
前処理指令とは、#前処理字句で始まり、それに続く最初の改行文字で終わる一連の前処理字句である。
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
前処理指令は、翻訳フェーズの(4)において実行される。
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
<ref>『JISX3010:2003』p.110「6.10 前処理指令」</ref>
| page = 133, §6.10 ''Preprocessing directives''
前処理指令によって、
| publisher = [http://www.open-std.org/jtc1/sc22/wg14/www/projects ISO/IEC JTC1/SC22/WG14]}}</ref><ref>『JISX3010:2003』p.110「6.10 前処理指令」</ref>。
ソースファイルの一部分を条件によって処理したり読み飛ばしたり、
 
他のソースファイルを組み込んだり、
;形式
マクロを置き換えたりすることができる。
''preprocessing-file'':
これらの処理は、概念的にはその翻訳単位の翻訳の前に行うので、前処理と呼ぶ。
''group''<sub>opt</sub>
''group'':
''group-part''
''group'' ''group-part''
''group-part'':
''if-section''
''control-line''
''text-line''
# ''non-directive''
''if-section'':
''if-group'' ''elif-groups''<sub>opt</sub> else-group<sub>opt</sub> ''endif-line''
''if-group'':
# if ''constant-expression'' ''new-line'' ''group''<sub>opt</sub>
# ifdef ''identifier'' ''new-line'' ''group''<sub>opt</sub>
# ifndef ''identifier'' ''new-line'' ''group''<sub>opt</sub>
''elif-groups'':
''elif-group''
''elif-groups'' ''elif-group''
''elif-group'':
# elif ''constant-expression'' ''new-line'' ''group''<sub>opt</sub>
else-group:
# else ''new-line'' ''group''<sub>opt</sub>
endif-line:
# endif ''new-line''
control-line:
# include ''pp-tokens'' ''new-line''
# define ''identifier'' ''replacement-list'' ''new-line''
# define ''identifier'' ''lparen'' ''identifier-list''opt )
''replacement-list'' ''new-line''
# define ''identifier'' ''lparen'' ... ) ''replacement-list'' ''new-line''
# define ''identifier'' ''lparen'' ''identifier-list'' , ... )
''replacement-list'' ''new-line''
# undef ''identifier'' ''new-line''
# line ''pp-tokens'' ''new-line''
# error ''pp-tokens''opt ''new-line''
# pragma ''pp-tokens''opt ''new-line''
# ''new-line''
text-line:
''pp-tokens''opt ''new-line''
non-directive:
''pp-tokens'' ''new-line''
''lparen'':
a ( character not immediately preceded by white space
''replacement-list'':
''pp-tokens''opt
''pp-tokens'':
''preprocessing-token''
''pp-tokens'' ''preprocessing-token''
''new-line'':
the ''new-line'' character
''identifier-list'':
''identifier''
''identifier-list'' , ''identifier''
 
; 制約事項
: 最初のトークンは <code>#</code> 前処理トークンで、(翻訳フェーズ 4 の開始時には翻訳フェーズ4の開始時に)ソースファイルの最初の文字(オプションで改行文字を含まない空白の後)か、少なくとも1つの改行文字を含む空白の後に続く <code>#</code> 前処理トークンです。
: シーケンスの最後のトークンは、シーケンスの最初のトークンに続く最初の改行文字です。
: 関数型マクロの呼び出しの中にあっても、改行文字で前処理指令を終了します。
: テキスト行は、 <code>#</code> 前処理トークンで始めてはならない。非ディレクティブは、シンタックスに表示されるディレクティブ名のいずれかで始まってはならない。また、非ディレクティブは、構文に現れたディレクティブ名で始まってはならない。
: スキップされるグループ(6.10.1)の中にある場合、ディレクティブの構文は、ディレクティブ名と次の改行文字の間に、任意の前処理トークンのシーケンスができるように緩和されます。
 
前処理指令により、ソースファイルのセクションを条件付きで処理・スキップしたり、他のソースファイルをインクルードしたり、マクロを置き換えたりすることができます。
ファイルをインクルードしたり、マクロを置き換えたりすることができます。
概念的には翻訳ユニットの翻訳前に行われるため、これらの機能は前処理と呼ばれます。
前処理ディレクティブ内の前処理トークンは、特に断りがない限り、マクロ展開の対象にはなりません。
 
== 条件付き取り込み ==
条件付き取り込み( ''Conditional inclusion'' )を制御する式は、以下を除き、整数の定数式でなければなりません<ref name="jtc1-sc22-wg14-n2596-6.10.1">{{cite book
条件付き取り込みとは、ソースファイルの一部分を条件によって処理したり読み飛ばしたりする前処理指令である。
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
| page = 134です。 §6.10.1 ''Conditional inclusion''
| publisher = [http://www.open-std.org/jtc1/sc22/wg14/www/projects ISO/IEC JTC1/SC22/WG14]}}</ref><ref>『JISX3010:2003』p.112「6.10.1 条件付き取り込み」</ref>
 
条件付き取り込み識別子(キーワードと同一記述ものを含む)以下のようになっている解釈されます
;形式
<syntaxhighlight lang=c>
defined ''identifier''
#if 定数式1
または
グループ1
defined ( ''identifier'' )
#elif 定数式2
; 識別子がマクロ名として定義されている場合
グループ2
: 定義済みであるか、#undefine が介在しない #define 前処理指令の対象となっている場合
#else
: 1 に評価されます。
グループ3
; 識別子がマクロ名として定義されている場合
#endif
:定義済みであるか、同じ識別子を持つ#undef指令の対象となっている場合
</syntaxhighlight>
: 0 に評価されます。
条件付包含式( conditional inclusion expression )は、以下の形式の単項演算子式を含むことができます。
__has_c_attribute ( ''pp-tokens'' )
これらはです。前処理トークンを属性トークンとして解釈して指定された名前の属性を実装がサポートしている場合はです。整数定数の形式に一致する0でないpp-numberで置き換えられです。そうでない場合は0で置き換えられる。前処理トークンは、属性トークンの形式と一致しなければなりません。
 
すべてのマクロ置換が行われた後に(制御式となる前処理トークンのリストに)残る各前処理トークンは、トークンの語彙形式でなければならない(6.4)。
 #if,#elif,#elseは、それぞれ制御文のif,else if,elseと同様の使い方をする。
すなわち、定数式1が真(0以外)の場合グループ1が実行され、
それ以外の場合で定数式2が真(0以外)の場合グループ2が実行され、
さらにそれ以外の場合グループ3が実行される。
 
また、#ifdef、#ifndef、および定義済み条件付き包含演算子は、 __has_c_attribute を定義済みマクロの名前であるかのように扱うものとします。識別子 __has_c_attribute は、本節で言及されていないいかなる文脈にも登場してはなりません。
定数式では次の形式の単項演算子式を含んでもよい。
;形式
<syntaxhighlight lang=c>
# if ''constant-expression'' ''new-line'' ''group''<sub>opt</sub>
defined 識別子
# elif ''constant-expression'' ''new-line'' ''group''<sub>opt</sub>
defined (識別子)
制御する定数式の評価値がゼロでないかどうかをチェックします。
</syntaxhighlight>
defined単項演算子は、
識別子がその時点でマクロ名として定義している場合1と評価し、
そうでない場合0と評価する。
 
評価の前に、制御する定数式となる前処理トークンのリスト内のマクロ呼び出しは、通常のテキストと同様に置き換えられます(定義された単項演算子によって修正されたマクロ名を除く)。
また、次の形式の前処理指令もある。
<syntaxhighlight lang=c>
#ifdef 識別子
グループ
#endif
</syntaxhighlight>
これは次の前処理指令と等価である。
<syntaxhighlight lang=c>
#if defined 識別子
グループ
#endif
</syntaxhighlight>
 
この置換処理の結果として定義されたトークンが生成されたり、定義された単項演算子の使用がマクロ置換前の 2 つの指定された形式のうちの 1 つと一致しない場合、その動作は未定義です。
<syntaxhighlight lang=c>
#ifndef 識別子
グループ
#endif
</syntaxhighlight>
これは次の前処理指令と等価である。
<syntaxhighlight lang=c>
#if !defined 識別子
グループ
#endif
</syntaxhighlight>
 
マクロの展開とdefinedおよび__has_c_attribute単項演算子の評価によるすべての置き換えが実行された後、残りのすべての識別子(キーワードと語彙的に同一のものを含む)がpp-number 0に置き換えられ、その後、各前処理トークンがトークンに変換されます<ref>この未定義の識別子を 0 と解釈する挙動のため、識別子のミススペルがあたかも 0 を定義しているように見える事による発見困難なバグの原因になります。⇒ [[#未定義マクロの値]]</ref>。
<ref>『JISX3010:2003』p.112「6.10.1 条件付き取り込み」</ref>
 
結果のトークンは、6.6の規則に従って評価される制御定数式を構成します。
 
このトークンの変換と評価のために、すべての符号付き整数型とすべての符号なし整数型は、それぞれヘッダーの<stdint.h>で定義されているintmax_t型とuintmax_t型と同じ表現を持っているかのように動作します。
 
これには、文字定数の解釈も含まれており、エスケープシーケンスを実行文字セットのメンバーに変換する必要がある場合もあります。これらの文字定数の数値が、同じ文字定数が式の中(#ifや#elif命令の中を除く)に出現したときの値と一致するかどうかは、実装によって決まります。
 
 
=== 未定義マクロの値 ===
マクロ展開と定義済み単項演算子による置換がすべて実行された後、残りのすべての識別子(キーワードと語彙的に同一のものを含む)は pp-number<ref>§6.4.8 ''Preprocessing numbers''</ref> 0 に置換されます<ref name="jtc1-sc22-wg14-n1570-7.23">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
| title = C11: WG14/N1570 Committee Draft — April 12, 2011 ISO/IEC 9899:201x
| page=162, §6.10.1 ''Conditional inclusion''
| publisher = ISO/IEC}}</ref>。したがって、未定義マクロの値は 0 となります。
 
== ソースファイル取り込み ==
ソースファイル取り込み( Source file inclusion )とは、他のソースファイルを取り込む前処理指令です<ref name="jtc1-sc22-wg14-n2596-6.10.2">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
| page = 136, §6.10.2 ''Source file inclusion''
| publisher = [http://www.open-std.org/jtc1/sc22/wg14/www/projects ISO/IEC JTC1/SC22/WG14]}}</ref><ref>『JISX3010:2003』p.113「6.10.2 ソースファイル取り込み」</ref>。
 
;形式
# include < ''h-char-sequence'' > ''new-line''
# include " ''q-char-sequence'' " ''new-line''
 
ヘッダーファイルのインクルード
# include < ''h-char-sequence'' > ''new-line''
この形式は、実装で定義されている一連の場所を検索して、 < と > の間の指定された順序で一意に識別されるヘッダを探し、 そのディレクティブをヘッダの内容全体で置き換える。どのように場所を指定するか、どのようにヘッダを特定するかは、実装で定義されます。
 
ソースファイルのインクルード
# include " ''q-char-sequence'' " ''new-line''
この形式は、" デリミタ "の間の指定された順序で特定されるソースファイルの内容全体で、その指示を置き換えます。指定されたソースファイルは、実装で定義された方法で検索されます。この検索がサポートされていない場合や、検索に失敗した場合は、次のようにヘッダーファイルが読まれたかのように再処理されます。
 
# include < ''h-char-sequence'' > ''new-line''
 
を、元の指令と同一の含まれたシーケンス(>文字があればそれも含む)に変更します<ref>標準ヘッダーファイル(stdio.hなど)を、<syntaxhighlight lang=c inline>#include "ヘッダーファイル名"</syntaxhighlight>の形式で取り込む事は、重大なセキュリティホールとなり得るので、厳に慎むべきです。</ref>。
 
# include ''pp-tokens'' ''new-line''
 
(前の二つの形式のいずれにも一致しないもの)は許可されています。ディレクティブの include の後の前処理トークンは、通常のテキストと同様に処理されます。(現在マクロ名として定義されている各識別子は、その前処理トークンの置換リストで置換されます)。すべての置換後の指令は、前の2つの形式のいずれかに一致しなければならない。<と>の前処理トークンのペアまたは、"と"の前処理トークンを1つのヘッダー名の前処理トークンにまとめる方法は、実装で定義される。
 
=== インクルードガード ===
インクルードガードとは、複数回ヘッダファイルをインクルードすることを防止する方法である
インクルードガードの記述は次のようになっている。
 
88 ⟶ 173行目:
</syntaxhighlight>
{{See also|[[w:en:pragma once]]}}
 
=== 未定義マクロの値 ===
マクロ展開と定義済み単項演算子による置換がすべて実行された後、残りのすべての識別子(キーワードと語彙的に同一のものを含む)は pp-number<ref>§6.4.8 ''Preprocessing numbers''</ref> 0 に置換されます<ref name="jtc1-sc22-wg14-n1570-7.23">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
| title = C11: WG14/N1570 Committee Draft — April 12, 2011 ISO/IEC 9899:201x
| page=162, §6.10.1 ''Conditional inclusion''
| publisher = ISO/IEC}}</ref>。したがって、未定義マクロの値は 0 となります。
 
== ソースファイル取り込み ==
ソースファイル取り込みとは、他のソースファイルを取り込む前処理指令である。
 
ソースファイル取り込みの記述は次のようになっている。
<syntaxhighlight lang=c>
#include <h文字列>
又は
#include "q文字列"
</syntaxhighlight>
 #indlude前処理指令は、
h文字列ではヘッダを、q文字列ではソースファイルをそれぞれ取り込む。
「#include "q文字列"」の探索をサポートしていない場合や、探索が失敗した場合は、
同じ文字列を「#include <h文字列>」と読み替えたのと同じ規則で再処理する<ref>標準ヘッダーファイル(stdio.hなど)を、<syntaxhighlight lang=c inline>#include "ヘッダーファイル名"</syntaxhighlight>の形式で取り込む事は、重大なセキュリティホールとなり得るので、厳に慎むべきである。</ref>。
<ref>『JISX3010:2003』p.113「6.10.2 ソースファイル取り込み」</ref>
 
== マクロ置き換え ==
マクロ置き換えとは、マクロ名を置換要素並びで置き換える前処理指令であるす<ref>『JISX3010:2003』p.114「6.10.3 マクロ置き換え」</ref>
マクロ置き換えには、オブジェクト形式マクロと関数形式マクロがある。
 
*オブジェクト形式マクロ
次の形式の前処理指令をオブジェクト形式マクロと呼ぶ。
; 形式
<syntaxhighlight lang=c>
# define ''identifier'' ''replacement-list'' ''new-line''
#define 識別子 置換要素並び
 
</syntaxhighlight>
defineの直後に記述してある識別子をマクロ名( ''object-like macro'' )という。
オブジェクト形式マクロ( ''object-like macro'' )は、
これ以降のマクロ名を置換要素並びで置き換える。
 
*関数形式マクロ
次の形式の前処理指令を関数形式マクロ( function-like macro )と呼ぶ。
; 形式
<syntaxhighlight lang=c>
# define ''identifier'' ''lparen'' ''identifier-listopt'' ) ''replacement-list'' ''new-line''
#define 識別子(識別子並び) 置換要素並び
# define ''identifier'' ''lparen'' ... ) ''replacement-list'' ''new-line''
</syntaxhighlight>
# define ''identifier'' ''lparen'' ''identifier-list'' , ... ) ''replacement-list'' ''new-line''
 
識別子並びは省略可能で、仮引数を指定し、個々の仮引数は「,」で区切り、最後に省略記号「...」を指定してもよい。
関数形式マクロは、
134 ⟶ 199行目:
置換要素並びで置き換える(マクロ呼出し)。
 
 
<ref>『JISX3010:2003』p.114「6.10.3 マクロ置き換え」</ref>
 
=== 実引数置換 ===
実引数置換とは、関数形式マクロの実引数を識別した後行われ、実引数の中に含まれるすべてのマクロの展開後、置換要素並びの中の仮引数を対応する実引数で置き換える<ref>『JISX3010:2003』p.116「6.10.3.1 実引数置換」</ref>。
実引数の中に含まれるすべてのマクロの展開後、
置換要素並びの中の仮引数を対応する実引数で置き換える。
ただし、#前処理字句または##前処理字句が前にある仮引数と、##前処理字句が後に続く仮引数とは除く。
実引数置換の前に、実引数の前処理字句列を完全にマクロ置き換えする。
147 ⟶ 210行目:
置換要素並びの中に現れる識別子__VA_ARGS__は、それが一つの仮引数であるかのように扱われなければならない。
それを、可変個数の実引数が形成する前処理字句列で置き換える。
 
<ref>『JISX3010:2003』p.116「6.10.3.1 実引数置換」</ref>
 
=== #演算子 ===
#演算子は、文字列化演算子と呼ばれ、関数形式マクロの置換要素並びの中の仮引数の直前に付けることができ、#前処理字句と仮引数を、実引数を「"」で囲んだ単純文字列リテラルで置き換える<ref>『JISX3010:2003』p.116「6.10.3.2 #演算子」</ref>。
 #演算子は、文字列化演算子と呼ばれ、
関数形式マクロの置換要素並びの中の仮引数の直前に付けることができ、
#前処理字句と仮引数を、実引数を「"」で囲んだ単純文字列リテラルで置き換える。
その際、「"」文字及び「\」文字の前に、「\」文字が挿入される。
 
<ref>『JISX3010:2003』p.116「6.10.3.2 #演算子」</ref>
 
=== ##演算子 ===
##演算子は、トークン連結演算子と呼ばれ、オブジェクト形式マクロ又は関数形式マクロの置換要素並びの中で使われ、その直前にある字句とその直後にある字句を連結する<ref>『JISX3010:2003』p.116「6.10.3.3 ##演算子」</ref>。
 ##演算子は、トークン連結演算子と呼ばれ、
オブジェクト形式マクロ又は関数形式マクロの置換要素並びの中で使われ仮引数の直前又は直後に##前処理字句がある場合、その仮引数を対応する実引数で置き換える。
その直前にある字句とその直後にある字句を連結する。
関数形式マクロの置換要素並びの中で、
仮引数の直前又は直後に##前処理字句がある場合、
その仮引数を対応する実引数で置き換える。
<ref>『JISX3010:2003』p.116「6.10.3.3 ##演算子」</ref>
 
=== 再走査と再置き換え ===
実引数置換、#演算子及び##演算子の処理、プレースマーカー前処理字句の削除を行った後、さらに置き換えるべきマクロ名があるかどうかを調べるために、ソースファイル上のその後のすべての前処理字句とともにその結果の前処理字句を再走査する<ref>『JISX3010:2003』p.117「6.10.3.4 再走査と再置き換え」</ref>。
さらに置き換えるべきマクロ名があるかどうかを調べるために、
ソースファイル上のその後のすべての前処理字句とともにその結果の前処理字句を再走査する。
 
現在置き換え中のマクロの名前を置換要素並びのこの走査中に検出した場合や入れ子になった置き換えで現在置き換え中のマクロの名前を検出した場合は、置き換えは行わない。
入れ子になった置き換えで現在置き換え中のマクロの名前を検出した場合は、
置き換えは行わない。
 
完全にマクロ置き換えした結果の前処理字句列は、前処理指令の形をしていたとしても、前処理指令として処理することはない。
前処理指令の形をしていたとしても、
前処理指令として処理することはない。
 
<ref>『JISX3010:2003』p.117「6.10.3.4 再走査と再置き換え」</ref>
 
=== マクロ定義の有効範囲 ===
マクロ定義の有効範囲は、そのマクロ定義から、対応する#undef指令を検出するまで又は前処理翻訳単位の最後までであるす<ref>『JISX3010:2003』p.117「6.10.3.5 マクロ定義の有効範囲」</ref>
 
マクロ定義を無効にするには、次のように記述する。
189 ⟶ 235行目:
</syntaxhighlight>
識別子で無効にしたいマクロ名を指定する。
 
<ref>『JISX3010:2003』p.117「6.10.3.5 マクロ定義の有効範囲」</ref>
 
== 行制御 ==
行制御とは、この指令の次のソース行の行番号を指定する前処理指令であるす<ref>『JISX3010:2003』p.120「6.10.4 行制御」</ref>
行制御の記述は、次の2通りがある。
 
214 ⟶ 258行目:
マクロ置き換えで、上の2通りの形式のいずれかと一致せねばならず、
一致した形式の規則に従って処理する。
 
<ref>『JISX3010:2003』p.120「6.10.4 行制御」</ref>
 
== エラー指令 ==
エラー指令とは、処理系に対し、指定された前処理字句の列を含む診断メッセージを出力する前処理指令です<ref>『JISX3010:2003』p.121「6.10.5 エラー指令」</ref>。
指定された前処理字句の列を含む診断メッセージを出力する前処理指令である。
エラー指令の記述は次のようになっている。
<syntaxhighlight lang=c>
225 ⟶ 266行目:
</syntaxhighlight>
前処理字句列で出力する診断メッセージを指示する。
<ref>『JISX3010:2003』p.121「6.10.5 エラー指令」</ref>
 
== プラグマ指令 ==
プラグマ指令( ''Pragma directive'' )は、以下のような形式をしています<ref name="jtc1-sc22-wg14-n2596-76.18410.6">{{cite book
| url = http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf
| title = N2596 working draft — December 11, 2020 ISO/IEC 9899:202x (E)
259 ⟶ 299行目:
 
== 空指令 ==
空指令とは、何の効果もない前処理指令である
空指令の記述は次のようになっている。
<syntaxhighlight lang=c>
290 ⟶ 330行目:
;__DATE__
: 前処理翻訳ユニットの翻訳日:"Mmm dd yyyy "形式の文字
: ここで、月の名前はasctime関数で生成されたものと同じであり、ddの最初の文字は、その値が10未満の場合はスペース文字である
: 翻訳の日付が得られない場合は、実装で定義された有効な日付を供給しなければならない。
; __FILE__
432 ⟶ 472行目:
|__STDC_HOSTED__||処理系が規格合致ホスト処理系の場合、整数定数1。そうでない場合(つまり、フリースタンディング環境である場合)、(未定義ではなく)整数定数0。
|-
|__STDC_VERSION__||標準Cのバージョンを表す値(C95 では 199409L、C99 では 199901L、C11 では 201112L、C90 では定義されていない)。このマクロが定義されているか否か、および、定義されている場合の値は実装依存である
|-
|__TIME__||前処理翻訳単位の翻訳の時刻。("hh:mm:ss"の形式の単純文字列リテラル)
463 ⟶ 503行目:
|-
|}
※ __DATE__と__TIME__はそれを使わなければ絶対に解決できない課題を解決するためにのみ使うべきであり、それ以外の場合に安易に使うべきではない。特に、バージョン値の代用としての使用は不適切である
<ref>『JISX3010:2003』p.121「6.10.8 あらかじめ定義されたマクロ名」</ref>
 
== プラグマ演算子 ==
プラグマ演算子は、指定した文字列リテラルを文字列解除し、その結果をプラグマ指令の中の前処理字句列として実行する<ref>『JISX3010:2003』p.122「6.10.9 プラグマ演算子」</ref>
つまり、次の形式の指令は、その次の形式でも表現できる。
<syntaxhighlight lang=c>
473 ⟶ 513行目:
_Pragma("listing on \"..\\listing.dir\"")
</syntaxhighlight>
<ref>『JISX3010:2003』p.122「6.10.9 プラグマ演算子」</ref>
 
== 脚注 ==
479 ⟶ 518行目:
 
== 参考文献 ==
*日本工業標準調査会(当時、現:日本産業標準調査会)『JISX3010 プログラム言語C』2003年12月20日改正
 
[[Category:C言語]]