• 締切済み

do-while文の処理が実行されない

コンパイラは通ったのですが、自分の思うように処理されない箇所があって困っています。 1区間の数字列を回帰直線で近似し、回帰直線との誤差が最大の点で区間を分割(誤差が閾値以上なら)するプログラムを作っています。次に分割した区間それぞれに同様の作業をし、分割が一つでもあればまた最初から繰り返す、どこも分割されなければ終了・・・という流れです。 プログラムでは do{ bunkatu=0; for(全ての区間){ (最大誤差や回帰直線の傾きを0に初期化する) (傾き、最大誤差求める) if(最大誤差が閾値以上なら){  (最大誤差の点を境に区間を分けるよう設定) bunkatu = 1;} } }while((bunkatu) != 0); と表しています。分割が一つでもあれば変数 bunkatu が1になり、whileの条件 (bunkatu) != 0 と合っているのでまた do 以下から動作する・・・と考えているのですが、考え方としてはこれで合っているのでしょうか。

みんなの回答

回答No.5

 #1さんの質問に『調べたところ回数が延々と出力され、10数万いったぐらいで「セグメントエラー」が起こりプログラムが終了しました。for文から抜け出していないと思われますが、どうしてそうなるかが検討がつかない状態です。』と返答されているので、#4さんが回答しておられるように、設定配列要素数より大きな値(あるいは小さな値)をもって配列をアクセスしたことによるセグメンテーション違反のエラーです。  しかし、提示されたプログラムにそのような配列要素を変えるようなプログラム箇所はありません。すなわち、Kaikia(), Kaikib(), Gosa(), Point() のいずれかに配列要素を換えるようなプログラム部分を持っているものと思われます。そのプログラムの配列要素を決めるやり方をしている関数とその箇所を見つけて訂正して下さい。考えられるのは   i=(int)実数計算式 をもって int型の配列要素としているアルゴリズムを使っている場合です。  なお、近似プログラムにおいて10数万も繰り返すことは、解のない発散状態にあることを示しています。よって、アルゴリズムの見直しも必要と考えます。

全文を見る
すると、全ての回答が全文表示されます。
  • 6yemon
  • ベストアンサー率69% (25/36)
回答No.4

