• ベストアンサー

プログラミングのエラー修正

抵抗R、コイルL、コンデンサCの値を与え、これらRLC直列回路の複素インピーダンスを共振周波数の1/10~10倍程度の範囲で数値計算し、データの組として出力するプログラムを作成するために、 #include <stdio.h> double resonance(double x,double y) { return(1/2*3.14*(x*y)^(1/2); } int main(void) { double r,l,c; double r_abs,l_abs,c_abs; double R; double f0; printf("put r"); fflush(stdout); scanf("%lf",&r); printf("put l"); fflush(stdout); scanf("%lf",&l); printf("put c"); fflush(stdout); scanf("%lf",&c); if(l==0||c==0){ R=0,X=0; } if(l<0){ r_abs=r; l_abs=-l; c_abs=c; } if(c<0){ r_abs=r; l_abs=l; c_abs=-c; } if(r<0&&c<0){ r_abs=r; l_abs=-l; c_abs=-c; } f0=resonance(l_abs,c_abs); double n[]={f0/10,f0*2/10,f0*3/10,f0*4/10,f0*5/10,f0/10,f0*6/10,f0*7/10,f0*8/10,f0*9/10,f0,f0*2,f0*3,f0*4,f0*5,f0*6,f0*7,f0*8,f0*9,f0*10}; R=r_abs; double X[]=(n[]*2*3.14*l_abs)-1/(l_abs*)*c_abs; printf("周波数%d,Z=%lf+j%lf",n[],R,X[]); return 0; } のようなプログラムを書いたのですが、if(l==0||c==0){ R=0,X=0; } double n[]={f0/10,f0*2/10,f0*3/10,f0*4/10,f0*5/10,f0/10,f0*6/10,f0*7/10,f0*8/10,f0*9/10,f0,f0*2,f0*3,f0*4,f0*5,f0*6,f0*7,f0*8,f0*9,f0*10}; double X[]=(n[]*2*3.14*l_abs)-1/(l_abs*)*c_abs; printf("周波数%d,Z=%lf+j%lf",n[],R,X[]);return(1/2*3.14*(x*y)^(1/2); にエラーが出てしまうのですがなぜだかわからないので、教えていただけませんか?

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

#3です。 新しいのを見たら、いろいろおかしな所に気づきました > double f=(1/2)*3.14*a; ここが0になります。 (1/2)が (intの1)/(intの2) = 0.5の切り捨て=0 となってしまうからです。 double f=(1.0/2.0)*3.14*a; と小数点を付けたり、 double f=((double)1/(double)2)*3.14*a; とキャストしたりして、doubleであることを明記する必要があります。 他の数値もdoubleとしたいところは小数点を付けた方がよいでしょう。 >if(isalpha(r)!=0||isalpha(l)!=0||isalpha(c)!=0){ doubleをisalphaで判定するのは無意味です。むしろ、誤動作の原因となります。 > if(l<0){ (以下略) ここもおかしいです。 おそらく、それぞれの絶対値をいれようとしているのだと思いますが。 例えば、 l=-1. r= 1, c = -1 のときどうなるか if(l<0){ なので l_abs=-l(=1) if(c<0){ なので l_abs=l(=-1) if(r<0&&c<0){ ではないので elseの l_abs=l (=-1) とl_absはlの絶対値になりません 変数一つに一つのifを使う if ( l < 0 ) { l_abs = -l ;} else { l_abs=1;} か、fabs関数を使うかです l_abs = fabs(l); >double n[19]; >double X[19]; Cの配列は、宣言した個数だけの領域が用意されます。添字は0から始まるため、有効な添字は 0~(宣言した個数-1)となります。上の場合は n[0]~n[18], X[0]~X[18]の19個です。 さらに、Cでは、添字が範囲内かどうかのチェックは行いません。n[19]としてもなにくわぬ顔でコンパイルできてしまいます。 しかし、実行時には、関係ない場所を参照したり書き換えたりするので、正常に動作しません。最悪、致命的なエラーとなります。 (むしろ、エラーになった方がわかりやすいくらいで、たまたま動いているように見えてしまう事もあり、やっかいです) 修正方法は2通りです 1)添字を0~18にして、forループも0~18にする 2)宣言を n[20] X[20] のようにし、n[19] X[19]を有効な添字にする。 あと、気になったのが >X[i] = n[i]*2*3.14*l_abs - 1/n[i]*c_abs; ですが1/n[i]*c_abs の c_absって分子側、つまり 1.0/(n[i]*c_abs) だったような気がするんですが(このあたりのLCR回路、ちょっと苦手だったもので...) πの精度も3.14程度でいいのですね?

