• ベストアンサー

「関数ポインタとして評価されない式」?(sin波)

知っている(ある程度のプログラミング知識がある)方にはばかばかしい内容かもしれませんが・・・。 sin波とcos波を描くものをC++でプログラミングしている途中です。 いざ実行!と思ってコンパイルすると、「関数ポインタとして評価されない式を使って、関数を呼び出そうとしました。」と出たのですが、何が原因かわかりません。 プログラム内容↓ #include <stdio.h> #include <math.h> #define PAI 3.14 (中略・ペン設定など) double j=0.0, sinwave[400]; int x0=50, y0=50, i=0; while(i<400){   for(j=0.0; j<=PAI; j=j+0.1){ sinwave[i]=sin(j); ●ここが原因らしい   }   i++; } (後略・ペンdeleteなど) math.hもあるし、特に変なところはないと思います。 また、そのあとにMoveTo,LineToでsin波を描きたいのですが、 for文で繰り返し MoveTo(x0+sin[i],?) LineTo(x0+sin[i+1],?) の、はてなの部分に何を入れればよいかわかりません。(x0:勝手にきめた原点)x0+sin[i]も、これで良いのか「?」です・・・。 お願いします。

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

  • ベストアンサー
  • betagamma
  • ベストアンサー率34% (195/558)
回答No.2

色々間違っていると思います。 double j=0.0, sinwave[400]; は、たしか、double型のj=0.0と、int型の配列sinwave[400]を定義していることになってしまったと記憶しています。理由は、sinwaveの型が省略されている=省略されたときはint型、ということで、sinwaveはintの配列になるのでは?と。こういうことがないように、 double j=0.0; double sinwave[400]; とちゃんとわけて書くようにしています。 int x0=50, y0=50, i=0; while(i<400){   for(j=0.0; j<=PAI; j=j+0.1){ sinwave[i]=sin(j); ●ここが原因らしい   }   i++; } これは、とても無意味なことをやっているのがわかりますか?i番目について見てみると、 sinwave[i]=sin(0.0) sinwave[i]=sin(0.1) ... sinwave[i]=sin(PAI) という文を実行したのと同じことです。sinwave[i]には、PAIしか入りませんよね?つまり、iの値がいくつでも、sinwave[i]=PAIになってしまいます。正しくは、 int x0=50;int y0=50;int i=0; for(i=0;i<400;i++){ sinwave[i]=sin(PAI/400*((double)i)); } のようになります。sinwave[i]=sin(PAI/400*i)という関係ですね。で、iはint型なので、double型に直してやらないと、()内が整数値しか取らないとかそういう変なことになるので、先にキャストして、double型に直してやっています。 MoveTo(x0+sin[i],?) LineTo(x0+sin[i+1],?) まず、x座標の部分から間違っています。sinは、xの値をもらって、yの値を返す関数ですよね?ということは、sinの式がx座標の式に出てくることはありません。 正しくは、おそらく、 for(i=0;i<399;i++){ MoveTo(x0+i,sin[i]);LineTo(x0+i+1,sin[i+1]); } なのでは?と思います。 後、PAIは、英語では、PIとなりますので、PIとしましょう。

kazutta22
質問者

お礼

回答ありがとうございました! いろいろ指摘するとこありすぎですね(--;) 正しいやり方を教えてくださって大変参考になりました。

その他の回答 (1)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.1