> 調べたところ回数が延々と出力され、10数万いったぐらいで「セグメントエラー」が起こりプログラムが終了 はっきり言って、これはまともな動作ではありませんので、どこかでメモリ破壊を起こしていると推測します。 メモリ破壊とは何か。 int a[5]; と定義した配列があるとします。この配列には a[0]~a[4] が存在しますが、a[5] = 0; とすれば、この配列以外のメモリを書き変えてしまうことになります。Cは配列の上限チェックを行いません(下限もチェックしない)ので、意図したか否かに関わらず、配列以外のメモリを書き変えることができてしまいます(いわゆるバッファオーバーフロー)。そのメモリは別の変数である可能性大ですから、プログラムの記述とは違う時点でその変数の値が変わってしまいます。こうした事を「メモリ破壊」と呼びます。メモリ破壊があれば、プログラムが思いもよらぬ動きをするのは当然です。 char の変数領域(8bit単位)に int 型(32bitの事が多い)へのポインタで書き込む、int の変数領域に double 型(普通64bit)へのポインタで値を書き込む…等もメモリ破壊を起こします。他に、スタックオーバーフローを起こした、割込処理或いは他のスレッドによって変数が書き変えられた等、いろいろなケースがあります。 大抵の場合、メモリ破壊はプログラムのバグであり、それがどこに潜んでいるか簡単に見当がつくようなものではありませんが、バグがあるかもしれないという目で提示されたコードを眺めてみると、気になる所がいくつかあります。特に for 文の回し方がそうです。 例えば、次の for 文。 for (o = all; o >= 0; o--) { ... 上記の int a[5]; について for ループを回すとしたら、例えば for (o = 4; o >= 0; o--) { a[o] = 何か; } のように回すことができますが、配列のサイズが5だからと言って for (o = 5; o >= 0; o--) { a[o] = 何か; } と回したなら、本来存在しないはずの a[5] を書き変えてしまいます。これを連想してしまうのです。要するにバッファオーバーフローです。 他にも ・E[h] = E[h - 1]; の E[h - 1] が配列の外(E[-1])をアクセスする事はないか ・E[o + 1] = E[o]; の E[o + 1] は大丈夫か、等々 念のために言えば、これらが誤りだと断定しているのではありません。提示されたコードはプログラムのほんの一部分でしかなく、ここに至るまでの経緯がわかりませんから、この回し方で正しいかもしれませんし、もちろん他のコードがメモリを破壊している可能性もあります。疑いの目で見ないとバグの手がかりは得られないという事なのです。

全文を見る
すると、全ての回答が全文表示されます。
  • ricardo_
  • ベストアンサー率19% (14/72)
回答No.3

bunkatu=0; のような初期化をループの中で行ったため、値が毎回リセットされループの脱出条件がいつまでも満足しないと言うようなミスを犯しやすい。  doやforループにそのような事がないか点検してみたらどうですか。  符号無し整数なのに負数になったら脱出というミスも有ります。  命令を削って無限ループの原因を探る事です。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

可能な限り、「ソースそのもの」を提示するようにしてください。

rurur
質問者

補足

do{ bunkatu=0; all=kaisuu; for(o=all; o>=0; o--){ katamuki=0.0; seppen=0.0; point=0; maxgosa=0.0; katamuki = Kaikia(S[o],E[o],x); seppen = Kaikib(S[o],E[o],x); if(E[o]-S[o] > 21){ maxgosa = Gosa(S[o],E[o],katamuki,seppen,x); if (maxgosa > 50.0){ point = Point(S[o],E[o],katamuki,seppen,x); for(h=all; h>=o; h--){ if(h>o){ E[h]=E[h-1]; S[h]=s[h-1]; } } E[o+1]=E[o]; E[o] = point; S[o+1] = point + 1; kaisuu++; printf("%d\n",kaisuu); bunkatu = 1;} } } }while((bunkatu) != 0); 失礼しました、上が自分のプログラムの質問部分のソースです。 Kaikia : 回帰直線の傾きを出力 Kaikib : 回帰直線の切片を出力 S(tart)[o],E(nd)[o] : 区間の始点と終点の位置 Gosa : 回帰直線と各点の最大誤差を出力 Point : 最大誤差を取る点の位置を出力 S[0]・・・E[0] S[1]・・・・・・・E[1] S[2]・・・E[2] という区間がある場合、S[1]とE[1]の間で分割が起こると S[0]・・・E[0] S[1]・ E[1] S[2]・E[2] S[3]・・・E[3] となるようプログラムしたものです。

全文を見る
すると、全ての回答が全文表示されます。
  • ricardo_
  • ベストアンサー率19% (14/72)
回答No.1

 for文が for(;;){}; の形になっていないような感じがします。  for文の中で止まっているんじゃないかな。  printf("コメント") をプログラムの要所要所に入れ、プログラムが何処を通過するか調べたらどうですか。

rurur
質問者

補足

調べたところ回数が延々と出力され、10数万いったぐらいで「セグメントエラー」が起こりプログラムが終了しました。for文から抜け出していないと思われますが、どうしてそうなるかが検討がつかない状態です。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • do-while文での無限ループ?

    こんにちは。 いつもお世話になっております。 現在Perlを使用してプログラムを組んでいますが、無限ループになってしまうらしく、次の画面に遷移しません。 @selected2には最大10個までの要素が入ります。(要素数は都度違う) その要素の中から$carno以外の要素を1つ選びたいのですが、このプログラムだとうまく動きません。 do-whileを取るととりあえずは動くので、条件の所が間違っているようなのですが、どう考えても正しいような気がします。 do{ if($ransuu==0){ $ransuu=int rand(11); } for($k=1;$k<=$a;$k++){ if($selected2[$k]==$ransuu){ $second=$ransuu; } } }while($ransuu==$carno || $second!=$ransuu); アドバイスをよろしくお願いいたします。

    • ベストアンサー
    • Perl
  • ある1点で傾きが急激に変化する波形に回帰直線を2本引きたい

    ある1点で傾きが急激に変化する波形に対して、その点を境に回帰直線を2本引くことを考えています。 人間の目で波形を見ると、「この辺りで傾きが急激に変化しているな」と認識できるのですが、数学的(プログラム的)にはどのように「急激に変化している点」を見つければ良いのでしょうか? 今考えている方法は、以下の泥臭い方法です。なんだか泥臭くて、もっと良い方法を探しています。 (1)波形がa≦x≦ bの範囲の時、注目する点(x = n)をaからbまで動かす。 (2)各時点の回帰直線1(a≦x≦n)の傾きと回帰直線2(n≦x≦ b)の傾きの二つ求める。 (3)「回帰直線1の傾きと回帰直線2の傾きの比」が最も大きい(小さい)点を、傾きが急激に変化している点とする。 (4)(3)で求めた点を境に2本の回帰直線を引く。 どなたか、お知恵を貸してください。

  • 回帰直線の変数xとyを入替えた場合の傾き

    数学の知識に乏しい者です。 回帰直線の傾きについて質問があります。 2変数での回帰直線の傾きにおいて、変数を入替えた場合の傾きは、入替え前の傾きの逆数になるのではないかと思うのですが、Excelで計算したらそのようになりません。 例えば・・・ (1,3)、(2,5.2)、(3,6.6)、(4,10.5)、(5,12)という座標の回帰直線の傾きは、 SLOPE関数を用いると2.33になります。 一方、変数xとyを入替えた場合の回帰直線の傾きは0.419125…となり、2.33の逆数である0.429185…と一致しません。 「傾きが逆数になる」という私の考えが間違っているのか、Excelの誤差なのか、どうなのでしょうか。 よろしくお願いします。

  • 散布図の回帰計算と信頼区間の設定

     2つの量に関する散布図があって、そこから回帰計算で直線近似するというのは最小2乗法のシンプルな適用事例です。さらにそこに”95%信頼区間”というものが設定されるようです(図を参照願います)。これはどういう風に計算するのでしょうか。 図はRが計算したもので、作図コマンドに”信頼区間を出せ”と指定するだけで出てきます。  直線が最小2乗法の結果からずれると誤差が増えることは評価できると思います。誤差が大きくなると信頼性が落ちるということを評価するのでしょうか。誤差と信頼性(%)の関係が示されないと具体的な数値が出せないと思うのですが。あるいは別の考え方かもしれませんが、信頼区間をどのように決めるのでしょうか。

  • switch文とwhile文を用いたプログラムに関して

    swich文とwhile文を用いたプログラムについて 授業の課題で、swich文とwhile文を用いたプログラムを作りなさい。いう課題が出ました。 5桁以上9桁以下の正の整数を入力し、4で割り切れたとき、何桁の数字かを出力。4でわって1余ったとき、すべての桁の合計を出力。3余ったとき、与えられた数の逆を変数に代入し、その変数を出力(単純に表示するわけではなく、数字として表示) といったものです。 途中からの授業参加で、C言語に関する知識はほとんどありません。do文を用いたプログラムは見つけれたのですが、while文とswich文を用いろということなので、do文は使えないです。 どなたか教えていただけませんか? 今日中にわからないとちょっとやばいです・・・。 よろしくお願いします

  • 回帰直線の傾きと切片の誤差

     エクセルで散布図を作成した後、近似直線(y=ax+b)を作りました。R-2値は0.999以上で非常に高い相関がみられたのですが、この直線の傾きと切片はどの程度の誤差を有しているのか知りたいです。傾きaと切片bの誤差の導き方を教えてください (それぞれの誤差をc,dとすると、a±c, b±dのような表現の仕方がしたいと思ってます)。よろしくお願いいたします。

  • 近似直線の傾きとSlope関数で求めた傾きについて

    近似直線の傾きとSlope関数で求めた傾きについて Excelでxとyについてのプロットデータに近似直線を追加しグラフにしました。そのときグラフ上にy=aX+bのような近似式を表示することができます。 ことのきの近似式の傾きaと、同じプロット点を使いSlope関数で求めたときの傾きとは別物なのでしょうか。同じになると思っていたのですが、同じ値にならないもので・・・。

  • 二変数の線形近似の方法

    ある二変数(x,y)に正の相関があることがわかりました。 最小二乗法などで回帰直線を求めてみたのですが、散布図に当てはめても、どうもずれているようなものになってしまいました。 変数が正規分布しているとみなせるなら、傾きが(yの標準偏差)/(xの標準偏差)、点(xの平均,yの平均)を通る直線で近似できると思うのですが、かなり歪んだ分布で、片方に裾が広がっています。 このようなケースでうまく近似する直線を求めるにはどうすればよいでしょうか。方法が間違っているのでしょうか。 質問に不備がありましたら補足要求をお願いします。よろしくご指導ください。

  • 【至急】BASICプログラムの問題(初心者)

    N88互換BASICというフリーソフトで作っています。 f(x)=x^4-7x^3-6x^2-4x+1の曲線とy=0の直線とで囲まれる面積を、x=0から10の範囲で近似的積分という問題です。 近似精度は10^-3以内。 シンプソン公式を用いて近似するとあります。 下記が手順です。 1、分割数zを入力。 2、dxの値を分割数から逆算して求める。(dx=「全体幅」/「2×分割数」) 3、FORNEXT文を用いて、各分割数区間毎にx座標を特定して放物線の面積を求める計算をし、その累積を求める。 4、求まった積分結果、そして答え「310」との誤差表示。 5、誤差が10^-3以内なら終了。それ以上なら1に戻る。 基礎的なコマンドは習いましたが、初心者なのでよくわかりません。説明不足でよくわからないとは思いますが、教えて頂けると嬉しいです。

  • べき乗関数の回帰式の95%信頼区間

    モデル式としてべき乗関数[Y=a*X^b]を用いて回帰分析を行なっています。回帰式の95%信頼区間を求めたいのですが、計算できません。ご教授願えますか? これまでやったことを示します。線形回帰の95%信頼区間の計算をRを使って行なうことができるので、べき乗関数を対数変換し、直線回帰を行ないました。ここで得られた95%信頼区間を表す式の切片、傾きから実数空間に戻して再計算したのですが、正しい結果が得られませんでした。 使用しているサンプルは下記の通りです。 X     Y 0.844   2.041873793 0.83   5.242322324 0.743   3.123938274 0.69   1.288763738 0.62   4.60944809 0.42   0.178478931 0.313   0.743454646 0.304   0.87 0.27   0.857248415 0.086   0.171183408 よろしくお願い致します。