ソースファイルのはじめに#include<> や #include ~.hppを記述するやり方は見慣れていて特に何も考えずスルーしていたのですが、最近ソースファイルの途中で#includeを記述しているのを見かけました。
これはどういった技術名?テクニック名?なんでしょうか?
何を行う時に使用するのでしょうか教えてください。
僕が見たのは以下のような使い方です。(うる覚えです)
bbb.cファイル
struct a{
~;
~;
~;
};
a = {
'#include aaaa.h
};
aaaa.hファイル
'#define MACRO(x,y,z) {z,y,z},
extern {
'MACRO(x1,y1,z1)
:
:
:
}
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答5件
0
ベストアンサー
こんにちは。
私も名前は知らないのですが、時々使います。
#define MACRO(...
は、bbb.cファイル側にあるはずです。
aaaa.hファイルには、下記のようなイメージの筈です。
C
1MACRO(x1,y1,z1) 2MACRO(x2,y2,z2) 3MACRO(x3,y3,z3)
#define MACRO(x,y,z) {x,y,z},
と定義した場合、aaaa.hは下記のように展開されます。
C
1{x1,y1,z1}, 2{x2,y2,z2}, 3{x3,y3,z3},
これをインクルードした結果、bbbb.cファイルは下記のように展開されます。
C
1struct a{ 2 ~; 3 ~; 4 ~; 5}; 6 7a = { 8{x1,y1,z1}, 9{x2,y2,z2}, 10{x3,y3,z3}, 11};
もしかすると、x1,y1,z1を{"x1","y1","z1"}のような文字列で受け取りたい場合もあるかもしれません。
その時は、`#define MACRO(x,y,z) {#x,#y,#z},
と定義すればできます。
このように「本質的に同じものを異なる形式で解釈したいものが、多数ある時」に使うと便利なテクニックです。
デバッグがたいへんやりにくくなりますので痛し痒しですが、本質的に同じものを書式を変えて何度も書くよりは良いと思います。
投稿2016/12/29 14:26
総合スコア23274
0
プリプロセッサの普通の機能です。
プリプロセッサの#includeディレクティブは、「#include <ファイル名>」または「#include "ファイル名"」の部分をそのファイルの内容に置き換えたものをコンパイラ本体に渡す、それ未満でもそれを超えるものでもありません。インクルードされるファイルにどのようなことが書かれていても、#includeディレクティブをどこで使っても、プリプロセッサは機械的にマージしてコンパイラ本体に渡すので、C/C++言語的な事項に関してはコンパイラ本体にお任せです。
ご存じかと思いますが、マクロの展開、#ifdefディレクティブなどに基づくコードの抑制、#ifディレクティブの右に書かれた定数式の評価などをプリプロセッサが行います。コメント/* */ // の除去をプリプロセッサで行うコンパイラもありますね。
マクロ定義や関数のプロトタイプ宣言、構造体・クラスの宣言をヘッダファイルと呼ばれるファイルに分離して、ソースファイルの先頭部分の#includeディレクティブによってコンパイル時にマージするのは、その方が開発・保守効率が良いゆえの慣習です。#includeディレクティブをソースファイルの最後に持ってきてもプリプロセッサ的には問題ありません。ただ、C++のメンバの定義にはメンバの宣言が先行していなければコンパイラ本体でエラーになるので、そうしない慣例になっているにすぎません。また、同クラス同関数定義をヘッダファイルに書き、複数のソースファイルでインクルードすればリンクエラーになります。
ぶっちゃけ、ヘッダファイルに何を書こうが、#includeディレクティブをどのように使おうが、エラーにならない限り自由です。でも、実際上の約束があることはご存じのとおりです。宣言を手動でいちいち複数のソースファイル間でコピペしていれば保守性が悪いからしません。
よって、エラーにならず保守性が良ければ、ヘッダファイル・#includeディレクティブをどのような利用法も可能だと思います。
gccでは-Eオプション、他のコンパイラでも同様の手段でプリプロセッサ実行だけがなされるので、その結果をご覧になると良くわかるかと思います。
投稿2016/12/29 17:01
総合スコア1105
0
各種データ値を開発終盤まで正確に値は決められない(たびたび変更しながら調整していく)けど、ファイル化して実行時に読ませるということはしたくない、できれば実行モジュールに埋め込みたい、かといってハードコーディングだとその都度ソースコードを編集しないといけなくなりミスを誘発してしまうのでそれは避けたい、というときに、ソースコードの「データ部分だけを別ファイル」にして、それをソースコードの途中に「埋め込む」という手法をとることがよくあります。その際、データをカンマで区切ったCSVファイルのような形式にすることが多いです。配列や構造体などの代入書式と親和性が高いからです。
データを別のツール(例えばExcelなど)で管理し、それをテキストファイルで出力してソースコードに埋め込む、というように使うことも多いです。
ちなみに、私の場合、その目的のファイルに付ける拡張子は.hではなく.incにすることが多いです。そして、ヘッダーファイルとは呼ばずにインクルードファイルと呼びます。なぜなら、ヘッダーではないからです(ヘッダーファイルと同じ場所でインクルードするとエラーになります)。
これはどういった技術名?テクニック名?なんでしょうか?
すみません。私も聞いたことがありません。
投稿2016/12/30 02:56
総合スコア5944
0
コンパイラにとって#includeの位置は、重要です。#include は任意のファイルを書かれた場所に展開する機能によりその場所に内容を展開します。
(実際はプリプロセッサが展開してcコンパイラに渡すのですが)
・ファイルincl1.hとincl2.hで値を定義します。 >cat incl1.h int a1; >cat incl2.h char *a2; >cat hoge.c #include <stdio.h>↲ ↲ ・下記のプログラムはコンパイルエラーです。(a2が定義されていない)a2をincl2.hの後にします。 int main(int argc, char *argv[])↲ {↲ #include "incl1.h"↲ a1=1;↲ a2="bhh";↲ #include "incl2.h"↲ }↲ ~
投稿2016/12/29 15:06
編集2016/12/30 01:30総合スコア4070
0
テクニックでもなんでもありません。
#include なんちゃら
は なんちゃらの内容がそこに書き下されたのと同じ。
なのでたとえば
C++
1// CSV.h ここから 2 1, 2, 3, 4, 3 5, 6, 7, 8, 4// CSV.h ここまで 5 6// use.cpp 7int a[] = { 8#include "CSV.h" 9};
と書けば
C++
1int a[] = { 2 1, 2, 3, 4, 3 5, 6, 7, 8, 4};
ってことになります。
投稿2016/12/29 14:23
編集2016/12/29 14:26総合スコア16612
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/12/30 04:21