GOTOの犁断の果実は甘いマむクロコントロヌラヌのバヌゞョン

良い䞀日



C / C ++のgoto挔算子に察するあなたの態床は䜕ですか ほずんどの堎合、プログラミングを孊んだずきにそれを䜿甚したした。 それからあなたはそれが悪いこずを知り、それを忘れたした。 耇雑な゚ラヌ凊理を䌎うこずもありたすが、いや、いや、詊しおみおください... throw ... catch。 たたはネストされたルヌプを終了するには...いいえ、フラグず倚くの困難がありたす。 たたは、ネストされたスむッチが...いいえ、いいえ、いいえ、同じフラグがある堎合。

それでも、倜の静寂の䞭で、あなたは朜圚意識に眪深い思考を蚱したした-「 ここで gotoを䜿甚しないのはなぜですか そしお、このプログラムはよりスリムに芋えるようで、最適な圢で登堎したす。 はい、それは良いでしょう...しかし、いいえ- それは䞍可胜です 、圌らは忘れおいたした」

なぜそうですか

長幎の実践ずさたざたなプラットフォヌムに基づいた小さな調査ず、この問題に察する私の姿勢です。 この蚘事は、 C ++の堎合ず同じものですが、Cおよびマむクロコントロヌラヌ専甚のハむラむトです。



gotoの熱烈な反察者ぞのリク゚スト-私がこのトピックを提起し、gotoの郚分的な支持者であるずいう理由だけで、私をマむナスカルマの地獄の火に倒さないでください

歎史的小旅行



組み合わせ回路、メモリ付き回路が䜕であるか、そしおアセンブラヌがこれからどのように成長したかを完党によく知っおいる人のために、私たちは安党に結論にスキップするこずができたす。



そしお、それはすべお組み合わせ回路から始たりたした






最初は蚀葉でした-そしお蚀葉は機胜でした。 それが論理倉数のブヌル関数であるこずはそれほど重芁ではありたせん-それに基づいお、圌らはすべおのほが数孊、そしおテキスト、グラフィックスを実装するこずに成功したした...ずにかく、コンピュヌタ技術を䜿甚するず非垞に䟿利であるこずが刀明したした算術、次に䞉角法およびその他のアクションを実行し、倉数の関数の倀を芋぀けたす。



぀たり、倉数の倀によっお関数の倀を芋぀けるデバむスを䜜成する必芁がありたした。



この困難な問題を解決するために、算術挔算を実行するための逐次アルゎリズムが構築されたしたこのようなアルゎリズムで蚈算の粟床が䞀定の堎合、各算術挔算は1クロックサむクルで実行できたす。



アルゎリズムを䜿甚するこずで、組み合わせ回路を構築するこずは難しくありたせん-即座に論理デバむスの動䜜ず信号の䌝播時間たで出力で答えを出す回路。

問題は、ここで移行が必芁ですか いいえ、圌らは単にそこにいたせん。 䞀貫した行動方針がありたす。 最終的に、これらのすべおのアクションは単䞀のクロックサむクルで実装できたす私は䞻匵したせんが、非垞に面倒になりたすが、すべおのデヌタのビット深床を考えるず、孊生はVHDLたたはVerilogのシンセサむザヌは蚀うたでもなく、そのようなスキヌムを構築したす



しかし、その埌、メモリ回路が介入したした






そしお、誰かのスマヌトヘッドがフィヌドバック回路RSトリガヌなどを思い぀きたした。 そしお、回路の状態が珟れたした。 そしお、状態はメモリを持぀すべおの芁玠の珟圚の倀に他なりたせん。



このようなメモリ゚レメントの出珟により、ハヌドワむダヌドデバむスからファヌムりェアぞの革新的な進歩が可胜になりたした。 簡単に蚀うず、ファヌムりェアにはコマンドメモリがありたす。 珟圚のファヌムりェア加算、枛算、たたはその他を実装する別のデバむスがありたす。 しかし、別のデバむスが「珟圚の」ファヌムりェアの遞択に関䞎しおいたす-それを「サンプリングデバむス」にしたす。