その他の回答 (3)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

まず確認しますが、これ、Cですか? とりあえず、Cだと仮定してgccでコンパイルしてみましたが、確かに、エラーが出ます。 で、エラーメッセージをちゃんと読んでますか? 例えば、 R=0,X=0; については、Xが定義されてない、とわかりやすいエラーですよ。 return(1/2*3.14*(x*y)^(1/2); →まず、括弧があってません。 ^演算子は Cでは「ビット毎の排他的論理和(XOR)」です。 よく、べき乗の上付き文字を表すのに使用されますが、Cではべき乗演算には使えません。 double X[]=(n[]*2*3.14*l_abs)-1/(l_abs*)*c_abs; →おそらく、すべてのnに対してのXを求めて配列にしようとしているのだと思いますが、Cでは、こんな単純な記述ではでません。 直接書くにしろ、ループで処理するにしろ、添字をちゃんと指定して一つずつ計算する必要があります。 printf("周波数%d,Z=%lf+j%lf",n[],R,X[]); →これも同じです。配列を指定したら、自動で全要素に対して実行してくれる、なんてことはCではやりません。

red_smith
質問者

補足

#include <stdio.h> #include <ctype.h> double resonance(double x,double y) { double a=sqrt(x*y); double f=(1/2)*3.14*a; return f; } int main(void) { double r,l,c; double r_abs,l_abs,c_abs; double R; double f0; int i,p; printf("put r"); fflush(stdout); scanf("%lf",&r); printf("put l"); fflush(stdout); scanf("%lf",&l); printf("put c"); fflush(stdout); scanf("%lf",&c); if(isalpha(r)!=0||isalpha(l)!=0||isalpha(c)!=0){ printf("error"); return 0; } if(l==0||c==0){ printf("error"); return 0; } if(l<0){ r_abs=r; l_abs=-l; c_abs=c; } if(c<0){ r_abs=r; l_abs=l; c_abs=-c; } if(r<0&&c<0){ r_abs=r; l_abs=-l; c_abs=-c; } else{ r_abs=r; l_abs=l; c_abs=c; } f0=resonance(l_abs,c_abs); double n[19]; n[1]=f0/10; n[2]=f0*2/10; n[3]=f0*3/10; n[4]=f0*4/10; n[5]=f0*5/10; n[6]=f0*6/10; n[7]=f0*7/10; n[8]=f0*8/10; n[9]=f0*9/10; n[10]=f0; n[11]=f0*2; n[12]=f0*3; n[13]=f0*4; n[14]=f0*5; n[15]=f0*6; n[16]=f0*7; n[17]=f0*8; n[18]=f0*9; n[19]=f0*10; R=r_abs; double X[19]; for (i = 1; i < 20; i++){ X[i] = n[i]*2*3.14*l_abs - 1/n[i]*c_abs; } for (p = 1; p < 20; p++){ printf("周波数%lf,Z=%lf+j%lf\n",n[p],R,X[p]); } return 0; } のように変更したのですが、 double a=sqrt(x*y); double f=(1/2)*3.14*a; return f; のところなんですが最終的に f=(1/2)*3.14*(x*y)^(1/2);にしたいんですがどうしたらいいですか? 後、プログラミングコンパイル段階には、問題は発生しないのですが、答えの数と答えのX=0000000になるのはなぜでしょうか?

回答No.2

行列を使うプログラムを書くのに配列を使っているんだと思いますが、配列と行列は透過ではありません。配列の要素は一つ一つ参照したり更新したりする必要があり、まとめて参照、更新はできません。 red_smith さんはそれを誤解されていると思います。 例えば、配列を使うには配列の要素数を予め宣言しておき、その宣言量以上使うことは出きません。 なお、配列の宣言は関数の最初のところで行いますので、途中で出しているdouble n[]={f0/10,f0*2/10,f0*3/10,f0*4/10,f0*5/10,f0/10,f0*6/10,f0*7/10,f0*8/10,f0*9/10,f0,f0*2,f0*3,f0*4,f0*5,f0*6,f0*7,f0*8,f0*9,f0*10};はエラーとなります。 また、配列の中身は固定値しか設定できないため、上記のような宣言は出きません。 さらに、配列の中身を更新するにはその要素一つ一つにたいして行う必要があり、全部をいっぺんに更新することは出きません。 これが原因でdouble X[]=(n[]*2*3.14*l_abs)-1/(l_abs*)*c_abs;はエラーとなります。 また、表示も要素一つ一つに対して行わなくてはなりません。 つまり、 double f0; の直後にdouble n[20], X[20], R[20];と宣言する必要があります。 そして、更新に使うためのカウンタとしてint i;などと宣言しておきます。 また、n,X,Rの更新は次のような形で行います。 例えばR=r_abs;とするところは、 for (i = 0; i < 20; i++) R[i] = r_abs; としなくてはいけません。 また、double X[]=(n[]*2*3.14*l_abs)-1/(l_abs*)*c_abs;は for (i = 0; i < 20; i++) X[i] = n[i]*2*3.14*l_abs - 1/l_abs*c_abs;と書かなくてはいけません。 ...l_abs*はl_absの書き間違いだと思いますが。 表示のところも、同様です。 おそらくはC言語を使うよりも、MatlabやMaple Vなど行列を行列として扱えるプログラミング言語を使うほうがやりたいことを素直に表せるような気がします。...C言語で書く必然性があれば別ですが。

red_smith
質問者

お礼

ご丁寧な説明、ありがとうございます。 もう一度しっかり勉強しなおします。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

何をしたときに(コンパイル時?実行時?)、 そんなエラーが出るか(エラーメッセージの内容は?)を 具体的に示してください。

関連するQ&A

  • 二分法のプログラムについて

    下の用なプログラムを作ったのですがどうしても正しい答えを導くことができません。自分でもいろいろ調べてみましたがわかりません。誰かご教授宜しくお願いします。 #include<stdio.h> #include<stdlib.h> #define MAX 10 int n , count; double c[MAX+1]; double a,b,e; void nyuuryoku(void) { int i; printf("nの入力>"); scanf("%d",&n); if(n>MAX){printf("最大次数を超えている");exit(1);} else if(n<0){printf("nが負");exit(2);} else{for(i=0;i<=n;i++){printf("係数の値>");scanf("%lf",&c[i]);} }} double f(double x) {double y; int i; y = c[0]; for(i=1;i<=n;i++){ y=y*x+c[i];} return y; } void hani(void){ printf("aの値>");scanf("%lf",&a); printf("bの値>");scanf("%lf",&b); printf("eの値>");scanf("%lf",&e); if(e<=0){printf("eが0または負"); exit(3);} if(f(a)==0){printf("%f",f(a)); exit(4);} if(f(b)==0){printf("%f",f(b)); exit(5);} if(f(a)*f(b)>0){printf("初期値異常"); exit(6);}} double nibun(void) {double c; if(b>a){ while(b-a>e){ count++; c=(a+b)/2; if(f(c)==0){ return c;} if(f(a)*f(c)<0){b=c;} if(f(b)*f(c)<0){a=c;} } return a;} if(a>b){ while(a-b>e){ count++; c=(a+b)/2; if(f(c)==0){ return c;} if(f(b)*f(c)<0){a=c;} if(f(a)*f(c)<0){b=c;} } return a;} } void syutsuryoku(double x){ printf("x=%lf\n",x); printf("f(x)=%lf\n",f(x)); printf("繰り返し回数=%d\n",count); } int main(void){ double ans; count=0; nyuuryoku(); hani(); ans = nibun(); syutsuryoku(ans); }

  • C++でのプログラミングについてです

    プログラミング初心者です C++で二次方程式の解のプログラムを作成したのですがうまく作動させることができません…どこがおかしいのでしょうか、またどのように変更すればよいでしょうか 発生したエラーは 15行 型voidの値をintのエンティティに割り当てることはできません 34行 宣言が必要です 55行 宣言が必要です 15行 voidが他の型と同時に使われました 34行 '{'を見つけました(関数のヘッダーがないかもしれません). 68行 構文エラー:'}' です よろしくお願いいたします #include<stdlib.h> #include<math.h> void solve(double, double, double); int main(void) { double a, b, c; /*二次方程式の定数*/ double D, x1, x2, r1, r2; int ret; printf("ax^2 + bx + c = 0 の係数 a, b, c を入力してください---> \n"); scanf_s("%lf %lf %lf", &a, &b, &c); printf("2次方程式を解いた結果は次の通りです。\n"); ret = solve(a, b, c, &x1, &x2, &r1, &r2); switch (ret) { case-1: printf("係数がおかしい\n"); break; case 0: printf("解は虚数解で%.2f+%.2fi と%.2f-%.2fi です\n", r1, r2, r1, r2); break; case 1: printf("解は実数解となり、%f です。\n", x1); break; case 2: printf("解は実解解で、%f と %f です。¥n", x1, x2); break; } return 0; } void solve(double a, double b, double c, double x1, double x2, double r1, double r2); { if (a == 0.0) { if (b == 0.0) { return -1; } { x1 = -c / b; return 1; } } else { D = b * b - 4 * a * c; if (D >= 0) { x1 = (-b + sqrt(D)) / (2.0 * a); x2 = (-b - sqrt(D)) / (2.0 * a); return 1; } if (D == 0) { x1 = -b / (2 * a); return 1; } else { r1 = -b / (2 * a); r2 = sqrt(-D) / (2 * a); return 0; } } }

  • Switch文を使ったプログラミング

    switch文を使って1のときは円周、2のときは円の面積、3のときは球の面積を求めるという問題をしています。xが1の時は出力結果は合っているのですが、xが2と3のときはdefaultの結果の"もう一度やり直し"になってしまいます。 どこが間違っているのかわかりません。 rは半径、Lは円周、Sは円の面積、Vは球の体積です。paiはπです。 #include<stdio.h> #include<stdio.h> int main(void){ double L, x, r, S, V, pai=3.14159; printf("半径rを入力:"); scanf("%lf",&r); printf("処理番号(1:円周は 2:円の面積は 3:球の体積は)"); scanf("%lf",&x); switch(x){ case 1: L = 2*pai*r; printf("円周は%0.2lf",L); break; case 2: S = pai*r*r; printf("円の面積は%0.2lf",S); break; case 3: V = 4*pai*r*r*r/3; printf("球の体積は%0.2lf",V); break; default: printf("もう一度やり直し\n"); } return 0; }

  • C言語のプログラミングがうまくいきません!

    先日のプログラムを作り直しました。アドバイスのおかげでエラーは減りましたが、まだ完ぺきではないようです。恐らく、elseのところがいけないと思うのですが、どうしたらいいか分かりません。 ご指摘お願いします。 #include <stdio.h> #include <math.h> void main(void) { double x ,y ,z ,error ,menseki ; double ans; printf("x ?"); scanf("%lf", &x); printf("y ?"); scanf("%lf", &y); printf("z ?"); scanf("%lf", &z); if(x<y+z || y<x+z || z<x+y) { ans=(x+y+z)/2; menseki=sqrt(ans*(ans-x)*(ans-y)*(ans-z)); } if(x==y && y==z && z==x) { printf("正三角形です"); printf("面積は%lfです" , menseki); } else if(x==y || y==z || z==x) { printf("二等辺三角形です"); printf("面積は%lfです" , menseki); } else { printf("三角形です"); printf("面積は%lfです" , menseki); } else { printf("error"); } }

  • 2次方程式の解 Cプログラミング

    C言語でのプログラムの添削をお願いします。 2次方程式の解を求めるものなのですが。 #include<stdio.h> #include<math.h> main(){ double a,b,c,d; double x1=0; double x2=0; scanf("%lf %lf %lf" ,&a,&b,&c); printf("a=%f b=%f c=%f\n" ,a,b,c); d=b*b-4*a*c; if(d>0){ x1=(-b+sqrt(d))/2*a; x2=(-b-sqrt(d))/2*a; printf("x=%f,%f\n" ,x1,x2); }else if(d<0){ x1=-b/2*a; x2=sqrt(-d)/2*a; printf("x=%f+%fi,%f-%fi\n" ,x1,x2,x1,x2); }else{ printf("x=%f\n" ,x1); } return 0; } このとき、 a=-7,b=2,c=-1 を与えると x=7.000000+-17.146428i,7.000000--17.146428i という値が返ってきます。 他にも、虚数解のときに間違った値が返ってきてしまう気がするのですが、いかがでしょうか? 実数解のときは正しいようです。 回答よろしくお願いします。

  • C言語 プログラミングで行詰まりました…

    標準入力(キーボード)からi,jk,nの値を入力し、次の漸化式を計算し、X_0からX_nまで求めるプログラムを作成したいのですが、うまく表示されません。どかがおかしいのかご指摘お願いします。 <漸化式> X_n=(a+b)/X_(n-1) , X_0=c(n=0) ================================================================== #include<stdio.h> float f_X(int a,int b,float c) { float y; y=(a+b)/c; return y; } int main (void) { int number,i,j; float k,l,n,X; printf("i:"); scanf("%d", &i); printf("j:"); scanf("%d", &j); printf("k:"); scanf("%f", &k); printf("n:"); scanf("%f", &n); X=k; printf("X_0= %.6f\n",X); for(number=1;number<=n;number++) { l=f_X(i,j,X); printf("X_%d= %.6f \n",number,l); X=l; } return 0; } ===================================================================

  • 定積分のプログラミングについて

    刻み幅dxを入力し、f(x)=4/(1+x^2)を0~1まで定積分するというプログラムを作ったんですが、なぜか、刻み幅を入力してENTERを押すと、 ずら~~~~~っと無限に結果の文字列が出てきてしまいます。 書いたプログラムを載せるので、間違っている箇所を教えてもらえませんか。お願いします。 #include <stdio.h> #include <math.h> double f(double m); main(){ double x,F,dx; printf("Numerical integration of y=4/(1+x^2).\n"); /*刻み幅の入力*/ scanf("%lf,&dx:"); /*aとbと刻み幅*/ printf("The lowwer bound:0.0\n"); printf("The upper bound:1.0\n"); printf("The meth width:dx\n"); /*関数*/ for(x=0.0;x<1.0;x+=dx) { F=f(x); /*計算結果を出力*/ printf(" f(%lf)= 4/(1+x^2) =%lf\n",x,F); } } double f(double m) { double y; y=4/(1+m*m); return y; }

  • プログラミング 実数 合計

    3つの実数を読み込んで合計を表示するというプログラムなんですが、プログラムをコンパイルして3つの実数を入力してくださいと表示させて実数1に1.5、実数2に0.8、実数3に1.0, 合計は3.3です表示させたいのですが #include <stdio.h> int main(void) { double n1,n2,n3; puts("3つの実数を入力してください。"); printf("実数:"); scanf("%lf", &n1); printf("実数:"); scanf("%lf", &n2); printf("実数:"); scanf("%lf", &n3); printf("合計は%5.lfです。\n",(double)(n1 + n2 + n3)); return (0); } でコンパイルしようとすると1つしか実数を入力する所が出てこなくて 数字を入れると合計は.lfですと出てきて実行できないのですが、上のソースのどこか間違ってる所があったら教えてくれませんか?

  • c言語 プログラミング(初心者)

    解を判定するプログラミングを作成したのですが、a,b,cを0,1,2と入力したときに解に0.00000が出てきて解がおかしくなります。 どなたか詳しい方教えてください。また簡潔にできる点などありましたらご指摘お願いします。 #include <stdio.h> #include <math.h> int main (void) { double a,b,c,d,x1,x2; printf("ax^2+bx+c=0 の係数を入力してください\n"); scanf("%lf %lf %lf",&a,&b,&c ); if(a==0){ if(b==0) { printf("解は存在しません\n"); } else { x1=-c/b; printf("解は %f です\n",x1); } } else { d=b*b-4*a*c; if(d>=0){ x1=(-b+sqrt(d))/(2.0*a); x2=(-b-sqrt(d))/(2.0*a); if(d==0){ printf("解は %f (重解)です\n",x1); } else { printf("解は %f と %f です\n",x1,x2); } } else { printf("実数解は存在しません(虚数解)\n"); } } return 0; }

  • 値の渡し方?(初心者)

    以前質問したプログラムについて、新たに質問です。 メインプログラムと、関数プログラムを組みました。 関数の中では、print文を使うと計算は正しく行われていて、結果が正しいことが分かりました。 でうが、メイン文の出力では、どこにも出てこない変な値が出てきてしまいます。 値の渡し方がおかしいのでしょうか? 誰か、アドバイスをお願いします。 ***以下プログラムです。*** #include <stdio.h> #include <math.h> double gamma(double x) { double c[9],y,a,r,b,s,z; int i; a=1.; r=1.; c[1]=5.771916e-01; c[2]=9.882058e-01; c[3]=8.970569e-01; c[4]=9.182068e-01; c[5]=7.567040e-01; c[6]=4.821993e-01; c[7]=1.935278e-01; c[8]=3.586834e-02; printf("0 %f\n",x); while(1){ if(x>2.){ x=x-1.; a=a*x; printf("1 %f %f\n",x,a); } else if(x<1.){ a=a/x; x=x+1.; printf("2 %f %f\n",x,a); } else{ break; } } x=x-1.; for(i=1;i<9;i++){ b=(double)(i); s=(c[i]*((double)(pow(-1.,b)))*((double)(pow(x,b)))); printf("3 %d %f\n",i,c[i]); r=r+s; } y=a*r; printf("4 %lf\n",y); return y; } main() { double x,y; printf("数字を入力してください。"); scanf("%lf",&x); printf("メインプログラム x= %lf \n",x); y=gamma(x); printf("x= %f y= %f\n",x,y); }