• 締切済み

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 ・ ・ よろしくお願いします。

noname#128756
noname#128756

みんなの回答

回答No.6

#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

回答No.5

突っ込みを入れさせてもらうと (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; } } }

回答No.4

>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)
回答No.3

>・・配列に入れる。その後、配列をもとにプログラムを作成。  「・・配列をもとに『出力する』プログラムを作成」と勝手に解釈・・。 #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)
回答No.2

forの三重ループをサブルーチン化して配列に格納する

noname#128756
質問者

お礼

ありがとうございました。

noname#196225
noname#196225
回答No.1

この問題の狙いは、関数に配列を渡すことができることを教えることでしょうね。 配列への値の代入方法は知っていますよね? 例: 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); と宣言することになります。(どちらでも大差ありません。) この辺の話は、参考書でポインタと配列について記述してあるところに書かれていると思います。 基本的な話なので、敢えて回答は載せません。以上を踏まえて自分で作ってみてください。

noname#128756
質問者

お礼

ありがとうございました。

関連するQ&A

  • C言語 関数の作り方

    1~30の数字を使い、直角三角形が成り立つ組み合わせを見つけよ。(a<=b<=c) ただし、a,b,c辺を見つけて配列に入れる機能は関数にすること。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー #include <stdio.h> int main(void) {    int a,b,c,i=0,ct=0;    int ahen[20];    int bhen[20];    int chen[20];    for(a=1;a<31;a++)    {     for(b=1;b<31;b++)     {      for(c=1;c<31;c++)      {       if(a*a+b*b==c*c && a<=b && b<=c)       {         ahen[i]=a;         bhen[i]=b;         chen[i]=c;         i=i+1;         ct++;       }      }     }    }    for(i=0;i<ct;i++)    {     printf("%d %d %d\n",ahen[i],bhen[i],chen[i]);    }    return 0; } 実行例: 3 4 5 5 12 13 6 8 10 7 24 25 8 15 17 9 12 15 10 24 26 12 16 20 15 20 25 18 24 30 20 21 29 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー とりあえず、関数を使わない上記のプログラムを作って見ました。 ここから関数を使ったものに変更したいのですが、配列が絡むとさっぱり分かりません。 printfで表示する箇所以外を全て関数にするのだと思いますが、どなたかご教示願います。

  • C言語課題!C言語初心者です。お願いします。

    課題内容 要素数10の(0~9の順)配列Aの値を2倍して配列Bに格納して  その後配列Aの値を配列Bに、配列Bの逆順を配列Aに格納し  入れ替える前と入れ替えた後の配列A,Bの値を表示するプログラム 書いてみたプログラム #include <stdio.h> int main(void) { int i; int va[10] = {0,1,2,3,4,5,6,7,8,9}; /* 初期化 */ int vb[10]; puts("入れ替え前"); puts("-----------"); for(i=0 , i<10 , i++){ printf("va[%d] = %d\n" , i , va[i]); /* 入れ替え前の配列A */ } for(i=0 , i<10 , i++){ vb[10] = 2*va[10]; } for(i=0 , i<10 , i++){ printf("vb[%d] = %d\n" , i ,vb[i]); /* 入れ替え前の配列B */ } puts("入れ替え後"); puts("-----------"); for(i=0 , i<10 , i++){ vb[10] = va[10]; } for(i=0 , i<10 , i++){ printf("vb[%d] = %d\n" , i ,vb[i]); /* 入れ替え後の配列B */ } for(i = 0 , i < 5 , i++){ /* 配列Bの逆順を配列Aに格納 */ int temp = va[i]; va[i] = vb[4-i]; vb[4-i] = temp; } for(i=0 , i<10 , i++){ printf("va[%d] = %d\n" , i ,va[i]); /* 入れ替え後の配列A */ } return(0); } コンパイルできません。 教えてください。お願いします。

  • C言語のint型の配列が分かりません

    #include<stdio.h> int main(void) { int str[ ]={0,1,2} printf("%s\n", str); return 0; } というプログラムをC言語でつくってみましたが動きません.(012と表示されて欲しかったのですが) int str[ ]={1,2,3}の部分をchar str[ ]={'0','1','2'}とすれば動きます. そこで質問なのですが, printf("~%s~", (配列名));  はchar型の配列にしか適応できないのですか? ※追記 puts関数の定義は int puts (const char *str); であるそうなので char型の仮引数にはchar型のアドレスを渡さなければいけません. ではprintf関数の定義は一体どんなものなのですか?

  • c言語

    length個のint型の要素を持つ配列A[], B[], C[]を受け取り、 A,Bの各々の各要素毎にその和(A+B)を計算して、その答えをCに代入して終了する関数 void add(int a[], int b[], int c[], int length)を定義しなさい。(以下のソースコードの空白を埋めなさい) #include<stdio.h> void diff(int A[], int B[], int C[], int length); int main(){ int a[3]={1,2,3}; int b[3]={4,5,6}; int ans[3]; diff(a, b, ans, 3); printf("answer = %d %d %d \n", ans[0], ans[1], ans[2]); } void add(int A[], int B[], int C[], int length){ } よろしくお願いします。

  • c言語で分からないところがあるので教えてください。

    http://www9.plala.or.jp/sgwr-t/c/Q/ens06-61.html の問題がわかりません。 回答の #include <stdio.h> int main( void ) { int kekka[51]; int a, b, i; int amari; printf( "整数値を2つ入力してください " ); scanf( "%d%d", &a, &b ); if( b == 0 ){ printf( "処理終了\n" ); return 0; } printf( "%d / %d = ", a, b ); kekka[0] = a/b; for ( i = 1; i < 51;i++ ) { amari = a%b; if ( amari == 0 ) break; a = amari * 10; kekka[i] = a/b; } printf( "%d.", kekka[0] ); ここまでの部分はわかったのですが、 下の for ( a = 1; a < i; a++ ) { printf( "%d", kekka[a] ); } の部分がわかりません。 この部分は何を表わしているのか 教えてください。

  • C言語の簡単な質問です。

    #include "stdio.h" int tasizan(int a,int b){ int c; c=a+b; return c; } int main(void){ int a,b,c; a=1; b=1; c=tasizan(a,b); printf("%d+%d=%d",a,b,c); return 0; } と、あるとします。この文を読み込む順番を教えてください。  文の左に行番号みたいに順番を書き込んでください。   例 (例が間違ってたらすみません) 1 #include "stdio.h" 2 int main(void){ 3 int a,b,c; 4 a=1; 5 b=2; 6 c=a+b; 7 printf("%d+%d=%d",a,b,c); 8 return 0; }

  • 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); }

  • c言語について

    #include <stdio.h> MakeData(int *a,int n){ int i,b[5]={5,1,4,7,2}; for(i=0;i<5;i++){a[i]=b[i];} } BubbleSort(int n,int *a){ ここに流れ図に沿ったプログラムを作る } main(){ int i,n,a[100]; n=5; MakeData(a,n); for(i=0;i<n;i++){printf("%4d ",a[i]);}printf("¥n"); printf("並べ替え後¥n"); BubbleSort(n,a); for(i=0;i<n;i++){printf("%4d ",a[i]);}printf("¥n"); } この課題が分かりません。 もし詳しい方がいらっしゃいましたら教えて頂けると助かります。

  • C言語について

    #include <stdio.h> int main(void) { printf("123456\tABC DEFGHIJK\n"); printf("2006/4/14\n"); printf("programing\n"); } のprintfをすべてputsに書き換えてコンパイル・実行すると、 #include <stdio.h> int main(void) { puts("123456\tABC DEFGHIJK\n"); puts("2006/4/14\n"); puts("programing\n"); } になると思うんですけど、そのputsを用いて上のprintfを用いたプログラムと同じ出力を得るにはどのようなプログラムに変えればいいのでしょうか?

  • C言語で直角三角形の斜辺を求めるプログラムについて

    「二辺の長さが与えられているとき、斜辺の長さを求めよ」という問題です。 #include <stdio.h> #include <math.h> #define a 3 #define b 4 int main (void) { double c=0; c=sqrt(a*a+b*b); printf("%f",c); return 0; } visual2010c++で作ったんですが、sqrtに下線がついて、コンパイルエラーしちゃいます。 すんごい初歩的なことなんだと思いますが、どこなのか気づけません。 どなたかよろしくお願いします。