質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

977閲覧

c言語 数値計算 do-while文の繰り返しが意図した回数行われない

drilllaser

総合スコア2

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/08/08 09:15

編集2021/08/08 09:18

前提・実現したいこと

初学者です。cを用いて数値計算の勉強をしています。

今回行ったことは一次元の熱伝導のシミュレーションです。

do-while文で繰り返しを行っているのですが,whileに記述している条件を満たさなくなる前に終了することがあります。

具体的に説明しますと500回繰り返してほしいところが94回で終了したりします。大体5回行うと3、4回この現象が起こります。

またこの回数は#defineで定義してるところをmain()のなかで記述したりすることで変わったりします。

このコードで行っている熱伝導の条件を以下に示します。
∂u/∂t = ∂^2u/∂x^2 (0<x<1)
u(x,0) = x (0<=x<=1/2) or 1-x (1/2<x<=1)
u(0,t) = u(1,t) = 0
⊿x = 1/10, ⊿t = 1/500

お手数おかけしますがよろしくお願いいたします。

該当のソースコード

c言語

1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4#include <string.h> 5#include <unistd.h> 6 7#define X 1. 8#define T 1. 9#define N_X 10 10#define N_T 500 11 12int main(){ 13 double u[N_X+1], new_u[N_X+1]; 14 double dx = X / (double)N_X, dt = T / (double)N_T; 15 double a = dt / (dx * dx); 16 double b = 1. - 2. * a; 17 int i, j = 0; 18 double t; 19 20 for(i=0; i<= N_X / 2; i++) u[i] = dx * (double)i; 21 for(i=N_X / 2 + 1; i<=N_X; i++) u[i] = 1. - dx * (double)i; 22 23 new_u[0] = 0.; 24 new_u[N_X] = 0.; 25 26 do{ 27 j++; 28 t = j * dt; 29 30 for(i=1; i<N_X; i++) new_u[i] = a * u[j+1] + b * u[j] + a * u[j - 1]; //問題の箇所 31 for(i=0; i<=N_X; i++) u[i] = new_u[i]; 32 33 if(j%50 == 0) printf("t = %lf u[%d] = %lf\n", t, N_X / 2, u[N_X / 2]); 34 }while(j<N_T); 35 36 return 0; 37}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2021/08/08 09:32

> do-while文で繰り返しを行っているのですが,whileに記述している条件を満たさなくなる前に終了することがあります。 何を根拠に、判断したのでしょうか? また、提示のコードを見ると、 for() の行に "//問題の箇所" とありますが、関係あるのでしょうか?
drilllaser

2021/08/08 09:48

回答ありがとうございます。 自分なりにどこでエラーが起きているのか探ろうと思い、printf("N_T = %d\n", N_T);を様々なところに入れたところ //問題の箇所 と記入しているところまではキチンと出力されるのですが、それ以降に挿入すると出力されなかったので、//問題の箇所としているところで何か起きているのではないかと考えました。
guest

回答2

0

ベストアンサー

doループに入る時点でjは0ですが、ループ内でj++としていて、ループの継続条件がj<N_Tだとすると、u[j]は容易に配列として確保した範囲外にアクセスするように思いますがどうでしょうか。

正しい対応かどうかは検討していませんが、double u[N_T+1], new_u[N_T+1];としたらとりあえず意図しない停止はなくなったりしないでしょうか。

投稿2021/08/08 09:39

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

drilllaser

2021/08/08 09:52

ありがとうございます。単純にu[i]とするところをu[j]としてしまい、範囲外にアクセスすることでエラーが起こっていたと考えられます。
pepperleaf

2021/08/08 09:55

既に、 double u[N_T+1]; になってません? もっともよく見ると、u[N_T+1] にアクセスしてるので、 double u[N_T+2]; にする必要はありそう。(正しいかは不明)
guest

0

whileに記述している条件を満たさなくなる前に終了することがあります。

この場合のjとN_Tの数値はどういうものでしょうか

投稿2021/08/08 09:20

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

drilllaser

2021/08/08 09:29

説明不足で申し訳ありません。 N_Tは、この時間まで計算してほしいと思っている時間で、今回は1秒を指定しています。 tは今行っている時間の場所を示めしており、例えば繰り返しが1回目だと微小時間長さdt = T / N_T = 1 / 500に1を乗算し、t = 1/500秒となります。
y_waiwai

2021/08/08 09:31

数値の意味ではなく、 その満たさずに終了した場合のその数値は具体的にどういう数値なんでしょうか。
drilllaser

2021/08/08 09:37

満たさずに終了した場合、jは94や73になります。 (これはdo-while文をfor文にしたり、変数を定義する場所によってかわります) N_Tはdo-while文のあとにprintf()で表示するように書くと 満たさずに終了した場合、表示されませんでした。
y_waiwai

2021/08/08 09:40

> 満たさずに終了した場合、表示されませんでした。 って、whileの条件で抜けてるんではなく、別のエラーで落ちてるだけなんでは
drilllaser

2021/08/08 09:45

おっしゃる通りだと思います。 しかし、その別のエラーが具体的に何なのか、そしてその解決策を知りたく思い質問させて頂きました。
BeatStar

2021/08/08 09:48

横からすみません。 @ 質問者さん > しかし、その別のエラーが具体的に何なのか、そしてその解決策を知りたく思い そう言う場合は『デバッグすればいい』です。 プログラミングはデバッグやテストまで含みます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問