• ベストアンサー

関数形式マクロ

type型の二つの値を交換する関数形式マクロ swap(type,a,b)を定義せよ 例えばint型でx、yに5、10があたえられているとき、swap(int,x,y)を 呼び出した後は、x,yには10と5が格納されていなければならない。 ・・という問題で以下のようにswapを作ったのですがエラーがでます どこが問題か教えていただけないでしょうか? #include <stdio.h> #define swap(type,a,b) (m = a a = b b = m) int main(void) { int x = 1,y = 2,m; swap(int,x,y); printf("x=%d y=%d\n",x,y); return(0); }

質問者が選んだベストアンサー

  • ベストアンサー
  • goosyu
  • ベストアンサー率58% (36/62)
回答No.5

#3 salsberryさんとまるかぶりしました。失礼しました。 参考になるサイトがありましたので貼っておきます。 http://www.nurs.or.jp/~sug/soft/super/macro.htm

参考URL:
http://www.nurs.or.jp/~sug/soft/super/macro.htm
Nya-22
質問者

お礼

サイトありがとうございます。また機会があればよろしくお願いします。

その他の回答 (4)

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.4

#1です。 コンパイルエラーの原因はわかっていただけたでしょうか? 参考までに,私が考えたマクロを貼っておきます。 このマクロのメリットは外部にint宣言しなくても使えることです。 #define swap(type,a,b) {type m; m = a; a = b; b = m;}

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.3

すぐに考えつくのは #define swap(type,a,b) { type m; m = a; a = b; b = m; } ですが、これだと if (x < 0) swap(int,x,y); else { ... } のような使い方をした場合に問題が出るので、もう一工夫が必要です。

Nya-22
質問者

お礼

一工夫がんばります。回答ありがとうございます。

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.2

 回答者#1です。少し情報を追加します。  プリプロセッサによって#defineマクロは展開されています。コンパイラがどのように処理しているか確認出来ますのでその方法を紹介します。  お使いのコンパイル環境のコンパイルオプション(またはスイッチ)でプリプロセッサのオプション(またはスイッチ)を探して有効にして下さい。これでどのように#defineが置き換えられているか確認出来ます。  例として「gcc」と「VC++」の設定方法について書いておきます。 【例1】「gcc」の場合  「-E」で標準出力されますので「src.c」をコンパイルする場合「gcc -E src.c > src.i」とすると「src.i」にファイルが作成されます。 【例2】「VC++」の場合  「/P」を追加してコンパイル。VisualStudio2008の統合環境からは「プロジェクト」の「プロパティページ」から「構成」の「構成プロパティ」,「C/C++」,「プリプロセッサ」を順に開き,「前処理済みファイルの生成」を「いいえ」から「行番号付き (/P)」に変更してコンパイル(ビルド)します。ソースファイルと同じ場所にソースファイルの拡張子が「.i」のファイルが生成されます。

Nya-22
質問者

お礼

返答おくれてすみません。親切な回答ありがとうございます! 何とかわかりそうなので、補足のほうも試してみたいと思います。

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.1

こんにちは早速ですが問題点について説明します。 「#define swap(type,a,b) (m = a a = b b = m)」の場合,「swap(int,x,y);」 は次のように置き換えられる事が予想されます。(この場合は単純に「a」に「x」,「b」に「y」にそれぞれ置き換えるだけです。) (m = x m = y y = m); これではコンパイルエラーが出るはずです。「m = x; m = y; y = m;」などになるような#define定義が必要です。 尚,この問題の回答としては「type」も使うようなコーディングを求められていると思います。

