• ベストアンサー

お願いします

int c(int x)    { x = x + 3;     { int t; t = 6;      { int x; x = 6; t = x + t + 12; }    return x + t;    } } 上の関数の変数の名前替えだけが許されるという条件の下で,関数f の働き(すなわち,引数と戻り値の関係)を変えずに,上記の関数定義の4行目 { int x; x = 6; t = x + t + 12; } の(int x)を(int t) に変更して.必要最小限の変数の名前替えを施した関数定義を書け. 私はこのように定義していますので、正しいですか、「関数の変数の名前替えだけが許されるという条件の下で,関数f の働き(すなわち,引数と戻り値の関係)を変えずに」ってあまり理解できてないので、ご教授お願いいたします。 int c(int x)    { x = x + 3;     { int y; y = 6;      { int t; t = 6; y = t + y + 12; }    return x + y;    } } }

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

  • ベストアンサー
  • yama5140
  • ベストアンサー率54% (136/250)
回答No.7

>必要最小限の変数の・・ >名前替えだけが許されるという条件  少なくとも、「変数」は、スコープ内及び関数の引数で、宣言されていないと「エラー」だよね。  (「グローバル」略)   int err( int x ) // エラー   { x = x + 3;   { int x; x = 6;     { int t; t = 6; t = x + t + 12; }     return x + t; この t は、「未定義のシンボル」。   }   }  また、   int w( int x ) // エラーではないが・・   { x = x + 3;   { int t; t = 6;     { int t; x = 6; t = x + t + 12; }     return x + t;   }   }   とすると、return 文直前の波括弧(スコープ)内の、x = 6; は、スコープを出ても有効だが、t = x + t + 12; は★このスコープ内でのみ★有効。  この辺りを考えると、「答え」が出るかと思います。  また、質問主旨とは離れます( t → a )が、下の関数 f() と q() の実行結果をみても何かが判るのでは・・。 ☆少なくとも「エラー」は、コンパイラが教えてくれるから、好きにいじくってみるのがよいかと・・。 >私はこのように定義していますので、正しいですか、 ☆「関数 f の働きを変えず」は、実行すれば確認できます。   当然、「必要最小限の変数の名前替え」かどうかは判りません・・。 #include <stdio.h> int f( int x ) { x = x + 3; { int t; t = 6;  { int x; x = 6; t = x + t + 12; }  return x + t; } } int w( int x ) // エラーではないが・・ { x = x + 3; { int t; t = 6;  { int t; x = 6; t = x + t + 12; }  return x + t; } } int q( int x ) { x = x + 3; { int t; t = 6;  { int a; a = 6; t = a + t + 12; }  return x + t; } } int c( int x ) // 質問者様 { x = x + 3; { int y; y = 6;  { int t; t = 6; y = t + y + 12; }  return x + y; } } int No6( int x ) // No.6 様 { x = x + 3; { int t; t = 6;  { int t; t = 6; t = t + t + 12; }  return x + t; } } int main() {  for( int i = -5; i < 6; i++ ){   printf( "%2d f %2d, w %2d, q %2d, c %2d, No6 %2d\n", i, f( i ), w( i ), q( i ), c( i ), No6( i ) );  }  return( 0 ); } 注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

inouegaku
質問者

お礼

yama5140さん、本当にお礼を申し上げます。たいへん助かりました、いい参考になります。どうもありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (8)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.9

や, その No6 は #6 で示唆されるものではないと思いますよ>#7. 少なくとも私の思い付いたものとは違います. そもそも元の c と機能が違いますよね. 最後が....

inouegaku
質問者

お礼

どうもありがとうございました、いい参考になります。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.8

おー, 確かに 3個だ>#6. そうする手があったかぁ. もっと強い条件で考えてた.... ああ, いずれにしても「変数の名前替え」という言葉の意味に依存します. そういえば誰も書いてないけど, 「関数 f の働きを変えずに」ってのは, 「引数 x に対して返される値が変化しないように」ってことです. 元の関数 c で (あれ?) 引数 x に対して返り値がどうなるか分かりますか? って, こっちの線から行くと最初に考えてた「1個少ない方法」にいっちゃうんだよなぁ.... う~ん, なかなか誘導も難しい....

inouegaku
質問者

お礼

どうもありがとうございました、いい参考になります。

全文を見る
すると、全ての回答が全文表示されます。
  • Yanch
  • ベストアンサー率50% (114/225)
回答No.6

>#5さんへ > 「名前替え」の意味が微妙. > それが最小という解釈も可能だし, 「もっと少ない方法がある」という解釈も可能. > (解釈次第で) 1個少ない方法はありうるけど, もっと減らす方法はありますか?>#1 1:int c(int x) 2:   { x = x + 3; 3:    { int t; t = 6; 4:     { int x; x = 6; t = x + t + 12; } 5:   return x + t; 6:   } 7:} として、 問題にある、 ●1箇所目 4行目の「int x」を「int t」に変更。問題の通り。 を含めて、3文字、変数名を変更すれば、良いと思います。

inouegaku
質問者

お礼

どうもありがとうございました、いい参考になります。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