問題は、移行があるかどうかです。 間違いなくはい さらに、無条件の遷移次のコマンドのアドレスはデヌタの珟圚の状態に䟝存しないず条件付き次のコマンドのアドレスはデヌタの状態に䟝存するが衚瀺されたす。



それらなしで行うこずは可胜ですか たさか 遷移を䜿甚しない堎合、メモリなしで組み合わせ回路に戻りたす。



その結果、アセンブラヌに来たした




そのようなコンピュヌティングデバむスの神栌化は、マむクロコンピュヌタヌ、シンプルコンピュヌタヌ、スヌパヌコンピュヌタヌになりたした。 それらはすべお、基本的にほが同じコマンドセットでアセンブラヌに簡単に倉換できるコヌド蚀語に基づいおいたす。 マむクロコントロヌラの特定の平均化されたアセンブラを考えおみたしょうATmeg、PIC、AT90のアセンブラに粟通しおいたす。 圌の移行䜜業はどのように構築されたすか



遷移は無条件次のアドレスぞの移動、サブプログラムぞの移動、終了であり、条件付きフラグの状態に応じおです。



私はすべおの責任を宣蚀したす- アセンブラヌでの遷移操䜜なしに行うこずは䞍可胜です アセンブラヌのプログラムはどれも目を奪いたす ただし、ここで私ず䞻匵する人はいたせん。



たずめ




芁玄するず䜕ができたすか マむクロプロセッサレベルでは、移行操䜜が非垞に積極的に䜿甚されたす。 それらを䜿甚しない実際のプログラムを䜜成するこずはほずんど䞍可胜です実行できる可胜性がありたすが、それは超メガ倒錯であり、実際のプログラムではありたせん。 誰もこれに぀いお議論したせん。



しかし、なぜ、より高いレベルの蚀語で-マむクロコントロヌラのCに集䞭しお-goto挔算子が突然支持を倱いたしたか..



アルゎリズムに぀いお少し







それでは、トリッキヌなアルゎリズムを芋おみたしょう。 これがどのようなナンセンスなのかはわかりたせんが、実装する必芁がありたす。 これがTKであるず仮定したす。



ここで、A、B、C、D、Eはいく぀かの操䜜であり、関数呌び出しではありたせん 倚くのロヌカル倉数を䜿甚する可胜性がありたす。 そしお、圌らは圌らの状態を倉える可胜性がありたす。 ぀たり、この堎合、関数の呌び出しに぀いおは説明したせん-䞀郚のアクションは詳现になりたせん。



gotoでは次のようになりたす。



if (a) { A; goto L3; } L1: if (b) { L2: B; L3: C; goto L1; } else if (!c) { D; goto L2; } E;
      
      







非垞に簡朔で読みやすい。 しかし- それは䞍可胜です gotoなしで詊しおみたしょう



 char bf1, bf2, bf3; if (a) { A; bf1 = 1; } else bf1 = 0; bf2 = 0; do { do { if (bf3 || b) bf3 = 1; else bf3 = 0; if (bf3 || bf2) B; if (bf3 || bf1 || bf2) { C; bf1 = 0; bf2 = 1; } if (!bf3) { if (!c) { D; bf3 = 1; } else { bf3 = 0; bf2 = 0; } } } while (bf3); } while (bf2); E;
      
      







2番目のリストのロゞックから䜕か理解できたすか..

䞡方のリストを比范したす。







しかし、2番目のリストにはgotoはありたせん



このようなアルゎリズムを実装するために、このアルゎリズムも提䟛されたした 。





if a

A

C



while b or not c

if not b

D

B

C



E











それは矎しいようですよね コピヌペヌストをしないのはなぜですか、远加のチェックを終了しないのはなぜですか... goto以倖のすべおを実行しおください!!!



たあ、倧䞈倫、人生ではそのようなアルゎリズムはほずんど芋圓たりたせん。 人生に぀いおのより良い話。



実際のプログラムでgoto





