前の質問No.300834(関数形式マクロと空白の質問)と関連します。
関数形式マクロで、引数として入れるものは、変数でなくて型名でも構わないのでしょうか。
例えば、
#define mymul(t,x,y) ((t)(x)*(t)(y))
と定義すると、
mymul(int, 5.0, 3.5)
と呼び出すと、
((int)(5.0)*(int)(3.5))
に置き換える、
(intでキャストした 5.0 と、intでキャストした 3.5 をかける)
というのは可能でしょうか。
あと、関数形式マクロの呼び出しは、実行部分でなくてもよいのでしょうか。関数頭部(関数の本体の前の部分)で呼び出せますか。
例えば
#define ARGUMENT3(t1,v1,t2,v2,t3,v3) ¥
(t1 v1, t2 v2, t3 v3)
#define a_func b_func ARGUMENT3
と定義しておいて、
関数を定義するときに、
int a_func(int,x, char*,cp, int**,ypp)
{
・・・・
}
こんなことをすると、
int b_func(int x, char *cp, int **ypp)
{
・・・・
}
に置き換わりますか?
もし、ARGUMENT3の定義を、ARGUMENT3の後の括弧の中のカンマのつけ方を変えて、
#define ARGUMENT3(t1 v1,t2 v2,t3 v3) ¥
(t1 v1, t2 v2, t3 v3)
とし、
int a_func(int x, char* cp, int** ypp)
{
・・・・
}
こうすると、先ほどのようなb_funcの関数頭部に変換することは出来ませんか?
(関数形式マクロでこのような空白の入れ方をしてよいのでしょうか。)
No.2ベストアンサー
- 回答日時:
●#define mymul(t,x,y) ((t)(x)*(t)(y))
実際にコンパイルしてみれば分かりますが、これはOKです。期待通りにコンパイルされます。
No.1 の
> mymul(int(5.0),int(3.5))
の中にある「int(5.0)」という書式のキャストは、C++ではOKですが従来のCではコンパイルエラーになるので、注意してください。
●関数形式マクロの呼び出しは、実行部分でなくてもよいのでしょうか
関数形式かどうかに関わらず、マクロ式はどこにでも書けます。
要するにC++でいうところの「テンプレート関数」みたいなものをCで実現したいということですよね。もちろんこれも実現可能です。
> #define ARGUMENT3(t1,v1,t2,v2,t3,v3) ¥
> (t1 v1, t2 v2, t3 v3)
> #define a_func b_func ARGUMENT3
と定義して
> int a_func(int,x, char*,cp, int**,ypp)
と書くと、
> int b_func(int x, char *cp, int **ypp)
と展開されます。
ただ、マクロ引数は1つずつカンマで区切らなければならないので、
> ARGUMENT3の定義を~
> #define ARGUMENT3(t1 v1,t2 v2,t3 v3) ¥
> (t1 v1, t2 v2, t3 v3)
これはさすがにエラーとなります。
っていうか、これはもはや展開の意味ないですよね。
ARGUMENT3 の定義を消せば、期待通りにコンパイルされます。
ご回答ありがとうございます。わかりました。
No.1の
>#define mymul(x,y) (x*y)
>mymul(int(5.0),int(3.5))
>でOKです
を見たとき、私にはまったく意味がわかりませんでした。
私がC++のことを知らないためのようですね。
>C++でいうところの「テンプレート関数」みたいなものをCで実現したいということですよね。
私はC++を知らないですし、テンプレート関数というものも知らないです。
質問の
>#define a_func b_func ARGUMENT3
>と定義しておいて、
>関数を定義するときに、
>int a_func(int,x, char*,cp, int**,ypp)
>{
>・・・・
>}
これは、たまたま手に入れたソースコードの書き方です。人が書いたものなので、本当の目的は不明です。私が思うに多分、関数の分離形式(古い形式)と一括形式(ANSI C の書き方)の違いを吸収するためではないか、と思います。(ソースコードが書かれたのも、かなり前なのかもしれません。)
他の目的は私には思い浮かびません。
次のような定義がどこかにあるのかもしれません。
#ifdef hogehoge
#define ARGUMENT0( ) (void)
#define ARGUMENT1(t1, v1) (t1 v1)
#define ARGUMENT2(t1, v1, t2, v2) (t1 v1, t2 v2)
#else
#define ARGUMENT0( ) ( )
#define ARGUMENT1(t1, v1) (v1) \
t1 v1;
#define ARGUMENT2(t1, v1, t2, v2) (v1, v2) \
t1 v1; \
t2 v2;
#endif
もちろん、引数がもっとたくさんあるときにも対応できるように、ARGUMENT10くらいまで定義しておくんでしょう。
ご回答で、このソースコードの書き方に関しては、もうほとんど納得いきました。
なお、質問では、
>#define a_func b_func ARGUMENT3
と、a_func と b_func とでぜんぜん別のような名前がついていますが、
実際のソースでは、(命名規則があるらしく)似た名前になっています。
No.1
- 回答日時:
コンパイル自体できませんよ
5.0*3.5を5*3で計算したいのですよね?
#define mymul(x,y) (x*y)
mymul(int(5.0),int(3.5))
でOKです
mymul(5.0,3.5)にすれば5.0*3.5です
(キャストがわかってますよね???)
(defineがわかってますよね???)
>関数形式マクロの呼び出しは、実行部分でなくてもよいのでしょうか。
実行部分とは何でしょうか?(例がよくわからないの、何をしたいのでしょうか?)
>実行部分とは何でしょうか?(例がよくわからないの、何をしたいのでしょうか?)
実行部分などという意味不明の言葉を使ってすみません。
宣言などに対して、演算子などを使って演算する部分のことを指すつもりで使いました。
手元の『新ANSI C言語辞典』という本の「文」という項に、次のような記述があります。
「FORTRANのように宣言を文の一種として捉え、「宣言文」とする考えもあるが、K&Rと規格では、文は「実行する動作を指定する」と規定しているため、宣言は文から外されている。」
そうすると、「実行」という言葉を使うのも、当たらずとも遠からず、といった感じだと思います。
厳密には「文」という表現になるんでしょうか。
いずれにしても、質問の後半の意図は、関数頭部で使えるのか、ということです。
これは回答No.2で解決しました。もう問題はありません。
(関数頭部という言葉は、手元の『明解C言語入門編 例解演習』(柴田望洋 著)という本で使われているので、大丈夫だと思います。)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- C言語・C++・C# ポインタの型変換、どうやるんでしたっけ? 2 2022/03/28 11:00
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Excel・Word リサーチ機能を無...
-
Excel マクロ VBA プロシー...
-
特定のPCだけ動作しないVBAマク...
-
エクセルで特定の列が0表示の場...
-
メッセージボックスのOKボタ...
-
マクロの連続実行
-
一つのTeratermのマクロで複数...
-
TERA TERMを隠す方法
-
エクセルで別のセルにあるふり...
-
エクセルに張り付けた写真のフ...
-
ExcelのVBA。public変数の値が...
-
VBAでカタカナ→ローマ字の変換...
-
EXCELのVBAでRange("A1:C4")を...
-
特定文字のある行の前に空白行...
-
Excel 改ページのVBAうまくい...
-
ExcelVBAでPDFを閉じるソース
-
ExcelVBA 図形をクリックした...
-
VBAのIF分で時間指定の条件式の...
-
エクセルのマクロについて教え...
-
エクセルのマクロについて教え...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excel・Word リサーチ機能を無...
-
特定のPCだけ動作しないVBAマク...
-
エクセルで特定の列が0表示の場...
-
Excel マクロ VBA プロシー...
-
メッセージボックスのOKボタ...
-
一つのTeratermのマクロで複数...
-
ExcelのVBA。public変数の値が...
-
エクセルに張り付けた写真のフ...
-
他人が作ったマクロの理解
-
ExcelVBAでPDFを閉じるソース
-
TERA TERMを隠す方法
-
エクセルで別のセルにあるふり...
-
マクロ実行時、ユーザーフォー...
-
Excel VBAからAccessマクロを実...
-
EXCELのVBAでRange("A1:C4")を...
-
TeraTermマクロの文字列結合
-
PDF出力マクロについて。マクロ...
-
#defineの定数を文字列として読...
-
エクセルのマクロをセルの値に...
-
wordを起動した際に特定のペー...
おすすめ情報