「名前替え」の意味が微妙. それが最小という解釈も可能だし, 「もっと少ない方法がある」という解釈も可能. (解釈次第で) 1個少ない方法はありうるけど, もっと減らす方法はありますか?>#1

inouegaku
質問者

お礼

どうもありがとうございました、いい参考になります。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

>{ int x; x = 6; t = x + t + 12; } >の(int x)を(int t) に変更して とのことでありますが、引用した上の行には (int x) という箇所がありません。よって、 (int t) に変更することができません。 出題者に確認することをおすすめします。 # 何だか変な問題 :)

inouegaku
質問者

補足

asuncionさん、{ int x; x = 6; t = x + t + 12; }中のint x を int t に変更すること。

全文を見る
すると、全ての回答が全文表示されます。
  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.3

*4行目*のint xをint tに変えろってコトだから、正しいと思うけど。。 ()は関係ないと思われます。 ちゃんと4行目の元のtをyに変えてるしね。

inouegaku
質問者

補足

そうです、tをyに変更する。

全文を見る
すると、全ての回答が全文表示されます。
  • 1108435
  • ベストアンサー率43% (94/217)
回答No.2

(int x)ってどこのことだと思う? (int x)が明記されているのは1箇所だよね。違うところ見てない?

inouegaku
質問者

補足

申し訳ございません、確か私は書き間違いました。上の関数の変数の名前替えだけが許されるという条件の下で,関数f の働き(すなわち,引数と戻り値の関係)を変えずに,上記の関数定義の4行目 { int x; x = 6; t = x + t + 12; } のint x を int t に変更して.必要最小限の変数の名前替えを施した関数定義を書け.

全文を見る
すると、全ての回答が全文表示されます。
  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