関連するQ&A

  • C言語のポインタの考え方について

    ポインタについて理解ができていないのでお聞きしたいのですが 値を交換する関数のプログラミングでこの場合ポインタ で以下にしないといけないと思います。 #include<stdio.h> void swap(int *a int *b){ int c; c=*a; *a=*b; *b=c; } main(){ int x,y; x=123; y=456; swap(&x,&y); printf("x = %d, y = %d\n", x, y); } またポインタを使用せず以下のプログラムではなぜダメのでしょうか。 よろしくお願い致します。 #include<stdio.h> void swap(int a int b){ int c; c=a; a=b; b=c; } main(){ int x,y; x=123; y=456; swap(x,y); printf("x = %d, y = %d\n", x, y); }

  • ユーザー関数が定義されません

    ユーザ関数について勉強しようとしてテキストの例文を打ってコンパイルしたのですが、ユーザー関数「sub1」が照合できず、ユーザー関数が使えません。 悪いところがあれば教えてください。 コンパイラはVC++です。 例文 #include <stdio.h> void main() { int a=8,b=-6; sub1(a,b); } int sub1(x,y) { int x,y; printf("x= %d y= %d",x,y); }

  • 関数のプログラムについて

    任意の二次方程式ax^2+bx+c=0をとくプログラムの作成です 引数をa,b,cとして、解の大きい方を返すというものなのですが、 僕は以下のようにして組んだのですが、うまくいきません。 と、いうより、関数の作り方がいまいちわからないです。 どこが駄目なのか教えてください。 作ってみたやつ↓ #include<math.h> #include<stdio.h> int a,b,c; double d; double x,y,z; int main(void) { a=1; b=2; c=1; printf("ax^2+bx+c=0\n "); d=b^2-4*a*c; if (d<0){printf("kyosuukai\n)} else if(d>=0) { x=(b+sqrt(b^2-4*a*c))/2*a; y=(b-sqrt(b^2-4*a*c))/2*a; if(x>=y){z=x} else if(x<y){z=y} printf("x= %f\n",z); } }

  • selection

    /*単純選択ソート*/ #include <stdio.h> #define swap(type, x, y) do {type t = x; x = y; y = t; } while (0) /*--- 単純選択ソート ---*/ void selection(int a[], int n) { int i, j; for (i = 0; i < n - 1; i++) { int min = i; for (j = i + 1; j < n; j++) if (a[j] < a[min]) min = j; swap(int, a[i], a[min]); } } int main(void) { int i; int x[7]; int nx = sizeof(x) / sizeof(x[0]); printf("%d個の整数を入力せよ。\n", nx); for (i = 0; i < nx; i++) { printf("x[%d] : ", i); scanf("%d", &x[i]); } selection(x, nx); /* 配列xを単純選択ソート */ puts("昇順にソートしました。"); for (i = 0; i < nx; i++) printf("x[%d] = %d\n", i, x[i]); return (0); } をswapなしで書き換えるにはどこを書き換えればいいですか?

  • scanf()関数の使い方について

    はじめまして。 質問があります。 以下のコードを見てください。 ---------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> int main(void) { int i; char buf[256]; int y; int m; int d; printf("文字列を入力してください:"); scanf("%s",buf); i = sscanf(buf,"%d/%d/%d",&y,&m,&d); //OK #if 0 i = sscanf(buf,"%d %d %d",&y,&m,&d); //NG #endif printf("日付 %d-%d-%d 戻り値i=%d\n",y,m,d,i); return EXIT_SUCCESS; } ---------------------------------------------------------------- 標準入力から日付を表す文字列「例:"2007/04/17"」を入力してbufに 格納したものをsscanf関数の第1引数に指定して、y,m,dを表示 させてみると、「i = sscanf(buf,"%d/%d/%d",&y,&m,&d)」では、 うまくyとmとdに日付が格納される(つまり、yに2007が入り、mには 04が入り、dには17が入る。)のですが、 「i = sscanf(buf,"%d %d %d",&y,&m,&d);」でbufに格納すると、 yにはうまく格納されるのですが、他のmとdには、うまく格納してくれ ません。これは、なぜなのでしょうか? ご教授お願いします。

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );

  • C言語の質問です。

    #include"stdio.h" int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = a+b; printf("add=%d\n", add); return 0; } と、------------------------------------------------------------------------------ #include"stdio.h" int tasizan(int x, int y); int main(void){ int a, b, add; scanf_s("%d%d", &a, &b); add = tasizan(a, b); printf("add=%d\n", add); return 0; } int tasizan(int x, int y){ int aa; aa = x + y; return aa; } の違いを教えてください。

  • 関数式マクロでエラーです。

    原因と解決方法を教えてください。 御願いします。 ・現象  Solarisでは問題なくコンパイル出来ますが、Linux(以下のバージョン参照)上ではエラーになります。  他の人によるとgcc 2.xでは問題なけれど、gcc 3.x以上ではエラーになると聞きましたが… ・質問  1.コンパイラのバージョン問題ですか?  2.解決するにはパッチが必要ですか?  3.必要だったら、何のパッチが必要ですか?  (ソースの修正なしで解決したいです。) ・エラーメッセージ: define_test.c:38:1: pasting "_test" and "(" does not give a valid preprocessing token Kernel:Red Hat Enterprise Linux AS release 4 (Nahant) Compiler:g++ (GCC) 3.4.3 20041212 (Red Hat 3.4.3-9.EL4) -- 以下 ソース -- #include <stdio.h> #include <stdlib.h> #define SEND4(o, m, l, on_off) o->send_extr_indir(o->_##m##l, on_off) class Define { public: int send_extr_indir(int data1, int data2); int _test(int arg1, int arg2); int test(void); }; int Define::send_extr_indir(int data1, int data2) { printf("data1=%d\n", data1); printf("data2=%d\n", data2); return data1+data2; } int Define::_test(int arg1, int arg2) { return arg1 + arg2; } int Define::test(void) { return SEND4(this, test, (1,2), 5 ); } int main(void) { int result = 0; Define object; result = object.test(); printf("result=%d\n", result); return 0; }

  • n個の要素を持つ配列xをシェルソートで昇順に整列

    穴埋め問題ですが、for文の j -= k の考えで立ち止まります。 #include <stdio.h> #define swap(X, Y) 【 1 】 ← X ^= Y, Y ^= X, X ^= Y void shell(int x[ ], int n); void main() {     int x[12] = {23, 67, 54, 82, 13, 28, 55, 61, 50, 32, 29, 44};     int n = 12, i ;     printf("配列(整列前)x => ");     for( i = 0; i < n - 1; i++ )         printf("%d, ",x[ i ]);     printf("%d\n",x[ i ]);       shell(x, n);     printf("配列(整列後)x => ");     for( i = 0; i < n - 1; i++ )         printf("%d, ",x[ i ]);     printf("%d\n",x[ i ]); } void shell(int x[ ], int n) {     int i, j, k = n ;     while( 【 2 】 ){ ← k > 0         【 3 】 ← k /= 2;         for( i = 0; 【 4 】; i++)             for( j = i; 【 5 】; j -= k)               swap(x[j], x[j + k]);     } } 【 1 】【 2 】は自信があるのですが【 3 】はあまり自信がないです。 【 4 】と【 5 】はどうすれば出来ますか教えてください。お願いします。

  • ハノイの塔 関数内の進み方

    ■プログラムは後半に書いてます。よろしくお願いします。      no x y ――――――― 10行目 3 1 3 10行目 2 1 2 10行目 1 1 3 printf ■この後の5回(できれば10回)の進み方を教え貰えると嬉しいです。 ■わからない理由 printfのとき、(no, x, y) = (1, 1, 3)でno = 1。 そのため13行目は行われない。 しかし、returnもbreakもないためまた6行目に戻るのでしょうか?(答えを見ると6行目に行きそうです。) (no, x, y) はどのような値で関数が始まるのでしょうか? 9行目があるのにno=2or3で表示される理由がわからないです。 01|#include <stdio.h> 02|#include <conio.h> 03| 04|#define N 3 05| 06|void move(int no,int x,int y) 07|{ 08| static int i=1; 09| if(no>1) 10| move(no-1,x,6-x-y); 11| printf("%dを%d軸から%d軸へ移動 : %d\n",no,x,y,i++); 12| if(no>1) 13| move(no-1,6-x-y,y); 14|} 15| 16|int main(void) 17|{ 18| move(N,1,3); 19| 20| _getch(); 21| return(0); 22|}

専門家に質問してみよう