みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Visual C++での数値計算のプログラミング

質問初めてになります。
プログラミングにあまり詳しくない大学院の数理科の学生です。
学校で熱方程式の陽解法のプログラミングのレポートが出されたのですが、困っています。

レポートで詰まっている点は
windows Visual C++ Expressionでの陽解法のプログラミングです。

indows Visual C++ Expression2008が良くわからないのでコマンドプロンプトで実行しています。

熱方程式の初期値問題の陽解法のプログラムをなんとか組んでいます。
私が組んだプログラムではLinuxでは通るのですがwindows Visual C++ Expressionでは通りません。

このプログラムをwindows Visual C++ Expression 2008で通すにはどのように直したがいいのか教えて頂きたいと思います。よろしくお願いします。


以下は私なりに組んだプログラミングです。

πの値、u1[N+1]、u2[N+2]
の3箇所でエラーがでてると思われます。

#include<stdio.h>
#include<stdio.h>
#include<math.h>

int main(){
int i,k,kmax;
int N=10;
double dx
double dt=0.01;
double u1[N+1];
double u2[N+1];
double r=dt/(dx*dx);
double T=1.0;
kmax=T/dt;
u1[0]=0;
u1[N]=0;

for(i=1;i<=N;i++){
  u1[i]=sin(M_PI*i*dx);
}
for(k=1;k<=kmax;k++){
for(i=1;i<=N-1;i++){
u2[i]=r*u1[i-1]+(1-2*r)*u1[i]+r*u1[i+1];
}
  for(i=1;i<=N-1;i++){
u1[i]=u2[i];
  }
  for(i=0;i<=N;i++){
printf("%f %f %f\n",dt*k,dx*i,u1[i]);
  }
  printf("\n");
}
return 0;
}

投稿日時 - 2008-12-18 00:35:40

QNo.4564277

すぐに回答ほしいです

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

>int N=10;
>double u1[N+1];
>double u2[N+1];

賢い最適化をするコンパイラなら、main関数の中でNが不変なので、Nを参照している部分を、定数の「10」に置き換えてしまうでしょう。

なので
double u1[N+1];
double u2[N+1];

double u1[10+1];
double u2[10+1];
としてコンパイルされ、コンパイルを通ってしまうでしょう。

ですが、そこまで賢くないコンパイラは「実行時変数は配列の要素数の指定に使えない」と怒るでしょう。

また、コンパイラによっては
double u1[N+1];
double u2[N+1];

double *u1,*u2;
u1 = new double[N+1];
u2 = new double[N+1];
として動的に領域確保して、関数の出口で暗黙的なdeleteを行っているかも知れません。

いずれにせよ「異なる環境に移植すると、どうなるか判らない」のは間違いありません。

なお、math.hにM_PIが定義されてないコンパイル環境では
#ifndef M_PI
#define M_PI πの値を少なくとも15桁
#endif
と書かねば、コンパイル出来ません。

投稿日時 - 2008-12-18 02:07:29

お礼

皆様のおかげで無事に問題が解決できました。
その上問題の原因も理解することができ非常に助かりました。


慣れない質問の中、皆様優しく詳細に答えて頂き感謝いたします。

投稿日時 - 2008-12-18 10:27:23

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

M_PIですが、
#define _USE_MATH_DEFINES
#include <math.h>
とすれば、VisualC++でも使えるはずです。
Linuxで通って、VC++で通らないのは、C90とC99の違いでしょうね。
int N=10;

#define N 10
とすればよいのは、みなさんおっしゃる通りです。

投稿日時 - 2008-12-18 09:36:38

お礼

これから多倍長計算でのプログラムに書き換えないといけなかったんで非常に助かります。


最後にこの私の質問を読んで考えていただいた皆様ありがとうございました。

投稿日時 - 2008-12-18 10:23:17

ANo.3

gcc なら通りますよ>#2. そこに関してだけ言えば, 今の C の規格では OK.
どちらにしても M_PI の手当は必要ですが.

投稿日時 - 2008-12-18 01:43:16

お礼

コメントありがとうございます。

投稿日時 - 2008-12-18 10:17:32

ANo.2

Linuxで通るというのが信じがたいです。
結論を書けば下のように直せば通るでしょう。
ほかにもあるかもしれませんが、ここですね、まず。

int N=10;
 ↓
#define N 10

解説。プログラムの値は、実行時のものと、コンパ
イル時のものがあるということです。
int n=10; でNと表現したら、これは実行時に10に
なりますが、コンパイル時は"N"なのです。

なので、コンパイル時に配列の定義をする場合、
double u1[N+1];
int Nの内容の10は得られない訳です。
従って、どんなOSでもCコンパイラではこれはエラー
です。

#defineが数値に限らず、コンパイル時に指定された
ものに置き換わります。

投稿日時 - 2008-12-18 00:50:39

お礼

素早い返答ありがとうございます。
今までintとdefineの意味を考えずになんとなく使ってただけでしたが、違いがわかるようになりました。

お世話になりました。

投稿日時 - 2008-12-18 10:12:44

ANo.1

・M_PI は普通定義されていないと思った方がいい. 代替手段が必要.
・配列の定義するときには大きさとして整定数しか使えないので
int N=10;
ではなく
#define N 10
としなければならない.
とりあえずこの辺.

投稿日時 - 2008-12-18 00:50:35

お礼

素早くポイントを指摘していただいてありがとうございます。
お世話になりました。

投稿日時 - 2008-12-18 10:06:20

あなたにオススメの質問