「必要最小限」というと、もっと「変数の名前替え」の少ない解があるみたいですね。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • c言語の関数定義について

    次の関数定義を考える. int f(int x) {if (x > 0) {return x * f(x-1);} else {return 1;} } この関数f と働き(すなわち,引数と戻り値の関係)が同じで再帰呼出(recursive call) を使わない関数g をC で定義せよ.ただし,オーバーフロー(overflow) については考慮しなくてよい. ”この関数f と働き(すなわち,引数と戻り値の関係)が同じで再帰呼出(recursive call) を使わない関数g をC で定義せよ”って理解できません、どのように定義したいいか、ご教授お願いします。

  • 関数の戻り値に関数のアドレスを返すできませんか?

    戻り値に関数のアドレスを与える方法が良く分かりません. ひとまず,以下のように動くプログラムを作りたいと思っています.  f2(1,2)(1); //このように引数の()を二種類に分けたいのですが 無理でしょうか?? プログラムは下のように作って実験しているのですが良く分かりません・・ どなたか分かる方居たら教えてください. int f1(int x , int y){ return 0; } ????? int ff(int x){ return f; };

  • こんな条件を満たす乱数生成関数教えてください

    1.任意の周期を指定できる 2.種を指定できる(直前の生成値を引数にとる) 3.逆関数が定義できる 4.生成された乱数 x、y の距離を(定数時間で)求められる   つまり y = f(x) ならxとyの距離は1、 y = f( f( f(x) ) ) なら距離3、というように 乱数としての質(均等に分布していること)はあまり重視しません。 ビット幅は32~128bitくらい(任意ならベスト)であればいいと思っています。 以下のような感じにしたいです。  int rand(x, p);   // 戻り値 y = f(x)、pは周期、xは直前の乱数値  int inv(y, p);   // 戻り値 x = f^-1(y)  int distance(x, y) // y = f(f(x)) のとき、distance(x, y) = 2 で distance(y, x) = -2 一応以下の関数が条件1~4を満たすのですが、残念ながら乱数としての性質が皆無なので使えないです。  int rand(x, p) { return (x+1) % p; }  int inv(y, p) { return y ? y - 1 : p-1; }  int distance(x, y) { return y - x; } よろしくご教授お願いします。

  • C言語(引数)

    はじめまして。 C言語を習い始めたものです。 関数を定義するとき、よく耳にする、仮引数や実引数があると思います。 仮引数は関数の定義内で値をうけとる変数のことであり 実引数は関数を呼び出す際に渡す値を実引数というらしいのですが どこからどこまでを仮引数と呼ぶのかわかりません。 例えば、 fの関数の定義内で ↓があるとします。 (関数にする意味はないのですが、確認のためあしからず・・・) double f(double x) {     x=5;     return(x); } この場合、仮引数とよばれるものは double f(double x)の xが仮引数であって x=5;のxは仮引数と呼ばないのでしょうか?? もしそうならば void f(double x) { printf("%f",x); } のprintf("%f",x);内のxは仮引数とよぶのでしょうか? 質問の内容が意味不明かもしれませんが よろしくお願いします。

  • カリー化について教えてください。

    初心者です。現在、カリー化について勉強中で、以下のサンプルコードを解読中なのですが、いまいち理解できません。以下を中心に、どなたか解説していただけるとうれしいのですが。 1.curry(f,x)の第一引数fは、関数で、第二引数xは変数と理解してよいのでしょうか? 2.カリー化により、最終的に返される値f(x,y)というのは、curry関数が呼び出された際の第一引数の関数f()に、curr関数の第二引数と、function式を用いて直接宣言されたyを渡した結果が返されるということでしょうか? 3.仮に、curry(add,1)と呼び出した場合には、yにはどのような値が入るのでしょうか? 4.その他、カリー化を学ぶ上で重要なことがありましたら教えてください。 function curry(f, x) { return function(y) { return f(x, y); } }

  • 二次元配列の引数渡し

    二次元配列を関数の引数として渡し、 その配列を戻り値として呼び出し元の変数に返したいです。 具体的にはルンゲクッタ法で微分する関数の引数を行列で扱いたいです。 for (i=0;i<N;i++){ for (j=0;j<N;j++){ y[i][j]=rand(); } }   K1=h*ff(t,y); K2=h*ff(t+h/2,y+K1/2); K3=h*ff(t+h/2,y+K2/2); K4=h*ff(t+h,y+K3); Ka=(K1+2*K2+2*K3+K4)/6; double ff(int t,double y[][]){ ここで return y[][]; のような形で二次元配列を戻り値として変数に返したいのです。 } C言語初心者なのでいまいちよくわかりません、 宜しくお願いいたします。

  • 関数の引数と実引数の取り扱いについて

    C言語初心者です. 関数の引数と実引数の取り扱いについて,教えていただきたいことがあります. 例えば,2変数の和を求める関数を考えると,以下のようになると思います. #include <stdio.h> double sum(double x, double y); int main(void) { double a, b, wa; a=2.0; b=3.0; wa=sum(a,b); return 0; } double sum(double x, double y) { double total; total=x+y; return total; } このとき,mainプログラムでは,a,bふたつの変数を定義しておいて,関数sumに入れて計算させているわけですが,mainプログラムで変数x,yを定義しておいて,以下のようなプログラムにするのはありでしょうか? 参考書などをみると,前者のように取り扱っているようなのですが,試しに後者で実行させてみても同じ結果となりました. #include <stdio.h> double sum(double x, double y); int main(void) { double a, b, wa; a=2.0; b=3.0; wa=sum(a,b); return 0; } double sum(double x, double y) { double total; total=x+y; return total; }

  • 合計値を求める関数

    #include<iostream> using namespace std; //sum関数の定義 int sum(int x, int y) { return x + y;  } int main() { int num1, num2, ans; cout << "1番目の整数を入力して下さい。\n"; cin >> num1; cout << "2番目の整数値を入力して下さい。\n"; cin >> num2; ans = sum(num1, num2); cout << "合計は" << ans << "です。\n"; return 0; }  ここのreturn x+y;の所の合計値を戻り値として返す処理の仕組みを解りやすく教えて欲しいです、戻り値はちょっと解りづらいです、よろしくお願いします。

  • C言語での関数形式マクロの使い方

    前の質問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の関数頭部に変換することは出来ませんか? (関数形式マクロでこのような空白の入れ方をしてよいのでしょうか。)

  • C言語で戻り値を使った正方形の面積と直方体の体積の表示について分からず

    C言語で戻り値を使った正方形の面積と直方体の体積の表示について分からずに困っています。 C言語ラストの問題が一番難しくて、全然分からずに困っています。 以下の点に留意して、一辺の長さを入力すると、正方形の面積と直方体の体積を計算するプログラムを作成する。main内 1)整数型の変数length、men、taiを宣言する。 2)実行例と同様の表示になるように、“一辺の長さを入力してください。”を表示し、入力された値を、変数lengthに読み込む。 3)作成する関数名は、titleとし、lengthを引数とし、関数titleを使う。 4)正方形の面積を計算する関数の関数名は、squareとし、lengthを引数とし、戻り値をmen に代入する。 5)直方体の体積を計算する関数の関数名は、qubeとし、lengthを引数とし、戻り値をtai に代入する。 6)“一辺○○の正方形の面積は ○○です。”と表示する。 7)“一辺○○の直方体の体積は ○○です。”と表示する。 関数title内 1)引数を変数名xとする。 2)下記の実行例の様になるように、表示を行う。 関数square内 1)引数を変数名xとする。 2)整数型の変数valを宣言する。 3)正方形の面積を計算し、valに代入する。 4)valの内容が戻り値となるようにする。 関数qube内 1)引数を変数名xとする。 2)整数型の変数valを宣言する。 3)直方体の体積を計算し、valに代入する。 4)valの内容が戻り値となるようにする。 という問題です。 考えて作ってみたのが下のですが、間違いだらけでどうしようもありません。 #include <stdio.h> void main(void) { int length,men,tai; printf("一辺の長さを入力してください。\n"); scanf("%d",&length); men=square(length); tai=qube(length); printf("***********************************\n"); printf("* 一辺%d *,&lenght); printf("*正方形の面積*") printf("*直方体の体積*") printf("*を計算します。*") printf("*************************\n"); } int square(x) { int val; val=x*x; return val; } int qube(y) { int val; val=x*x*x return val; } どなたかよかったら教えてください。 よろしくお願いします。