20幎以䞊の経隓の䞭で、私はいく぀かのハヌドりェアプラットフォヌムず数十個のプログラミング蚀語を䜿い 、倧きなActiveHDL゜フトりェア補品の䜜成に参加し、商甚デヌタベヌスずオリンピック競技倧䌚で䜿甚される機噚をデバッグするための倚くの小さなプログラムを䜜成し、このためのデバむスも䜜成したしたオリンピックそのもの正確には、すでにいく぀かのオリンピック。 芁するに、私はプログラミングでシャッフルしおいたす。 そしお、はい、私は忘れおいたした-私はKHNUREから名誉卒業蚌曞を卒業したした -぀たり、理論的には、私もファックしたす。



したがっお、私のその埌の考えや状況...私はそれらに察する道埳的暩利を持っおいるず蚀っおみたしょう。



gotoの暗黙的な䜿甚




Cには、条件付きたたは無条件の、実際には些现なgotoである倚くの挔算子がありたす。 これらは、すべおの皮類のfor...、while...{...}、{...} while...ルヌプを実行したす。 これは、数倀倉数switch...{case ... case ...}の分析です。 これらは、ブレヌクルヌプずコンティニュヌルヌプの同じ割り蟌み/ゞャンプステヌトメントです。 最埌に、これらはfunct関数の呌び出しであり、それらを終了したす。



これらのgotoは「合法」ず芋なされたす-goto自䜓はなぜ違法ですか



gotoが非難されるもの




圌らは圌が刀読䞍胜になり、䞍十分に最適化されたず非難し、゚ラヌが珟れるかもしれたせん。 これは実甚的な短所です。 そしお、理論的なものは単に悪いず文盲です、それだけです



コヌドの読みやすさず最適化の悪さに぀いおは、䞊蚘のリストをもう䞀床芋おください。

゚ラヌの可胜性に関しおは-私は同意したすが、このコヌドはリストを䞊から䞋に読むこずに慣れおいるずいう事実により、やや耇雑に感じられたす。 しかし、それだけです しかし、Cの他の手段は安党であり、コヌドに゚ラヌを䜜成できないのでしょうか はい、少なくずも型倉換を行い、ポむンタヌを操䜜したす。 そこを台無しにするには-䜕もしないで



ナむフは非垞に危険なものだず思いたせんか しかし、キッチンで䜕らかの理由でそれを䜿甚しおいたす。 そしお220ボルト-恐怖、なんお危険なこずでしょう しかし、それを賢く䜿甚すれば、生きるこずができたす。



gotoに぀いおも同じこずが蚀えたす。 それを賢く䜿甚する必芁がありたす-そしお、コヌドは正しく動䜜したす。



そしお、理論的議論に぀いお-これは、すみたせん、奜みに぀いおの議論です。 ハンガリヌ蚘法を䜿甚しおいたすか 私-いいえ、私は圌女を我慢できない しかし、私は圌女がこのために悪いず蚀っおいるのではありたせん 個人的には、倉数にはセマンティックロヌドが必芁であるず考えおいたす-なぜ䜜成されるのか。 しかし、他の人がこの呜名芏則を䜿甚するこずを犁止したせん



たたは、a = ++ iを曞くこずは文盲であるず信じる麻酔医がいたす。i= i + 1ず曞く必芁がありたす。 a = i。 そしお今、これも犁止するには



゚ラヌ凊理




倖郚デバむスからの入力パケットの凊理を行いたす。



 pack = receive_byte (); switch (pack) { case 'A': for (f = 0; f < 10; ++f) { 
 if (timeout) goto Leave; 
 } break; case 'B': 
 } Leave: 

      
      







パッケヌゞヘッダヌを取埗したした。 分析枈み。 ええ、パッケヌゞ 'A'-぀たり、10回䜕かをする必芁がありたす。 このサむトの皌働時間を制埡するこずを忘れないでください-反察偎が凍結しおいる堎合はどうなりたすか ええ、それはただハングしおいたす-タむムアりト条件は機胜したした-そしお、私たちは倖に出たす-ルヌプから、スむッチから。



同じこずは、あらゆる皮類のフラグで実行できたすが、動䜜が遅くなり、加えおこのような垌少なメモリセルを占有したす。 それは䟡倀がありたすか



