• ベストアンサー

ソースとヘッダについて

zwiの回答

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.7

C++/CLI系の文法には詳しくないので内容には触れませんが、 #define き tree #define せ き->SelectedNode #define か TN^ a=(TN^)せ #define あ Nodes->Add #define れ if (!a) return これはまたすごい・・・。半年とか経つと自分でなぜこうしたか忘れないか私は不安ですが。普通マクロ名は、機能を表す名前を使います。理由は忘れるから。 じゃあ、同じソースコード内でも前半と後半でおなじ「き」でも意味が違うってコードを考えているんですね。 その1。いちいちエディタでカーソルかざさないと機能が確認できないのは可読性が低いのが問題かと。 2.#dafineで定義されたものが増えてくると混乱するかも。 3.マクロを多用するとプログラムコードが増大する(今時のメモリなら気にしなくて良いが)のと、マクロ内でエラーが発生するとデバッガのカーソルが止まるのはマクロの名前の部分なので、どの部分か判断に困りますのでそこが気になるかな。 まぁ、他の人に見せるコードじゃなければ何をやって良いのですが、一度やってみて作れるか作れないか、可読性が良いかは自分で判断すればよいと思います。デバッグで困ったり一月後に読めなくければ大丈夫かと。 #define ご(x,y) if (x) goto y; まぁ、構文的には普通ですがgotoはあまり多用しないほうがと要らぬお節介を書いときます。 >「同じソース」には「#pragma onceを書いたファイル自身」をプリプロセッサが一回しかincludeをしないでOKですか? コンパイルの単位=ソースコード内に一回しか#includeさえません。 >そして、「同じヘッダにも」その効果は適用されますか? #includeのファイルがネストしていても同じです。 #include "a.h"と成っていてa.h内で#include "b.h"だとしたらa.hとb.hに各々「#pragma once」が書かれていれば一回しかインクルードされません。 >そしてもしそうならつまり、ソースあるいはヘッダが異なればそれぞれで「一回ずつは許容される」という意味になりますよね? いえヘッダがヘッダをインクルードしている場合は、違うと思うんですけどね。実験したことが無いので試してみてください。 >ということは、逆に言うと#pragma onceをつけないヘッダなら、同じファイル内で複数回includeしてもOKになる、ということでしょうか? 同じ定義を#undefなしに#defineするとエラーになりますけどね。 >む?よく考えてみるとところで……ソースファイルは、インクルードする方法はあるのでしょうか? #includeは実は何でもインクルードできます。 #include "aa.cpp"もOKです。

LongSecret
質問者

お礼

はい、実はgotoについては( )と2つの引数(?)の実験として作ったという意味合いの方が強く、これを使おうと思う場合は結構限られてて 「沢山のif()~があって、それが同じような結果を出す場合で、try catch にしたくない場合」 「何層にもなったループ文の内側の方から、一定の状況の時に一気に抜け出したい場合」 ぐらいです。 なので、消しても問題ないぐらいだとは思っています。 他で充分同等に書けるようなところでgotoを多用すると可読性下がる可能性高し!というのは納得ですからね。 残りの事につきましても、納得しました。ありがとうございます!

LongSecret
質問者

補足

あ!いい事思いつきました。 万が一それでも忘れた場合の事を考えて「以下の理由づけをコメントでそれらdefineの右側にでも書いておけばいい」ですよね? そうすれば万が一忘れても、また一回見れば「ああ、そうそう」 で、それ以後またそれでやっていけますので…。 おかげさまで思いつけました。ありがとうございます。 (早速メモっておこう。)

