質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

3回答

8342閲覧

インクルードガードについて教えてください。

Green-Tea

総合スコア12

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2016/05/11 12:45

編集2016/05/11 12:59

###インクルードガードとは...

マクローリン級数展開を利用しsin(x)の関数を作成しました。
そしてこのsin(x)などの関数をまとめてヘッダファイルとして新しく作成したいです。

###試したこと
呼び出し元

C

1#include <stdio.h> 2#include <Original.h> 3 4#define PI 3.14159265 5 6int main(void){ 7//Original.hの中にある関数を呼び出して実験しています 8}
//Original.h #include <stdio.h> #define PI 3.1415 double sine(double deg){ //マクローリンのアルゴリズムがあります。 }

このときエラーが出ます。当たり前ですが。。。

これらについて調べてみたところ#ifndef - #Endif というマクロがあるのまでは分かったのですが、理解ができません。

この場合であればstdio.hがすでにインクルードされているか。されていなかったときのみインクルードする方法。PIについてもすでに定義されているか調べ、されていなかったらPIについて定義する方法をご示唆お願いします。
###環境
Visual Studio 2015

###余談
余談ですがVisual Studio 使うときになぜstdafx.hをインクルードしないといけないのですか?
またstdafx.hをインクルードしないで使用する方法とかございましたら教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2016/05/11 12:56

Original.hはどれですか?
Green-Tea

2016/05/11 12:59

すいません!!2つ目のソースプログラムがそれに当たります
guest

回答3

0

ベストアンサー

これらについて調べてみたところ#ifndef - #Endif というマクロがあるのまでは分かったのですが、理解ができません。

インクルードガードは、だいたいこんな感じで書きます。

C

1#ifndef MYPROJECT_ORIGINAL_H_ 2#define MYPROJECT_ORIGINAL_H_ 3 4//Original.h 5#include <stdio.h> 6#define PI 3.1415 7 8double sine(double deg){ 9//マクローリンのアルゴリズムがあります。 10} 11 12#endif // MYPROJECT_ORIGINAL_H_

インクルードガードは同じヘッダーファイルを何度も読み込ませないための仕組みです。
コンパイラーによって初めてそのファイルを読もうとするときにはMYPROJECT_ORIGINAL_H_が定義されていないので、#ifndefに合致し、対応する#endifまでが読み込まれます。その際、#ifndefの次の行の#define MYPROJECT_ORIGINAL_H_が実行されます。
2度目に同じファイルを読もうとしたときは、すでにMYPROJECT_ORIGINAL_H_マクロが定義されているため、#ifndefに合致せず、#endifまで読み飛ばされます。

この場合であればstdio.hがすでにインクルードされているか。されていなかったときのみインクルードする方法。

stdio.hはすでにインクルードガードが施されているので気にする必要はありません。

PIについてもすでに定義されているか調べ、されていなかったらPIについて定義する方法をご示唆お願いします。

マクロ単体でそのようにすることは通常はあまりありません。異なる値が定義されると、どれが使われるかによって結果が変わってしまうからです。Original.hの中で使うためのPIなら#define ORIGINAL_PI 3.14……という具合に、名前を変えて区別する方が良いです。

それと、ヘッダーの中に関数を書く場合はインライン関数にしてください。

C

1inline double sine(double deg){

余談ですがVisual Studio 使うときになぜstdafx.hをインクルードしないといけないのですか?
またstdafx.hをインクルードしないで使用する方法とかございましたら教えてください。

いけないわけではなく、「プリコンパイル済みヘッダー」の機能が使えるようにプロジェクト作成時にデフォルトで組み込まれているのです。プロジェクトのプロパティのC/C++の「プリコンパイル済みヘッダー」の設定で「プリコンパイル済みヘッダー」を「プリコンパイル済みヘッダーを使用しない」に変更するとstdafx.hをインクルードしなくても良くなります。

投稿2016/05/11 13:52

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Green-Tea

2016/05/11 15:00

MYPROJECT_ORIGINAL_H の "MYPROJECT"はなぜつけるんですか?
catsforepaw

2016/05/11 15:07

説明が抜けていました。インクルードガード用のマクロ名は、他と被らない独自の名前にすることが求められます。ファイル名だけでは別のプロジェクトやライブラリでも同じ名前が使われている可能性があるので、特に決まりはないですが、プロジェクト名などをくっつけることが多いです。
guest

0

まず#ifndef~#endifディレクティブですが、

C

1#ifndef HOGE 23#endif

と書いた時、HOGEというdefineが定義されている時は、その間に記述されている内容をコンパイルしないようにします(ついでに、その逆をするのが#ifdef ~ #endif)。

多分、エラーって、PIというdefineが二重定義されているという旨のものではないですか?Original.hとCソースファイルとで、違う値で定義しているので。
普通、こうした定数定義もヘッダファイルに記載します。なので、Cソースファイル側の定義を削除すればエラーは解消されると思います(少なくとも、これに関しては。他の記述がないので、他にもあるかもしれません)。

さらに言えば、ヘッダファイルには関数本体の記述はしません。プロトタイプ宣言のみを記述します。関数本体(この場合はsine())は別のソースファイルに記述して、分割コンパイルを行なうようにします(もしくはsine()等の関数をまとめたファイルをライブラリとして生成します)。

投稿2016/05/11 13:24

archiver

総合スコア1557

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Green-Tea

2016/05/11 15:02

最後のヘッダファイルには書かないってことが少し驚きました。。。。 回答ありがとうございました。
guest

0

こんにちは。

stdio.hがすでにインクルードされているか。されていなかったときのみインクルードする方法。

こちらは通常は無理です。
でも、stdio.h自身がインクルードガードがかかっているので、2重にインクルードしても2回目のインクルードは事実上無視されます。

PIについてもすでに定義されているか調べ、されていなかったらPIについて定義する方法

下記です。

C

1#ifndef PI // PIが定義されていない時のみ#endifまでコンパイルする 2 #define PI 3.14159265 3#endif

投稿2016/05/11 13:18

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Green-Tea

2016/05/11 15:02

stdio.hは特殊なヘッダファイルなんですね。。。
Chironian

2016/05/11 15:28

stdio.hは標準ライブラリのヘッダ・ファイルです。搭載されていないCコンパイラはまず存在しませんので特殊ではないです。 実は、C/C++言語では、ヘッダ・ファイルにインクルード・ガードをつけることはほぼ「常識」となってます。寧ろ、インクルードガードを付けていないインクルード・ファイルの方が特殊かも知れません。 ところで、実際に目にするインクルード・ガートは#pragma onceが多いかも知れません。コンパイラ・メーカが提供するヘッダでは良く使われてますし、お手軽なので使う人も少なくないです。 ですが、コンパイラによっては使えない可能性があるものなので、あまりお勧めはできません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問