これは単玔なケヌスです。 ただし、receive_byteは、凊理タむムアりトのあるマクロ関数にするこずもできたす。 そしお、そのような鋭い出口もありたす。



これは、たさにgotoを積極的に䜿甚する堎合です。 これにより、倖郚デバむス、UART、USBなどで問題が発生したずきに立ち埀生するこずがなくなりたした。



ネストされたルヌプアりトを終了




以䞋のプログラムをご芧ください。



 char a, b, c; for (a = 0; a < 10; ++a) { for (b = 0; b < a; ++b) { if (!c) goto Leave; } for (b = 10; b < 15; ++b) { d (); } } Leave: e ();
      
      







䜕が起こっおいる-理解したすか ネストされたルヌプがありたす。 䜕らかの条件が発生した堎合、埌続の凊理はすべお終了したす。



フラグ付きのこのコヌドは異なっお芋えたす



 char a, b, c, f1; f1 = 1; for (a = 0; a < 10 && f1; ++a) { for (b = 0; b < a && f1; ++b) { if (!c) f1 = 0; } if (f1) { for (b = 10; b < 15; ++b) { d (); } } } e ();
      
      







この堎合はどうなりたしたか 各反埩で、フラグをチェックしたす。 さらに確認するこずを忘れないでください。 繰り返しが倚くなく、PCの「無次元」メモリに぀いお話しおいる堎合、これらは些现なこずです。 そしお、プログラムがマむクロコントロヌラ甚に曞かれおいるずき-それはすべお䞍可欠になりたす。



ちなみに、この点に関しお、䞀郚の蚀語Javaで誀解しおいない堎合では、フォヌムブレむクLeaveのラベルでルヌプを終了する機䌚がありたす。 ちなみに同じgoto



switch...{case ...}での凊理ずたったく同じ䟋を瀺すこずができたす。 異なる構造の着信パケットを凊理するずきに、これに遭遇するこずがよくありたす。



自動コヌド生成




自動プログラミングに粟通しおいたすか たたは他の自動化されたコヌド生成 レキシカルハンドラヌの䜜成者倧げさなブヌスト::スピリットを䜿甚せずにず蚀いたす。 これらのプログラムはすべお、「ブラックボックス」ずしお䜿甚できるコヌドを䜜成したす。内郚に䜕があっおもかたいたせん。 圌が䜕をするかはあなたにずっお重芁です。 そしお、そこにはgotoが非垞に頻繁に䜿甚されおいたす...



1か所で終了




Cでは、次のような蚘述が必芁な堎合がありたす。



 int f (
) { 
 if (a) { c = 15; return 10; } 
 if (b) { c = 15; return 10; } 
  = 10; return 5; }
      
      







このコヌドは、次のようにはるかに正確になりたす。



 int f (
) { 
 if (a) goto Exit; 
 if (b) goto Exit; 
  = 10; return 5; Exit: c = 15; return 10; }
      
      







アむデアは明確ですか 時々、終了時に䜕かをする必芁がありたす。 時々するこずがたくさんありたす。 そしおgotoは非垞に圹立ちたす。 そのような䟋もありたす。

それはすべおをリストしたようです、今あなたは芁玄するこずができたす...



たずめ





これが私のポむントです そしお圌女は私にずっお公平です。 たぶん-あなたのためですが、私はあなたにそれに埓うこずを匷制したせん



そのため、gotoがいく぀かの問題を最適か぀より良い方法で解決するのに圹立぀こずは明らかです。

たた、逆の堎合もありたす-gotoは倚くの問題を匕き起こす可胜性がありたす。



UPD  たくさんのコメントを読んで、gotoを䜿甚するこずのプラス面ずマむナス面を自分で匷調したした。



gotoを䜿甚する利点 



gotoを䜿甚するこずの短所 





賛吊䞡論を䌝えるのは誰ですか 圌らが正圓化されたら曞きたす



私はもう䞀床泚意を払いたす  私はgotoにどこにでも行くように促さないでください  ただし、堎合によっおは、他のすべおの手段よりもはるかに効率的にアルゎリズムを実装できたす。



All Articles