- 締切済み
C言語をお願いします
普通には出来たのですが、配列や関数の使い方がよく分かりません。 助けてください。よろしくお願いします。 問 1~30の整数の範囲で、3辺a, b, c(cを斜辺)の三角形のうち、直角三角形が成立する場合を見つけて配列に入れる。その後、配列をもとにプログラムを作成。 ※a, b, c辺を見つけて配列に入れる機能は関数にすること。 ※a <= b、b <= cを仮定。 #include<stdio.h> int myfunc(int x, int y, int z); int main(){ int a, b, c; for(a=1; a<=30; a++){ for(b=a; b<=30; b++){ for(c=b; c<=30; c++){ if(a*a + b*b == c*c){ printf("%d,%d,%d",a,b,c); puts(" "); } } } } return 0; } 実行例 3,4,5 5,12,13 ・ ・ よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
#4 です。 「追い詰められて」さんは、全部お任せを通すとはしぶといですね。 次に示すのはテストプログラムですが、渡し方と受け取り方でアドレスはどのように変わるかを示したものです。関数がわからない方はこのようにアドレスの動きを確認することが肝要です。 /* Test program of argument */ #include <stdio.h> void myfunc(int array_a[], int array_b[], int array_c[]); int main(void) { int array_a[20],array_b[20],array_c[20]; printf("a=%#x &b[0]=%#x *c=%#x\n", array_a, &array_b[0], array_c); printf(" vvvv\n"); myfunc(array_a,&array_b[0],array_c); return 0; } void myfunc(int array_a[], int array_b[], int *array_c) { printf("a=%#x &b[0]=%#x *c=%#x\n", array_a, &array_b[0], array_c); //return 文がないから void型(何も返さない)の関数 } ↑のテストプログラムから、今回の「配列と関数の課題」は回答 #4 が発展して↓のようになります。 なお、設問は直角三角形ですからピタゴラスの定理が採用されます。 http://ja.wikipedia.org/wiki/%E3%83%94%E3%82%BF%E3%82%B4%E3%83%A9%E3%82%B9%E3%81%AE%E5%AE%9A%E7%90%86 #include <stdio.h> #define MAX 30 //プロトタイプ宣言 int myfunc(int array_a[], int array_b[], int array_c[]); int main(void) { int array_a[20],array_b[20],array_c[20]; int count,i; //ピタゴラスの定理成立の確認 count = myfunc(array_a, array_b, array_c); //配列を元に出力プログラムを作成 for(i=0; i<count; i++){ printf("%d: %d,%d,%d\n",i+1,array_a[i],array_b[i],array_c[i]); } return 0; } int myfunc(int array_a[], int array_b[], int array_c[]) { int a,b,c,count; count=0; for(a=1; a<=MAX; a++){ for(b=a; b<=MAX; b++){ for(c=b; c<=MAX; c++){ if(a*a + b*b == c*c){ //ピタゴラスの定理が成立したら各配列に値を代入する array_a[count]=a; array_b[count]=b; array_c[count]=c; count++; } } } } return count; } ----- 実行結果 ----- 1: 3,4,5 2: 5,12,13 3: 6,8,10 4: 7,24,25 5: 8,15,17 6: 9,12,15 7: 10,24,26 8: 12,16,20 9: 15,20,25 10: 18,24,30 11: 20,21,29
- 正親町(@Ohgimachi)
- ベストアンサー率43% (110/252)
突っ込みを入れさせてもらうと (1) 問題がおかしい >※a <= b、b <= cを仮定 b=cの場合は直角二等辺三角形になるので、aが長辺になってしまい、矛盾します。 (2) 三角形の成立条件が加味されていない 三角形が成立するためには、a+b>cが成立していなければなりません。 (3) ループの中の演算が無駄 a*aとb*bはループのなかで毎回計算する必要はありません。 また奇数の二乗は奇数に、偶数の二乗は偶数になるため、cが奇数の場合にはa,bは奇数と偶数の組み合わせ、cが偶数であればa,bは偶数と偶数、奇数と奇数の組み合わせになります。 しらみ潰しに探すのならcからループさせる方が効率がよくなります。 ループの実行回数が多すぎますから、整理して少なくしましょう。 例としてこんな感じ int a, b, c; for(c=3;c<=30;c++){//c>bの条件からcは3以上 for(b=c/2+1;b<c;b++){//b>=aの条件からbはcの半分以上の長さが必要 int a1,a2; a1=(c-b); a2=a1*(c+b);//c*c-b*bの計算 a1+=1;//aの最小値、a>c-bは三角形の条件 //aに偶数か奇数をセットして2づつ加算する。 for(a=a2%2?a1+1:a1;a<=b;a+=2){ int aa=a*a; if((a2==aa)){ //一致した場合の処理 }else if(a2<aa) brak; } } }
- 和泉 博(@hiroshi09s)
- ベストアンサー率54% (59/109)
>1~30の整数の範囲で、3辺a, b, c(cを斜辺)の三角形のうち、直角三角形が成立する場合を見つけて配列に入れる。 まず、自分にわかり易い配列名や変数を使い、プログラムを作成する。 #include <stdio.h> #define MAX 30 int main(void) { int array_a[20],array_b[20],array_c[20]; //配列を用意する int a,b,c,count; int i; //その後の出力用 count=0; for(a=1; a<=MAX; a++){ for(b=a; b<=MAX; b++){ for(c=b; c<=MAX; c++){ if(a*a + b*b == c*c){ //printf("%d,%d,%d\n",a,b,c); に代わって配列に入れる array_a[count]=a; array_b[count]=b; array_c[count]=c; count++; //カウントを増やすことを忘れないこと } } } } //>その後、配列をもとにプログラムを作成 for(i=0; i<count; i++){ printf("%d: %d,%d,%d\n",i+1,array_a[i],array_b[i],array_c[i]); { return 0; } >※a, b, c辺を見つけて配列に入れる機能は関数にすること。 ↑のプログラムの countなどの変数や for()文を抜き出して関数を作る。プログラムをそのままコピーするので、必要な部分を「ドラッグする」と考えるのが簡単です。 int myfunc(int array_a[], int array_b[], int array_c[]) { //上記プログラムの一部をそのままコピペ int a,b,c,count; count=0; for(a=1; a<=MAX; a++){ for(b=a; b<=MAX; b++){ for(c=b; c<=MAX; c++){ if(a*a + b*b == c*c){ array_a[count]=a; array_b[count]=b; array_c[count]=c; count++; } } } } //count値を返さないと main()関数は続けて動かないヨ! return count; } これで myfunc()関数ができました。 さて、これを使ってあなた自身でプログラム完成してみてください。
- yama5140
- ベストアンサー率54% (136/250)
>・・配列に入れる。その後、配列をもとにプログラムを作成。 「・・配列をもとに『出力する』プログラムを作成」と勝手に解釈・・。 #include<stdio.h> int myfunc(int x, int y, int z); int main(){ int a, b, c; int i = 0, nn = 0, i90Sankaku[ 30 ][ 3 ] = {{ 0 }}; for(a=1; a<=30; a++){ for(b=a; b<=30; b++){ for(c=b; c<=30; c++){ if( 0 == myfunc( a, b, c ) ) continue; i90Sankaku[ nn ][ 0 ] = a; i90Sankaku[ nn ][ 1 ] = b; i90Sankaku[ nn ][ 2 ] = c; nn++; } } } while( i90Sankaku[ i ][ 0 ] ){ // 配列をもとに出力する printf( " %2d", i90Sankaku[ i ][ 0 ] ); printf( " %2d", i90Sankaku[ i ][ 1 ] ); printf( " %2d", i90Sankaku[ i ][ 2 ] ); puts( "" ); i++; } return 0; } int myfunc( int x, int y, int z ) { if( ( x * x + y * y ) != ( z * z ) ) return( 0 ); return( 1 ); }
- yomyom01
- ベストアンサー率12% (197/1596)
forの三重ループをサブルーチン化して配列に格納する
この問題の狙いは、関数に配列を渡すことができることを教えることでしょうね。 配列への値の代入方法は知っていますよね? 例: int a[30]; a[0]=3; a[1]=5; など 関数には、次のように配列を代入することが可能です。 int a[30],b[30],c[30],L; L=myfunc(a,b,c); このとき、myfuncの宣言は、 int myfunc(int a[],int b[],int c[]); または、 int myfunc(int *a,int *b,int *c); と宣言することになります。(どちらでも大差ありません。) この辺の話は、参考書でポインタと配列について記述してあるところに書かれていると思います。 基本的な話なので、敢えて回答は載せません。以上を踏まえて自分で作ってみてください。
お礼
ありがとうございました。
お礼
ありがとうございました。