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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

38206閲覧

#ifdef #endif の使い方。

saito.kaz

総合スコア76

C

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

1クリップ

投稿2016/03/31 06:04

###前提・実現したいこと

#ifdef #endifの使い方に混乱しております。
参考書なので、これの使い方について理解したつもりですが、勉強のために長いコードを拝見すると、ヘッダーファイルや、メインプログラムの先頭に、#ifdef #endif
elif や else など様々なコマンドがあり、なかなか理解することができません。

申し訳ないですが、簡単に説明していただくことはできますでしょうか。下記のコードはネットで見つけたサンプルです。 参考書で理解したつもりが、下記のコードを見てぜんぜん分からなくなり、混乱してしまいました。

###ソースコード

#define SLASH '\\' #else #define SLASH '/' #endif 他 #ifdef LIBTK_EXPORTS # if defined(__lint) # define TKEXPORT __export(TK) # define TKGLOBAL extern __global(TK) # define TKPRIVATE extern __private(TK) # elif defined(_WIN32) # define TKEXPORT __declspec(dllexport) # define TKGLOBAL extern __declspec(dllexport) # define TKPRIVATE extern # else # define TKEXPORT # define TKGLOBAL extern # define TKPRIVATE extern # endif #else # if defined(__lint) # define TKEXPORT __export(TK) # define TKGLOBAL extern __global(TK) # elif defined(_WIN32) && !defined(WNT_STATIC_LINK) # define TKEXPORT __declspec(dllimport) # define TKGLOBAL extern __declspec(dllimport) # else # define TKEXPORT # define TKGLOBAL extern # endif #endif
mahbou3👍を押しています

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

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

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

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

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

guest

回答3

0

ベストアンサー

#ifdef#endifの使われるパターンはだいたい次の三つに分かれます。

  1. インクルードガード

ヘッダファイルが二重に読み込まれるのを防ぐために使います。ただ、最近は同じ事を実現可能な#pragma once(非標準の機能です)に対応したコンパイラがほとんどのため、想定しているコンパイラが限定されている場合は#pragma onceを使うことが多いようです(特にVC++向けのプログラムは)。

  1. 環境(OSやコンパイラなど)の違いを吸収するため

例えば、Windowsではフォルダの区切りは\ですが、UNIX(Mac含む)/Linuxでは/です。このようにOSやコンパイラによって違いが出てくるときがあり、それぞれ別の処理が必要になる場合があります。OSやコンパイラによって定義済みのマクロが異なる(たとえば、Windowsだと_WIN32が定義されるが、それ以外ではされない)ため、それを#ifdefでチェックすることで、Windowsのみでの動作、UNIX(Mac含む)/Linuxのみでの動作と分けることが可能になります。この分岐はコンパイル時に行われるため、実行時に分岐の処理分遅くなると言うこともありません。

  1. 機能のON/OFF

使用者が少ない非常にマイナーな機能やまだバグが残っているかも知れない実験的な機能は不要であれば無効にできた方がいいでしょう。また、デバッグの有効/無効でログの出方等も調整したいと思うでしょう。そこでC/C++ではコンパイル時に定義済みのマクロを指定できるようになっています。例えばgccで-DDEBUGとオプションをつけると#define DEBUGが一番最初に書かれた場合と同じ効果が得られます。それを利用して、DEBUGが定義済みの時だけ、詳細メッセージを出すと言ったことができます。この分岐もコンパイル時に行われるため、実行時の処理速度に影響を与えません。

投稿2016/03/31 08:35

raccy

総合スコア21733

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

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

saito.kaz

2016/03/31 11:18

詳細な説明ありがとうございます。 とても助かりました。
guest

0

こんにちは。

たぶん、冒頭のソースは正しくは下記ですね。

C

1#ifdef _WIN32 2#define SLASH '\\' 3#else 4#define SLASH '/' 5#endif

_WIN32は定義済マクロと言って、Windows上で走るプログラムをコンパイルするとき、コンパイラの方で勝手に定義しているマクロです。

そして、#define#ifdef等の#で始まる文は、全て「プリプロセッサ」とよばれるコンパイルの前処理プログラムで処理されます。(実際にはコンパイラが直接処理する場合もありますが、標準規格は別プログラムが処理することを前提としていますので、コンパイラは処理しないと考えた方が理解しやすいです。)

#ifdefは、その後に書かれたマクロが定義されていたら、#elseもしくは#endifまでを残してコンパイラへ引き渡します。つまり、もし、そのマクロが定義されてなければ、コンパイラへ渡されないのでコンパイルされません。


【ところで】
まずは検索することをお勧めします。その結果、判らないことを質問されると喜ばれます。
下記は#ifdefでググってでてきた最初の2つてす。
16.2.1 #ifdef 文
#ifdef ~ #else ~ #endif

投稿2016/03/31 06:49

Chironian

総合スコア23272

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

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

saito.kaz

2016/03/31 08:04

申し訳ありません。 今後の学習に活かします。 ありがとうございます。
guest

0

C

1#if (条件式) 2なにか 3#elif (条件式) 4なにか 5#else 6なにか 7#endif

は、C言語(など)で言うところの

C

1if (条件式) { 2 なにか 3} 4else if (条件式){ 5 なにか 6} 7else{ 8 なにか 9}

と大雑把に言えば対応してます。
用語も大体一緒のはずです。

#ifdef FOO#if defined(FOO)と同じ意味です:「FOOが定義されていたら~」
#ifndef FOO#if !defined(FOO)と同じ意味です。

投稿2016/03/31 06:29

編集2016/03/31 06:39
ozwk

総合スコア13512

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

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

saito.kaz

2016/03/31 06:32

#ifdef __cplusplus extern "C" { #endif のような ”#ifdef”とはなんでしょうか。
ozwk

2016/03/31 06:37

更新しました。 それ参考書に書いてないんですか?
HiroshiWatanabe

2016/03/31 07:07

>#ifdef __cplusplus >extern "C" { >#endif > >のような ”#ifdef”とはなんでしょうか。 "#ifdef __cplusplus" は "もし__cplusplusが定義されていたら真" になります "#endif" は "#if" や "#else" 等のブロックがそこで終了するというエンドマークです なのでこの場合は もし __cplusplus が定義されているのなら extern "C" { とする という事になりますね
saito.kaz

2016/03/31 11:19

ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問