関連するQ&A

  • 新規ソース内のマクロ定義が既存ソース内のマクロ定義と衝突しない策について

    C言語です。 Effective C++か何かで読んだ const int hoge = 3; const char *bar = "HOGEHOGE"; などを使用しようと思ったのですが、 C言語ではコンパイルする際に、 「関数の外では定数は宣言できません」?? のようなエラーが出てしまいました。 そこでこれらを使用するのは諦めて、 #define~を使って定数を使用しました。 (上記のようなエラーが出てしまうのは、 C言語の仕様上、文法がおかしいからだと 思います。そもそもC++に関する本に 載ってるtipsだし^^;) #defineを使用するように修正して、コンパイルする際に、 既存のソース上のマクロ定義(#define~)と名前が重複するものが いくつか見つかり、修正に手間がかかりました。 マクロ定義なので、スコープという概念は 適用されないと思うので、既存のソースと新規のソースで マクロ定義がバッティングしないようにする策としては どのようなものがあるでしょうか? 今のところ思いつくものとしては以下です。 ・新規のソースに関するキーワードをプリフィックスとして使用する ・新規のソースの末尾で#undefをする。(これは試してないので有効か  どうか自信がありません。) 他に何か有効な策がありましたら教えてください。 よろしくお願いいたします。

  • 関数の実体定義にヘッダファイルの2重定義防止方法が効かない?

    いつもお世話になっています。 MFCでCプログラミングをしています。 ヘッダファイルの2重定義防止のために、 ヘッダファイル全体を下記のように 囲みました。 <aaa.h> #ifndef AAA #define AAA #define PI 3.141592 void Func(); int wa(int a, int b){ return a+b; } #endif ビルドしたところ、 関数宣言(Func)や#define部分(PI)については、 2重定義が防止されているようなのですが、 関数の実体部分(関数wa)については、 2重定義防止機能が働かず、 ***.obj : error LNK2005: "int __cdecl wa(int a, int b)" は既に ***.obj で定義されています。 というリンクエラーが表示されます。 関数の種類や ヘッダファイル内の宣言の順番を いろいろ変えてみたのですが同じ結果でした。 ここで、このヘッダファイルの先頭に #pragma onceを使用すると このリンクエラーは回避されるのですが、 他コンパイラとの互換性の観点から、 #pragma once以外の方法で実現する必要があるので、 困っています。 URLを検索してみたのですが、 このような特殊な場合について記述されているものは 見つけられませんでした。 どなたか解決法又はヒントをご教示頂ければ ありがたいです。 よろしくお願いします。

  • VisualC++のプリプロセッサ定義とビルド関係

    VisualC++のプロジェクトには「#define _MYDEBUG」というプリプロセッサと同じ働きをするプリプロセッサ定義という設定項目がプロジェクトのプロパティにありますが、これらがコンパイラによって使用されるタイミングはどのようなものでしょうか? VisualC++コンパイラがソースパーズ時にプロジェクトのプリプロセッサ設定を参照しに行ってコンパイル結果に反映させるといったことが行われているのでしょうか?

  • defineで定数が置き換えられない?(C言語)

    #defineについて質問です。 #defineは、ソースコード内にこの文字を見つけたら、コンパイルする前にこの文字をこの定数に置き換えて、というプリプロセッサですよね?だから、printfで#defineで定義した定数を出力する場合で、変換指定が必要ない場合は #include <stdio.h> #define DEF 100 void main(){ printf("#defineで定義された定数はDEFです"); } でもいいと思うんです。ですがこのソースコードは間違いで、実行結果は #defineで定義された定数はDEFです(←置き換えられてない) となってしまします。プリプロセッサだけ実行しても、DEFは100に置き換えられずそのままです。printfで#defineで定義した定数を出力させたい場合は書式指定をしなければなりません。なぜ、このような場合は#defineで定義した定数は置き換えられないのでしょうか?回答よろしくお願いします。

  • C言語 共通ヘッダ作成の学習に関する事

    共通ヘッダー作成の学習をしています。 共通ヘッダ <getputch.h> #ifndef __GETPUTCH #define __GETPUTCH #if defined(_MSC_VER) || (__TURBOC__) || (LSI_C) /* MS-Windows / MS-DOS系 */ #include <conio.h> #static void init_getputch(void) {} #static void term_getputch(void) {} #else /* Cursesライブラリが提供されるUNIX/Linux/macOS */ #include <curses.h> #include <stdio.h> #include <string.h> #undef getch #undef putchar #undef puts #undef printf #undef scanf static void init_getputch(void) { initscr(); refresh(); } static void term_getputch(void) { endwin(); } static int putch(int ch) { int result = addch(ch) == OK ? ch : EOF; refresh(); return result; } static int __putchar(int ch) { return putch(ch); } static int __printf(const char *format, ...) { int count; va_list ap; static char __buf[4096]; va_start(ap, format); vsprintf(__buf, format, ap); va_end(ap); count = printw("%s", __buf) == OK ? strlen(__buf) : EOF; refresh(); return count; } static int __puts(const char *s) { int count = printw("%s\n", s) == OK ? strlen(s) + 1 : EOF; refresh(); return count; } static int __getch(void) { int ch; cbreak(); noecho(); ch = getch(); nocbreak(); echo(); return ch; } #define getch __getch #define putchar __putchar #define printf __printf #define puts __puts #define scanf __scanw #endif #endif 私が使用しているOSはWindows10、 エディタ Visual Studio Code1.89.1 です。 コンパイルしたら<curses.h>のファイルが見つからない旨の エラーメッセージが出ます。 説明では、 _MSC_VER、__TURBOC__、LSI_Cは、それぞれVisualC++、 Borland C++(Turbo C++)、LSI Cの処理系で、処理系識別のために 独自に定義されているマクロです。 上記以外のMS-Windows用の処理系をお使いであれば、その処理系で 独自に定義されているマクロを追加する必要があります。 という事です。 もしかしたら、マクロを追加しないといけないのかもしれませんが 調べ方が分かりません。 どうしたら良いのでしょうか。ご指南を頂きたく投稿しました。

  • C言語でヘッダファイルを自作する

    C言語で#defineを用いてヘッダファイルを作成したのですが、 作成したコンパイルするときにヘッダファイルがオープンできません。 参考にしている資料があるのですが、そこに書かれているサンプルプログラムを 丸ごとコピーして作ったプログラムも同様にヘッダファイルがオープンできない というエラーが出るので、ヘッダファイルを定義する方法そのものが間違っていると 思うのですが、どこが間違っているのでしょうか? よろしければ正しい記述方法もお教えください。 #include <stdio.h> #if !defined SAMPLE_H #define SAMPLE_H wa(int a, int b) { return a+b; } #endif #include "sample.h" int main(){ printf("%d\n",wa(40,70)); return 0; } ヘッダファイルの定義の方法は他にもあるとは思いますが、 今回は#defineを用いた方法でお願いします。

  • ヘッダーファイルについて

    //DMusic7Ex.h あるプログラムを解析しています。 //コンパイラ設定 //多重定義防止 #pragma once //ファイルインクルード #include <dmusicc.h> #include <dmusici.h> //型定義 typedef IDirectMusicPerformance* LPDIRECTMUSICPERFORMANCE; typedef IDirectMusic* LPDIRECTMUSIC; typedef IDirectMusicLoader* LPDIRECTMUSICLOADER; typedef IDirectMusicSegment* LPDIRECTMUSICSEGMENT; //関数プロトタイプ 1・DMusic7Ex.cppを作らず他の関数で、このヘッダーファイルをインクルードする手法は一般的なのか? 2・なぜ関数プロトタイプを記述しないで、このタイプ宣言を他のファイルで使用するのは一般的なのか?

  • C言語の#defineについて

    初歩的なことですみませんが、 #define命令はソースのどこに記述しても問題ありませんか? 一応、コンパイル時には問題ないようですが。 また、#ifdef,#ifndef,#elseifとうのマクロ全般においてはどうなのですか? どなたか教えていただけませんか?

  • プリプロセッサのエラー対策がわからない状態

    こんにちは。 VS.2005でプログラミングをしているのですがプリプロセッサで起こるエラーの対策が分からずに 悩んでいます。 エラー内容は以下のとおりです。 warning C4067: プリプロセッサ ディレクティブの後に余分な文字がありました - 改行が必要です この状態を改善するには、/ZaコンパイラオプションがどうのこうのとMSのHPには載っていますが どのようにやればいいのか分かりません。 以下にソースコードを載せておきます。 #ifndef _TEXT(x) // TEXTマクロを使うとこの警告が表示されるようです。 #define _TEXT(x) __T(x) #endif この警告を無くすにはどうしたらいいでしょうか? よろしくお願いします。

  • 前処理指令行の末尾の改行の必要性

    ある本に次のような例題がありました。 「不正なヘッダ」 #define max(a,b) ((a)>(b)?(a):(b)) EOF 「正しいヘッダ」 #define max(a,b) ((a)>(b)?(a):(b)) ←Enterキー EOF ここで”不正なヘッダ”でコンパイルするとエラー表示のメッセージが表示され、その理由は”前処理指令は改行文字で終了しなければならない”との事です。又処理系によっては”不正なヘッダ”(改行文字なし)が許されるものもあると書かれていました。しかしその場合、可搬性は損なわれると書いてありました。私の処理系はRedHat Linuxでviを使っています。私の処理系で”不正なヘッダ”でコンパイルしてもなんらメッセージが無くコンパイルできました。 はたしてこの場合可搬性はあるのでしょうか? 又その本には”ソースファイルの最後の行にも必ず改行文字をつけよう”と書いてありました。しかしviを使っていてcプログラムとしてソースファイルを書いている時、最後に改行文字を入れた事はありませんでした。この場合も可搬性は失われるのでしょうか。 宜しく願います。