>いざ実行!と思ってコンパイルすると、「関数ポインタとして評価されない式を使って、関数を呼び出そうとしました。」と出たのですが、何が原因かわかりません。 >MoveTo(x0+sin[i],?) LineTo(x0+sin[i+1],?) sinという名前の変数がいたりしませんか? >MoveTo(x0+sin[i],?) LineTo(x0+sin[i+1],?) >の、はてなの部分に何を入れればよいかわかりません。 >(x0:勝手にきめた原点)x0+sin[i]も、これで良いのか「?」です・・・。 ?には、 >  for(j=0.0; j<=PAI; j=j+0.1){ ということなんで、0.1ラジアンあたり、何単位ずらして描画していくかですね。 1単位ずつずらしていくんでしたら、 MoveTo(x0+sin[i],i) LineTo(x0+sin[i+1],i) こんな感じに。 で、 >(x0:勝手にきめた原点)x0+sin[i]も、これで良いのか 原点はこれでかまいません。 Windowsの標準ではクライアント領域の左上が原点になり、x軸は下方向、y軸は右方向に進んでいきます。 通常のグラフとは上下逆になる点に注意してください。 で、MoveTo等ですが、intなんで座標は整数ですね。 MoveTo(x0+sin[i],i) LineTo(x0+sin[i+1],i) で、x座標の値をsin関数の戻り値そのまま座標として使おうとすると、-1、0、1にしかならないんで曲線になりません(^^;; 適当に大きな数字をかけてあげる必要があります。 なお、座標系ですが、ここのマップ系のメソッドを使うことで向きや1単位あたりのサイズを変更することが出来ます。 http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_mfc_cdc_class_members.asp

kazutta22
質問者

お礼

回答ありがとうございました! >x座標の値をsin関数の戻り値そのまま座標として使おうとすると、-1、0、1にしかならないんで曲線になりません そうでした...こういうところでミスして後々悩むんですよ(汗)

関連するQ&A

  • プログラミングの課題で困ってます。

    正弦関数x=sintのグラフを■で描きなさい(31行程度で)。数値xに対する■の数はウインド各行に表示される しきれる範囲内で任意に定めてよい。 という課題が出ました。よくわからなくて困っています。 下記に書いてるプログラミングを参考に答えを教えていただきたいと思い、質問させていただきました。よろしくお願いします。 また、下記を参考にしなくてもよいです。 プログラミングはvisual C++ 2008を使ってます。 #include "stdafx.h" #include<stdio.h> #include<math.h> int _tmain(int argc, _TCHAR* argv[]) { double x[100]; int i , j; for(i=0; i<31; i++){ x[i]=sin(0.1*i); } // for(j=0; j<31; j++){ // printf("%lf\n",y[j]); // } for(i=0; i<31; i++){ for(j=0; j<x[i]*20; j++){ printf("■"); } printf("\n"); } return 0; }

  • ポインタ、関数、アドレス・・・

    はじめまして。 今微分方程式を解かせるプログラムを作る上で、関数に配列を渡したいと考えています。(多変数微分方程式なので) そのため、ポインタを学び、何となくそれについて分かってきたつもりなんですが、いざ試しのプログラムで、コンピュータがちゃんと値を返してくれるかを試しているのですが、どーもうまく値を返してくれません。。。 下に僕が作ったプログラムを載せますので、問題点を指摘してもらえたらうれしいです。 このプログラムで、僕として返してもらいたい値は1.1111です。 よろしくお願いします /******ソースプログラム******/ #include<stdio.h> #include<math.h> double f(int *x); void main() { double x[5]; x[0] = 0.0; x[1] = 1.0; x[2] = 2.0; x[3] = 3.0; x[4] = 4.0; printf("%f \n", f(x)); (←ここらへんがおかしいと言われます。。。) } double f(int *x) { int i; double z=0.0; for(i=0 ; i<=4 ; i++) { z += pow(0.1,*(x+i)); } return(z); }

  • 初歩的なことかもしれないのですが

    最近Cの勉強を始めました。 [visual C++ 2008]を使用しています。 文字列の勉強をしていて参考書の例題を打ちました。 下のが打ち込んだプログラムの一部です。 #include<math.h> #include<stdio.h> #include<string.h> void wait(int tm) {  int i, j;  for(i = 1; i < tm; i++)  for(j = 1; j < tm; j++){   double x = sin(i)*cos(j);  } } ビルドを行った際に error C2668: 'sin' : オーバーロード関数の呼び出しを解決することができません。(新機能 ; ヘルプを参照) error C2668: 'cos' : オーバーロード関数の呼び出しを解決することができません。(新機能 ; ヘルプを参照) 例題と何度も見比べたのですが、写し間違いはなく何度打ちなおしても同様のエラーが出てしまいます。 解決法を教えていただけないでしょうか。

  • 三角関数

    #include<math.h> を宣言していますが三角関数(sin(),cos(),tan())が使えません。これはどうしてでしょうか?

  • 漸化式のプログラム

    n=100としてn+1個の点(Xj,Yj) (j=1,2,3・・n)はどのようなグラフになるか?ただし、h=1/n, Xj=jh, Y(j+1)=Yj+hYj, Y(0)=1である。 このプログラムを教えてください。 #include <stdio.h> #include <math.h> main() { double pi, x, y; int i; pi=4*atan(1); x=1/100; y=1; for(i = 1; i<=100; ++i){ x=i*1/100; y[n+1]=y[n]+1/100*y[n]; printf("%lf %lf\n", i, x, y,); } } ではだめなんでしょうか?

  • 関数宣言

    3次元で領域を確保するプログラムをmalloc関数を用いて書きました。しかし、プログラムが長いので関数宣言をしなさいといわれたために、以下のプログラムを書きました。しかし、途中でつまづいてしまい、どのように関数を用いたり、関数を定義すれば良いのか混乱しています。初心者ですが、どうかお願いします。 /*ソース*/ #include<stdio.h> #include<stdlib.h> int main(){ double ***C; f3Malloc(C,.,.); //数値を代入(関数の使い方?) f3Free(C,.,.); } /*3次元配列(返し方?)*/ double*** f3Malloc(C,,){ int i,j,x,y,z; x = 2; y = 3; z = 4; C=(double***)malloc(sizeof(double**)*x*y*z); for(i=0;i<y;i++){ C[i]=(double**)malloc(sizeof(double*)*y*z); for(j=0;j<z;j++){ C[i][j]=(double*)malloc(sizeof(double)*z); } } } /*メモリの解放(返し方?)*/ void f3Free(C,.,.){ int i,j,x,y; x = 2; y = 3; for(i=0;i<x;i++){ for(j=0;j<y;j++){ free(C[i][j]); } free(C[i]); } free(C); }

  • 三次元を二次元に・・・

    ヘッダーファイルの中にXeasyGraphic.hと言うのがあり、立方体を表示させ回転たいのです。 そして、三次元で回転させ、二次元に落とすという方法をしたかったのですが、どうしても、ゆがんでしまいます。どうしたらいいでしょうか? -------ソース------- #include<stdio.h> #include<XeasyGraphics.h> #include<math.h> int main(){ /*立方体の宣言*/ float box_x[8]={10,10,10,-10,10,-10,-10,-10};/*X軸*/ float box_y[8]={10,10,-10,10,-10,10,-10,-10};/*Y軸*/ float box_z[8]={10,-10,10,-10,-10,10,10,-10};/*Z軸*/ /*立方体のキャッシュ*/ float box_x2[360][8],box_y2[360][8],box_z2[360][8]; /*平面に落とした時のキャッシュ*/ float flat_x[360][8],flat_y[360][8]; /*回転用*/ int j,i; float th,x,y,x2,y2; /*回転プログラム*/ for(j=1;j<=360;j++){ for(i=0;i<8;i++){ x=box_x[i]; y=box_y[i]; th=(PAI/180)*j; box_x2[j-1][i]=x*cos(th)-y*sin(th); box_y2[j-1][i]=x*sin(th)+y*cos(th); box_z2[j-1][i]=box_z[i]; } } /*三次元から二次元へ*//*ここが間違えていると思われる*/ for(j=0;j<360;j++){ for(i=0;i<8;i++){ flat_x[j][i]=box_x2[j][i]-box_z2[j][i]; flat_y[j][i]=box_y2[j][i]-box_z2[j][i]; } } /*この後に表示が入る予定*/ getchar(); exit(0); }

  • 二次元空間におけるフーリエサイン変換のプログラミング(C)について

    二次元のフーリエサイン変換を考えています。 正方形の中心にだけ高い数値を持つ状況をつくり、その波数分布を示したい(最終目標は違いますが・・・)のですがうまくいきません。 下記のように書いてみましたが、コンパイルは通っても、変換した値が一様に0となってしまいます。 よろしければ、見てやってください。 #include<stdio.h> #include<math.h> #define max 100 #define pi 3.141592 main() { //変数i,jが位置、ki,kjが波数に当たります int i,j,ki,kj; //Nはデータ点の数 int N=30; double a[max][max]; double A[max][max]; //aの分布をデルタ関数的なものとします。 for(i=0;i<N;i++){ for(j=0;j<N;j++){ a[i][j]=0; }} a[N/2+1][N/2+1]=100; for(ki=0;ki<N;ki++){ for(kj=0;kj<N;kj++){A[ki][kj]=0.0; for(i=0;i<N;i++){ for(j=0;j<N;j++){ A[ki][kj] += (2/N)*(2/N)*a[i][j]*sin((2*pi*ki*i)/N)*sin((2*pi*kj*j)/N); }}}} return(0); }

  • 三角関数の導関数

    いつもお世話になっています。 三角関数の導関数のところで  lim{sin(x+h) - sin(x)}/h = lim{2cos(x+h/2)sin(h/2)}/h = lim{cos(x+h/2)sin(h/2)}/(h/2) のように変形して、h→0 のとき  cos(x+h/2) → cosx  sin(h/2)/(h/2) → 1 として求めていました。 ここで質問なのですが  lim(○△) = lim○lim△ のようなことをしてもよいのでしょうか? あと h→0 のときに sinh/h → 1 となる証明は http://osaka.cool.ne.jp/economia/math/math4.pdf のページ等で図形を使うものを見つけて大体納得できたのですが、  cos(x) < sin(x)/x < 1 まできたところで、x→0 のとき cos(x)→1 とやっています。 最後のところですごく感覚的になった気がするのですが、 これは式で証明しなくてよいのでしょうか?

  • ダイヤモンドパターンを回転させる

    こんにちは。 次の問題がわかりません(>_<) 【グラッフィックスのダイヤモンドパターンを回転させる】問題です。  平面図形(正八角形、正十二角形とか)がくるくる回るようにしたいのですが、図形が崩れた感じで奇妙な(?)回転になります。一応、プログラムは書いてみましたが、どこが間違っているのかわかりません。  下に自分で考えたプログラムの流れとソースを記しておきました。わかる方ご回答願います。 ※ 実行結果は無限に設定してあるので、Ctrl+C でプログラムを強制的に終わらせることとします。 【プログラムの流れ】 (1) 座標を計算(半径1のもの) (2) ダイヤモンドパターンを書く (3) 座標を回転 (4) ちょっと待つ (5) 画面を消去する→(2)に戻る 【プログラム】 ----------------------------------------------------------- /* ダイヤモンドパターンを回転させる */ #include <stdio.h> #include <math.h> #include <gucc/gucc.h> #define PAI 3.141593 void main( void ) { int i, j, np, k, t1,c,t2,rad,u,v; double x[100], y[100], z[100]; int R[5]={0,64,128,192,255}; int G[5]={0,64,128,192,255}; int B[5]={0,64,128,192,255}; double rs, ang; rs = 150.0;/*円の半径*/ printf("頂点数? "); scanf( "%d",&np );/*npは頂点数*/ for( i=0; i<np; i++ ){ ang = 2.0 * PAI * (i-1) /np ;/*PAIはπ*/ /*半径1の円周上の点*/ x[i] = cos(ang); y[i] = sin(ang); } G_INIT();/*グラフィックモードの切り替えと初期化*/ G_CLS(); do{ /*図形を描く*/ for( i=0; i<np-1; i++ ){ for( j=i+1; j<np; j++ ){ G_LINE( rs*x[i]+ 300.0, rs*y[i]+ 240.0, rs*x[j]+ 300.0 , rs*y[j]+ 240.0 ); } } /*座標を回転 */ for( i=0; i<np-1; i++ ){ rad=rad+0.05; z[i] = x[i] * cos(0.05) + y[i] * sin(0.05); y[i] = -x[i] * sin(0.05) + y[i] * cos(0.05); x[i]=z[i]; } /*ちょっと待つ*/ t1=time(&t2); while(t1==time(&t2)); /*画面を消去*/ G_CLS(); }while(1); } ----------------------------------------------------------------

専門家に質問してみよう