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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

1442閲覧

break ラベル;で思うように飛ばないです

ko20vonobird

総合スコア50

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2017/01/08 07:37

編集2017/01/08 11:52

###前提・実現したいこと
フォームから得られた自然数で四則演算のみが用いられた数式を評価して、答えを返すというプログラムの製作途中です。

###発生している問題

ブレークポイントを用いて確認したところ、break subloop;でsubloop:に戻るという動作を期待しているのですが、なぜかいくらかforが実行された後for文を抜けて最後のアラート(式の評価)に飛びます。感覚的にはbreak ラベル;が実行されていない感じです。

###該当のソースコード

javascript

1function keisan() { //a 2 /*try{*/ 3 var chk1 = 0 4 var str = document.siki.mainsiki.value; 5 var strlong = str.length; 6 for (var cnt = 0; cnt < 10; cnt++) { //b 7 if (str.indexOf(cnt, 0) != 0) { //c 8 chk1++ 9 } //c 10 } //b 11 if (chk1 > 9) { //d 12 alert("最初の文字は数字にしてください"); 13 return; 14 } //d 15 var siki = str; 16 var sikilong = siki.length; //0-x + 1 17 var sisoku = new Array(); 18 sisoku[0] = '+'; 19 sisoku[1] = '-'; 20 sisoku[2] = '*'; 21 sisoku[3] = '/'; 22 var sisokunum = 0; 23 /*var sisokunochk = 0;*///不要? 24 for (var cntstrnum = 0; cntstrnum < sikilong; cntstrnum++) { //e 25 var chk = siki.charAt(cntstrnum); 26 for (var cnta = 0; cnta < 4; cnta++) { //f 27 if (chk == sisoku[cnta]) { //g 28 sisokunum = sisokunum + 1; 29 } //g 30 } //f 31 } //e 32 if (sisokunum == 0) { //h 33 alert("答え:" + siki); 34 return; 35 } //h 36 var sisokunochk = 0;//テスト// 37 /*loop:*/ 38 for (var cntmain = 0; cntmain < 2; cntmain++) { //i////gotoの代わり 39 /*var sikip = ""; 40 if (sisokunochk != 0) { 41 continue loop; 42 }*/ 43 subloop: 44 for (var cntb = 0; cntb < sikilong; cntb++) { //j 45 var sisokunochk = 0;//テスト// 46 var sikip = "";//テスト// 47 var counter = 0; 48 var countertwo = 0; 49 var sikipa = ""; 50 var sikipb = ""; 51 var sikisisoku = ""; 52 var sikiright = ""; 53 var twosisoku = 0;//// 54 for (var cntxyz = 2; cntxyz < 4; cntxyz++) {//xyz 55 if (sisoku[cntxyz] == siki.charAt(cntb)){//cntxyz 56 twosisoku = 1; 57 }//cntxyz 58 }//xyz 59 for (var cntz = 0; cntz < 4; cntz++) { //k 60 if (sisoku[cntz] == siki.charAt(cntb)) { //l 61 counter = 1; 62 } //l 63 } //k 64 if (counter == 0) { //m 65 sikip = sikip + siki.charAt(cntb); //sikipはsikiの計算する部分の記録用 66 if (cntb == sikilong - 1) { //n 67 sikipb = sikip; 68 } //n 69 } else if (counter == 1) { //m 70 for (var cnty = 2; cnty < 4; cnty++) { //o 71 if (sisoku[cnty] == siki.charAt(cntb)) { //p 72 if (sikipa == "") { //q 73 sikipa = sikip; 74 sikip = ""; 75 } else { //q 76 sikipb = sikip; 77 sikiright = siki.substr(cntb + 1, sikilong - 1); //怪しい 78 } //q 79 sikisisoku = siki.charAt(cntb); 80 continue; 81 } //p 82 } //o 83 } //m 84 for (var cntx = 0; cntx < 2; cntx++) { //r 85 if (sisoku[cntx] == siki.charAt(cntb) && twosisoku == 0) { //s//twosisokuは*/の数 86 sikipa = sikip 87 sikip = ""; 88 sikisisoku = siki.charAt(cntb); 89 } else if (sisoku[cntx] == siki.charAt(cntb) && twosisoku > 0) { //s 90 sikip = ""; 91 } //s 92 } //r 93 94 if (sikisisoku != "" && sikipa != "" && sikipb != "") { //s2 95 if (sikisisoku == sisoku[0]) { //t 96 sikileft = sikipa + sikipb; 97 siki = sikileft.toString() + sikiright.toString(); //以下共通 98 } else if (sikisisoku == sisoku[1]) { //t 99 sikileft = sikipa - sikipb; 100 siki = sikileft.toString() + sikiright.toString(); 101 } else if (sikisisoku == sisoku[2]) { //t 102 sikileft = sikipa * sikipb; 103 siki = sikileft.toString() + sikiright.toString(); 104 } else if (sikisisoku == sisoku[3]) { //t 105 sikileft = sikipa / sikipb; 106 siki = sikileft.toString() + sikiright.toString(); 107 } //t 108 } //s2 109 sikilong = siki.length; //計算後を想定した記述 110 sisokunochk = 0; 111 for (var cntc = 0; cntc < sikilong; cntc++) { //t 112 var chka = siki.charAt(cntc); 113 for (var cntd = 0; cntd < 4; cntd++) { //u 114 if (chka == sisoku[cntd]) { //v 115 sisokunochk = sisokunochk + 1; 116 } //v 117 } //u 118 } //t 119 if (sisokunochk == 0) { //w 120 continue; //もう四則演算子がない 121 } //w 122 if (sisokunochk != 0) { //x 123 continue subloop; //まだ四則演算子がある 124 } //x 125 } //j 126 127 } //i 128 alert("答え:" + siki); 129 return; 130 131 /*}catch(e){ 132 alert("式が不適合もしくはエラーです。"); 133 return; 134 } 135 finally{ 136 return; 137 }*/ 138 } //a

###試したこと
ブレークポイントを設定し、どうプログラムが進んでいるのかを詳細に調べました。また、ラベルで該当する文を{}で囲み、for文としてでなくラベル文として機能するようにしました。

###補足
"1+4"で検証しました。

###修正したこと
ラベル {}の{}を削除
break ラベルをcontinue ラベルに変更

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

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

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

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

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

kei344

2017/01/08 11:45

回答が付いた質問の編集は慎重に行ってください。質問文のコードについて回答にて指摘があった場合は「追記」し、元のコードを編集する場合も「直したこと」がわかるようにしてください。
ko20vonobird

2017/01/08 12:00

修正したこと、の項目を設けました。
guest

回答2

0

ベストアンサー

たぶん、やりたいことと、berakの動作についての認識が逆になっていると思われます。

やりたいことは、break subloop;の所で、ループの最初からやり直したいということであってますでしょうか?もし、そうであれば、使うのはbreakではなくcontinueです。しかし、このままcontinueに変えても動作しません。

まず、次のコードを動かしてみてください。

JavaScript

1console.log("test before"); 2test: for (let i = 0; i < 10; i++) { 3 console.log(i); 4 if (i < 5) { 5 continue test; 6 } else { 7 break test; 8 } 9} 10console.log("test after");

下記のようになったと思います。

"test before" 0 1 2 3 4 5 "test after"

コードの動作を見てみると、iが0から4のときは、continue test;が処理されますが、これはループの最初に戻っています。逆に、iが5になった瞬間にbreak test;が処理され、ループを抜けています。

コードからわかるとおり、break ラベルはラベルの位置に戻るのではなく、ラベルの付いたブロック(ループでない場合も同じ)を抜ける、つまり、ブロックが終わったところに処理が移ると言うことです。もし、ラベルの位置に戻りたい場合は、continue ラベルを使う必要がありますが、continueループにしか使用できません

以上を踏まえて処理を見直してみてください。また、深いループは混乱の元ですので、関数に小分けすると、わかりやすくなると思います。

投稿2017/01/08 11:16

raccy

総合スコア21735

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

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

ko20vonobird

2017/01/08 11:50

なるほど、つまり、breakラベルは他の言語でのgotoの働きではないのですね、、、勘違いをしていました。continueはforがラベルの次の文章に記述されていれば、ラベルに飛ぶということでしょうか? また、ここ2、3日これを作っているのですが、恥ずかしながら混乱しております。なので、お聞きしますが、これの目的は式を計算し答えを出すというものなのですがなぜか式が返されます。これの原因は一体何なのでしょうか??
raccy

2017/01/08 11:59

そうですね。JavaScriptのラベルはbreakやcontinuneの対象を指定できるという意味以上は無いですので、gotoとは同じ動作になりません。 すいません、私も途中でコードが追えなくなってきて、何をやっているのかよくわからないです。私からのアドバイスは一つ、処理を関数に小分けすることです。ブロック単位でもいいですので、何が入力で何が出力なのかをはっきりさせながら、別の関数にしてみてはいかがでしょうか?
ko20vonobird

2017/01/08 12:18

恐縮です。 関数に小分けするということを試してみようと思うのですが、大元のfunction()の中にさらにfunction()を作るということで合っていますか?また、その場合、子関数は親関数の中に記述するということで良いのでしょうか?
raccy

2017/01/08 13:06

JavaScriptは関数の中に関数を作れますが、クロージャーを理解しておく必要がありますので、必要で無ければお勧めしません。基本的にトップレベルに関数を並べると考えてください。関数にするのは「入力」と「出力」をはっきりさせるためです。例えば、「演算子、値1、値2」という入力に対して「結果」という出力を得る、等と言った一つの処理を関数として小分けに作って行きます。それを、大本の関数から呼び出します。 あまり関数を作ったことが無ければ、いきなりこの課題でするのはちょっと難しいかも知れません。計算機のようなものを作るという課題は、結構ハードルは高めです。
ko20vonobird

2017/01/08 13:15

クロージャ―、少々調べてみましたが、一筋縄ではいかないようですね。他の言語にあるメンバ変数とかが関わってくるのでしょうか。 ハードルは確かに、今やっていて難しいと感じるばかりです、、、。 今は言うて暇があまりないので勉強する時間は取れませんが、取れるようになれば再び勉強しようかと思います。
guest

0

ブレークポイントが指定できているのであれば、ループカウンタの値がどのように変化しているのか分かりますか?

投稿2017/01/08 10:05

sleepsheep

総合スコア310

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

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

ko20vonobird

2017/01/08 10:50

調べたところ、ループカウンタcntbは、0のままでした
sleepsheep

2017/01/08 11:16

subloopラベルの直前にあるfor文のループカウンタ [cntmain]はどうですか?
ko20vonobird

2017/01/08 11:45

cntmainは0から1にて動作していました。
sleepsheep

2017/01/08 12:06

そのカウンタの変化は想定されているものでしょうか? [break subloop;]が実行されているので、そのような動作になると思うのですが・・・。 あと、他の方の回答にもありますが、処理の見通しが悪いように思いますので、関数化したほうが良いと思います。
ko20vonobird

2017/01/08 12:16

cntmainに関しては、0から1に変化する際に必要な処理を記述するためだけのfor文です。 なるほど、break subloop;ですか、、。 そうですね、関数化する方向で調整しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問