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

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

新規登録して質問してみよう
ただいま回答率
85.47%
標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

リファクタリング

リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

Q&A

解決済

4回答

654閲覧

8bitの2進数でタイムリーに0を検知するプログラムについて

changryu

総合スコア3

標準入力

標準入力(stdin)は、プログラムが標準的に用いるデータ入力元。リダイレクトしない限り、プログラムを起動した端末のキーボードが標準入力になります。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

標準出力

標準出力(stdout)は、プログラムが標準的に用いるデータ出力元。標準出力に書き込み要求を発行しすることにより、ディスプレイ装置にデータを表示することができます。UNIX系OSやC言語に実装されて普及した概念ですが、他のOSや言語も含めた総称としても使われます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

リファクタリング

リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

1グッド

0クリップ

投稿2023/11/02 05:31

編集2023/11/07 00:20

試してみたこと

いつもお世話になっております。
現在、C#にて8bit(8入力)のデジタル入力を検知するプログラムを作成しています。

TOP16というI/Oボードを使用しており、提供されたDLLからI/Oの入力状態を監視し(該当の入力があったらアクションを)させようとしています。

入力される値は以下のように10進数で取得することができます。(悩んで悩んで・・やっと分かりました)
例として一部を記載します。

無入力であれば 255 (11111111)
Input1が入れば 254(11111110)
Input2のみが入れば 253(11111101)
Input4のみが入れば 247(11110111)
Input1と3が入っていれば 250(11111010)

8入力なので2進数の1桁目がInput1で8桁目がInput8となります。

同時に複数のInputが入っていることも想定し、若いInput入力でbreak;をせず全Inputの状態を取得したいです。
実際に複数の入力があった場合、Input1が入っていることを条件にInput3はアクション可能というような使い方も想定しています。

そこでここ3日ほど、乏しい経験と無い頭をフル稼働し自分でプログラムを作ってみて一段落したと思ったのですが、

ふと。もっと良い書き方、例えば配列を使ったりする方法もあるのではないか?と思った次第です・・・

ここで別の手法を使って同じ結果を出せるようになれば一皮むける気がしているのですが、
苦渋の決断で経験豊富な先輩方の知恵をお借りできればと思い、こちらで相談させて頂くことにしました。

稚拙なプログラムで公開するのは恥ずかしいのですが私の考えたものを記載したいと思います。
どうか皆様のお知恵、アイデア、アドバイスを頂けませんでしょうか?
どうぞ宜しくお願い致します。

作成したソースコード

C#

1 //タイマーを使って入力を監視します。 2 private void timer1_Tick(object sender, EventArgs e) 3 { 4 //デジタルインプット(8bit)を取得 5 int xInput = Top16.GetInputs(handle); 6 7 //10進数を2進数に変換する 8 string binaryStr = Convert.ToString(xInput, 2); 9 10 //カウンターを初期化 11 int count = 0; 12 13 //binaryStrの文字列でカウントダウンをさせる 14 for (int i = binaryStr.Length - 1; i >= 0; i--) 15 { 16 char inputBinaryNum = binaryStr[i]; //binaryStrの[i]番目の文字列の切り出し 17 count++; 18 19 if (inputBinaryNum == '0') //inputBinaryNumが'0'だった時 20 { 21 if (count == 1) 22 { 23 //Input1が入ったときのアクション内容を書く 24 } 25 else if (count == 2) 26 { 27 //Input2が入ったときのアクション内容を書く 28 } 29 else if (count == 3) 30 { 31 //Input3が入ったときのアクション内容を書く 32 } 33 else if(count == 4) 34 { 35 //Input4が入ったときのアクション内容を書く 36 } 37 else if(count == 5) 38 { 39 //Input5が入ったときのアクション内容を書く 40 } 41 else if(count == 6) 42 { 43 //Input6が入ったときのアクション内容を書く 44 } 45 else if(count == 7) 46 { 47 //Input7が入ったときのアクション内容を書く 48 } 49 else if (count == 8) 50 { 51 //Input8が入ったときのアクション内容を書く 52 } 53 } 54 } 55 }
TN8001🎉を押しています

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

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

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

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

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

changryu

2023/11/05 23:16

ご指摘頂きました点について、自分のteratailの使い方の認識不足及び間違いがあるかと思います。改めて「質問するときのヒント」を読み直して問題点について修正させて頂きたいと思います。この度は、ご指摘ありがとうございました。
TN8001

2023/11/06 09:16

> 週末バタバタしており返信が遅くなりました 急な予定が入って回答の吟味ができないことはわかります。 ただそれを表明する(「返事が遅れます」等のコメント)くらいの時間はあるでしょう。 わたしがせっかちすぎですかね?w あんまり開くと自分で書いたことも忘れてしまうんですよね^^;
TN8001

2023/11/06 09:16

「調査したこと・試したことが記載されていない質問」 という指摘はわたしです。取り下げました。 修正依頼の内容としては間違っている(拡大解釈をしている)と思うのですが、回答やコメントしてから3日以上何のリアクションもない質問に一律付けています(事前に遅れることを書いてあればその期間以上開けます) 「望んだ回答でないと返事しない上その希望すら表明していない」といった解釈。ほかにいい内容があればいいのですが... 目的としては * (通知が行くので)最後の希望として返事の期待 * (稀にいる)回答への返事を質問の編集あるいは編集履歴タイトルでする人への対策(回答しただけでは編集の通知が来ない) * (せっかく丁寧に回答したのに返事がなく内心ムカついてはいるので)ささやかな抵抗としてw 当初は1週間としていたのですが、5日・3日と短縮してきました(4年1000回答以上してきた感触) (リニューアル後)通知が来ないことがよくあるので、(回答した未解決質問は)最低24時間に1回は実際に開いて確認するのですが面倒になってくるんですよね。 修正依頼後は(遅れてくるかもしれないが)通知に期待して確認をやめています。 ノーリアクションの方が多すぎるんですよね(体感1割弱) 難しすぎるのか望んだ内容でないのかわかりませんが、言ってもらわないと直しようもないのに... changryuさんには関係がないことを長々失礼しました。 --- 「こちらの質問が他のユーザーから「調査したこと・試したことが記載されていない質問」という指摘を受けました。」 「他のユーザー」となっている場合は、指摘者は(おそらく)ひとりです。 この場合上記注釈が見えるのは、質問者と指摘者のみになります(ログインせずに質問を見ると注釈が見えません) 「複数のユーザー」となっている場合は、全員に注釈が表示されています。
changryu

2023/11/06 23:12

TN8001様 コメントの追記ありがとうございます。 >>ただそれを表明する(「返事が遅れます」等のコメント)くらいの時間はあるでしょう。 この一文を見て確かにその通りだな。と思い反省しました。 回答してくださっている方は人間だということを少し忘れがちだった気がしました。 如何なる事情があったとしても、人として一言お礼と、遅れる旨を書くのが筋でした。 TN8001様他、ご回答を頂いた皆様 せっかく回答をしていただいたのにも関わらず、気分を害するような対応をしたことをお詫び致します。
changryu

2023/11/06 23:24

上記のことを昨夜、布団に入ってから考えていて、昨今身近なサービスがシステム化し便利になったことは嬉しいことですが 例えば、ヤフーオークションなんか四半世紀前なんて見ず知らずの相手にメールアドレスを晒していちいちメールを送り合っていたのが、今ではやり取りのオペレーションがほぼ確立し、商品の善し悪しは大事ですが、それ以外はほぼシステム間のやりとりだけ(なんならコメントもテンプレ)で済み便利になったと思います。 一方で、人、AI関わらずオンラインでのやり取りに慣れてきてしまったのか、私だけかも知れませんがモニターの向こう側に人が居ることを忘れだしている気がしました。 若者にネットリテラシーなんかを説教する前に、自分の意識を変えないと、もしかしたら今どきの若者の方が現在の世界(ネット含め)をもっと上手に使っている気がし、まだまだ修行が足りないな。と眠りについた次第です。 何の話やらw
guest

回答4

0

ベストアンサー

実際に複数の入力があった場合、Input1が入っていることを条件にInput3はアクション可能というような使い方も想定しています。

そういう複合条件みたいなのがどれだけあるのかわかりませんが,とりあえず switch で良いのでは? という気がします.
(むしろそれだと困るような話があるならば質問で明言すべきでしょう)

C#

1//入力1と3だけが成されているときの値. 2//プログラムの意味的に「それが何の入力に相当するのか」という話があると思うので, 3//なんかそういう名前を付けておけば良いのでは? と思う. 4const int CatNapInput = 0b1111_1010; 5 6//こっちは入力3だけが成されているときの値. 7const int WildMeowInput = 0b1111_1011; 8 9... 10 11//入力状態に応じた処理 12switch( xinput ) 13{ 14case CatNapInput: CatNap(); break; 15case WildMeowInput: WildMeow(); break; 16default: break; 17}

投稿2023/11/06 02:03

編集2023/11/06 02:04
fana

総合スコア11658

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

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

changryu

2023/11/07 00:15

fana様 この度は追加でのアドバイスをしていただき感謝致します。ありがとうございます。 >>そういう複合条件みたいなのがどれだけあるのかわかりませんが,とりあえず switch で良いのでは? という気がします. >>(むしろそれだと困るような話があるならば質問で明言すべきでしょう) すみません。ちゃんとどの入力入っているとき(条件)、何をするのかを整理出来ていないことに気づきました。 例えば Input1:安全センサー Input2:非常停止 Input3:実行ボタン だとしたときに、 Input3はInput1がONのときに実行可 Input1がOFFのときはInput3は入力入っても無視される などなど 最初にちゃんと条件が分かっていれば(設計ができていれば)、教えて頂いたswitch文はスマートな気がしました。 意味合いはあってますでしょうか? その前にコメントしていただいたビット演算も試してみたいので、調べる時間、試すお時間を頂けたらと思います。 別の方のところにも記載しましたが、別の業務との脳の切り替えが出来ないもので・・・本当にすみません
fana

2023/11/07 01:18

他の回答でのコメント欄でも触れられていますが, いくつかの考えられる方法があるときにそのどれが適しているのか? というのは{やること,状況,背景事情,あなたの好み,etc}に多分に依存するものなので,いろいろと比較検討する必要があるでしょう. (回答を書いている側にはそこらへんの実情が正確にはわからないので,いろいろと列挙しているにすぎない) そこに時間を要するのは当たり前のことであり,本来わざわざ断りを入れるようなことでもないと思います. 「質問したならば即座に解決しなければならない!」みたいな謎ルールがあるわけでもないのですし. (……とはいえ,あまりにも放置が蔓延している場であるがために,「時間がかかりそう」とか明示的に述べておく必要性が生じてしまっている気はします.)
fana

2023/11/07 01:48 編集

> 意味合いはあってますでしょうか? * 条件が完全に定まっている(固定である.実行中に動的に変化しない)し, * 結局そんなにパターンが多いわけでもないし(実際上,数十パターンとかの処理があるわけじゃないですよね,きっと) * 入力のON/OFFに依存する処理が複数個所にあるわけではない …みたいな場合,switch で xInput の値そのもので処理分岐を書くのが{手っ取り早い,それで十分である,わかりやすい,etc}な可能性もあるよね,という話です. 逆に言えば, 動作中に入力に応じて行うべき処理内容が変わってくるとか,Input1のON/OFF状況を他所でも判断せねばならないとか,そういう場合には別の方法を考えた方が良いかもしれません.
changryu

2023/12/15 00:26

この度はお世話になりました。回答をいただき誠にありがとうございました。 それと回答に時間がかかり申し訳ございませんでした。 今回ベストアンサーとさせて頂いた理由として、以下の内容があります。 1.可読性の良さ 2.今回の用途に合っている 3.限られた時間で実装できたこと 結局は全て自分の知識レベルによるものですが、修正などで時間が経ってから見直したときに分からないようでは問題があるので、現在の自分で理解して、使いこなし、最初に考えた案より改善されたからです。 ひとまず今回はここをゴールとしますが、引き続き電気設計も含めて見直し、またプログラミング技術向上にも努め、本当の意味での最適化を目指したいと思います。 改めてお礼申し上げます。ありがとうございました。
guest

0

ここ長いこと、C系のcode書いてないので考え方だけですが。ポインタ扱いの表現間違えてるかも、なのでそこ注意してください。

長さ256の 「functionへのポインタ」の配列を用意します。
配列[0] = *全部onの時の処理関数
配列[1] = *Input1以外がonの時の処理関数


配列[254] = *input2のみonの時の処理関数
配列[255] = *inout1のみonの時の処理関数
( 装置の性質からしてありえない入力の組み合わせが有ったらそこは省略可能)

でもって *配列[入力の値] を実行

投稿2023/11/03 03:33

winterboum

総合スコア23349

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

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

changryu

2023/11/05 23:21

winterboum様 早速の回答に感謝致します。週末バタバタしており返信が遅くなりましたことをお許しください。 回答を読ませて頂き、自分がなんとなく出来るのではないかという事のヒントにすごくなりました。 これをどう実装するのか?ここから成長できる気がします。 これをヒントに自分でもどう解決するか検討してみますので、少しお時間いただければと思います。
winterboum

2023/11/06 01:23

ポインタ ってややこしいので楽しんでください。 関数へのポインタは変数への よりも楽しめるかな。 ポインタ使いこなせれば2ランクアップです
fana

2023/11/06 02:05 編集

質問は C# の話ですよね? (あえて別言語な雰囲気で回答せずとも良いのでは…?) それはそれとして, 本当にそんな膨大なパターン毎にやることが違うというような話であれば,そのテーブルを用意するのと巨大 switch 書くのとで労力変わらないような気もしますね. (まぁパターン毎の処理が動的に変わる! とか,同じような分岐箇所がたくさんあるとかなってくるならば別ですが) → というわけで,「switchでよくね? (逆に何がだめなん?)」っていう回答を別途作っておきました.
winterboum

2023/11/06 02:25

書く労力は変わらんですね。caseがまばらだとswitchの方が見通し良いかも。 色々な書き方のなかで、こういうのもありますよ、という例としてだしました。 で、 実行速度が早くなります。 というか switchだとcaseの最初と最後ではcaseの評価回数分だけ実行着手が遅れますが配列だとそういう差は出てきません。(caseの評価にどんだけ時間がかかるんだ てのはありますが。) あと、caseの順番を吟味しないとまずいのでその負荷も減るかな。 1の場合と、1と3の場合と、1と3と5の場合があるとき、10101010 なパターンのときはどれを選ぶの?というのを考えて順番を整えないと。
fana

2023/11/06 09:58 編集

> switchだとcaseの最初と最後ではcaseの評価回数分だけ実行着手が遅れますが もうちょっと効率がよい形にコンパイラ様が頑張ってくれるのではないか(2分木的にとか),と根拠なく期待しています(実際どうなるのか知りません). > caseの順番を吟味 順番とは,fall through を想定しているのでしょうか? そこは割り切って{1の場合,1と3の場合,1と3と5の場合,…}は全て独立した case で個別に実装する(最大で256分岐)ということにすれば,(caseの順番には意味がなくなるので)配列案と差は無いかと.
winterboum

2023/11/06 13:36

え!? 私の古い記憶では、最初にマッチするcaseを実行して終わってしまうのですが。違いましたっけ? switch flag のflagの値が 1 かつ 12 なんてことはありえないから、全てのcaseを舐める必要ないですよね。 fall through は想定してません。というか、それを使ってcodeを短くしたり可読性上がるなら使ってもよいですが。 2分木的に は無理でしょうね、場合が樹枝状になるわけでは無いから。 私がコンパイラなら 分岐先のアドレスを並べておいて(配列だ!)switchの値をレジスタに入れ、間接参照JUMPですね。 あと、可読性がちがうな。 switchだと文脈の中に置きますよね、ですので そこに256〜512行の固まりが入る。 配列の場合は、配列の定義と関数の定義は文脈の流れと関係ない所におけますから、1行で済むのでcode読むのを邪魔しません。配列の命名センス次第ですが。 場合が256もなく、1画面に収まるなら switchの方が読みやすいかな、と思います。
winterboum

2023/11/07 00:18 編集

そか、 C#のコンパイラが >分岐先のアドレスを並べておいてswitchの値をレジスタに入れ、間接参照JUMP させるなら、関数のポインタへの配列 使うのと実質同じですね。caseの記述順には影響しない。 すると可読性だけの違いか
fana

2023/11/07 01:35

> 1画面に収まるなら 実際上,そういう判断基準みたいなのがありますね. 自分で switch を挙げておいてなんですが,switch-case って無駄に行数食いがちな形してるところがイマイチ好きじゃない感. case XXX: 処理; break; case YYY: 処理; break; という感じで各 case を1行に書いても見難くないようなやつじゃないと,ちょっとつらい. 「処理;」の前後に改行入れて各caseが3行になるとか,各 case の間に空行入れたいとか,処理のところを {} で囲んでブロックにしたいとか言い始めると,大したことしてないくせにやたらとスペースだけ食う塊が爆誕するので.
winterboum

2023/11/07 02:32

ですね。 で、実を言うと私 if elsif、、、もswitch case も避けたい方なんです。 if が来ると 「これは例外処理か単なる場合分けか」とちょっと緊張して文脈からそれてしまう、ってのもあるのですが、両者とも 全ての場合が網羅されているか 欠けているのは 無いからなのか見落としなのか を考えなければならなくなって。 場合分けを他で定義できれば、その書き方の工夫で場合分けの網羅性の確認がしやすいので。
changryu

2023/12/15 00:31

この度はお世話になりました。回答をいただき誠にありがとうございました。 それと回答に時間がかかり申し訳ございませんでした。 ポインタ。なんとなく良さそうな気がしたのですが、今の自分にはまだ早かったようです。 こちらの内容も検討していると1年位平気で時間が経ってしまいそうなのでこちらの質問についてはクローズとさせて頂きたいと思います。 どうぞご理解のほど宜しくお願い致します。 いつかは2ランクアップを目指して頑張りたいと思います。 改めてお礼を申し上げます。ありがとうございました。
guest

0

同時に複数のInputが入っていることも想定し、若いInput入力でbreak;をせず全Inputの状態を取得したいです。

現状上位桁が0の時、取り逃してしまいますね。

Input1が入っていることを条件にInput3はアクション可能というような使い方も想定しています。

enumを使うと判定をわかりやすく書けます(.NET Frameworkの場合は、HasFlagは遅いで有名なので注意してください)
FlagsAttribute クラス (System) | Microsoft Learn
Enum.HasFlag(Enum) メソッド (System) | Microsoft Learn

ふと。もっと良い書き方、例えば配列を使ったりする方法もあるのではないか?と思った次第です

例えばbinaryStr[i]のようにインデクサをお使いなので、配列を使っているのとほぼ同じことかと思います。
イヤなのはその後の、if羅列のほうですよね。

icountを使って処理を共通化できるなら、if羅列を消すことができるでしょう。


前回の質問の続きでしょうから寄せました。
WindowsフォームアプリケーションにてDllを使いたい

cs

1using System; 2using System.Diagnostics; 3using System.Drawing; 4using System.Linq; 5using System.Windows.Forms; 6 7namespace Qvcazys1ngsxj93 8{ 9 public partial class Form1 : Form 10 { 11 private DataGridView dataGridView1; 12 private Timer timer1; 13 private object handle; 14 15 public Form1() 16 { 17 InitializeComponent(); 18 19 dataGridView1 = new DataGridView 20 { 21 AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill, 22 Dock = DockStyle.Fill, 23 Parent = this, 24 }; 25 26 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "Board", }); 27 28 for (int i = 1; i <= 8; i++) 29 dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = $"in {i}", }); 30 31 dataGridView1.Rows.Add("hoge"); 32 dataGridView1.Rows.Add("fuga"); 33 dataGridView1.Rows.Add("piyo"); 34 35 36 timer1 = new Timer { Interval = 1000, }; 37 timer1.Tick += Timer1_Tick; 38 timer1.Start(); 39 } 40 41 private void Timer1_Tick(object sender, EventArgs e) 42 { 43 int xInput = Top16.GetInputs(handle); 44 45 // 0埋めで8桁取得(上位桁の0を取り逃さないように) 46 string binaryStr = Convert.ToString(xInput, 2).PadLeft(8, '0'); 47 48 // 確認用(出力ウィンドウ) 49 Debug.Write($"\n{binaryStr}"); 50 Debug.Write($" →逆順 {string.Join("", binaryStr.Reverse())}"); 51 Debug.WriteLine($" →反転 {string.Join("", binaryStr.Reverse().Select(x => x == '0' ? '1' : '0'))}"); 52 53 54 // hoge行の処理 55 int count = 0; 56 foreach (char inputBinaryNum in binaryStr.Reverse()) // 右が1なのでひっくり返す 57 { 58 count++; 59 if (inputBinaryNum == '0') // 0だったら入力有 60 { 61 Debug.Write($"Input{count}, "); 62 dataGridView1.Rows[0].Cells[count].Style.BackColor = Color.Blue; 63 } 64 else 65 { 66 dataGridView1.Rows[0].Cells[count].Style.BackColor = Color.White; 67 } 68 } 69 Debug.WriteLine(""); 70 71 72 // fuga行の処理 73 Flag flag = (Flag)~xInput; // 各ビット反転してenumにキャスト 74 Debug.WriteLine(flag); 75 76 var row1 = dataGridView1.Rows[1]; 77 78 // ループにしずらいのでこういうのは向かないかなw 79 if (flag.HasFlag(Flag.Input1)) row1.Cells[1].Style.BackColor = Color.Blue; 80 else row1.Cells[1].Style.BackColor = Color.White; 81 // 以下同じ意味 82 row1.Cells[2].Style.BackColor = flag.HasFlag(Flag.Input2) ? Color.Blue : Color.White; 83 row1.Cells[3].Style.BackColor = flag.HasFlag(Flag.Input3) ? Color.Blue : Color.White; 84 row1.Cells[4].Style.BackColor = flag.HasFlag(Flag.Input4) ? Color.Blue : Color.White; 85 row1.Cells[5].Style.BackColor = flag.HasFlag(Flag.Input5) ? Color.Blue : Color.White; 86 row1.Cells[6].Style.BackColor = flag.HasFlag(Flag.Input6) ? Color.Blue : Color.White; 87 row1.Cells[7].Style.BackColor = flag.HasFlag(Flag.Input7) ? Color.Blue : Color.White; 88 row1.Cells[8].Style.BackColor = flag.HasFlag(Flag.Input8) ? Color.Blue : Color.White; 89 90 91 // 複数条件はわかりやすい 92 //if (flag.HasFlag(Flag.Input1) && flag.HasFlag(Flag.Input3)) row.Cells[3].Style.BackColor = Color.Red; 93 // ↑↓意味は同じ 94 if (flag.HasFlag(Flag.Input1 | Flag.Input3)) row1.Cells[3].Style.BackColor = Color.Red; 95 96 // 意味のある名前を付けたければこうでもいい 97 //if (flag.HasFlag(Flag.Input1_and_3)) row.Cells[3].Style.BackColor = Color.Red; 98 99 100 //// piyo行の処理 101 //var row2 = dataGridView1.Rows[2]; 102 103 //for (var i = 1; i <= 8; i++) 104 //{ 105 // row2.Cells[i].Style.BackColor = Color.White; 106 107 // // インデックス(C# 8.0以上) 108 // // [インデックス/範囲処理 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/data/dataranges/) 109 // if (binaryStr[^i] == '0') row2.Cells[i].Style.BackColor = Color.Blue; 110 //} 111 112 //// リスト パターン(C# 11以上) 113 //// [パターン マッチング - C# によるプログラミング入門 | ++C++; // 未確認飛行 C](https://ufcpp.net/study/csharp/datatype/patterns/?p=2#list) 114 //row2.Cells[3].Style.BackColor = binaryStr switch 115 //{ 116 // // Input1・Input3の入力があり、Input8の入力がなければ。。。 117 // ['1', .., '0', _, '0'] => Color.Green, 118 119 // // Input1・Input3(・Input8)の入力があれば。。。 120 // // ↑に当てはまらない時なのでここに入るのはInput8もONなことになる 121 // [.., '0', _, '0'] => Color.Red, 122 123 // [.., '0', _, _] => Color.Blue, // Input3の入力があれば。。。 124 125 // _ => Color.White, // default 126 //}; 127 128 //// ifを並べたほうがわかりやすい場合も? 129 ////if (binaryStr is [.., '0', _, '0']) row2.Cells[3].Style.BackColor = Color.Red; 130 ////if (binaryStr is ['1', .., '0', _, '0']) row2.Cells[3].Style.BackColor = Color.Green; 131 } 132 133 [Flags] 134 enum Flag : byte 135 { 136 None = 0, 137 Input1 = 1, 138 //Input1 = 0b0000_0001, // こうのほうがわかりやすければそれでもいい 139 //Input1 = 0b1111_1110, // こうはダメ! 140 Input2 = 2, 141 Input3 = 4, 142 Input4 = 8, 143 Input5 = 16, 144 Input6 = 32, 145 Input7 = 64, 146 Input8 = 128, 147 148 Input1_and_3 = Input1 | Input3, // 複数条件に意味のある名前を付けたければ 149 } 150 151 private class Top16 // 雑いw 152 { 153 private static Random random = new Random(); 154 public static int GetInputs(object handle) => random.Next(256); 155 } 156 } 157}

アプリ動画

投稿2023/11/02 13:58

編集2023/12/15 09:59
TN8001

総合スコア9326

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

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

TN8001

2023/11/02 13:58

結局「ビット演算する」がベストな気もしますが...^^;
changryu

2023/11/05 23:53

TN8001様 早々にご回答頂いていたのにも関わらず、別の仕事が立て込んでおり返信が遅くなり大変申し訳ございません。 この度はご回答ありがとうございました。 ご回答を見させて頂き、第一に前回の質問との関連まで読み取って頂き本当に感謝致します。 その通りでございまして、前回まではTop16の使い方や特性を探っておりまして、実際にTop16で装置を制御しようとした際に、装置のそれぞれのフェーズ(状況)でInput/Outputを使う必要があり(この辺もクラスで部品化できればいいのですが・・・)、もうちょっとちゃんと考えなければいけないことに気付いた次第です。 次に、ご指摘の『イヤなのはその後の、if羅列のほうですよね。』 ほんとそうなんです。感覚的に美しくない(ダサい)ということは分かっているのですが、おそらく"最低限"やりたい事はできるかも知れないが、最高(最適)ではない気がしておりまして・・・言語化できない知識量ですみません。 最後に自分の今持っている知識を遥かに上回ったアドバイスをして頂いたことと同時に、やはりもっと違うやり方はあるんだな!(当たり前かw)ということを知ることができて今回思い切って質問して良かったと思いました。 私自身、だいぶ昔に大学でちょっとプログラミングをかじっただけで、リアルでは先輩プログラマーがいないため、こんな時に先輩プログラマーがいたらどんなアドバイスされるのかなーと想像して今回質問させて頂いたのもあり、感動しました。 せっかくなので今回頂いたアドバイスを元にもう少し自分でも考えて試して見たいと思います。 少しお時間を頂くことになるかと思いますが、もう少しお時間をいただければと思います。
TN8001

2023/11/06 09:22 編集

> 現状上位桁が0の時、取り逃してしまいますね。 まずこの「バグ」の指摘が第一義なのですが、そこは通じてますでしょうか。 例えば入力が51(0011_0011)の時は、Input3,Input4,Input7,Input8です。 Convert.ToString(xInput, 2) ですと、文字列は"110011"になりInput7,Input8を取り逃します。 どの数値も確実に8桁確保するため、回答では .PadLeft(8, '0') としました。 問題点は見た瞬間わかりましたが、実際どうするのかは(わたしも)都度ggっています。 [c# 2進数 ゼロ埋め - Google 検索](https://www.google.co.jp/search?q=c%23+2%E9%80%B2%E6%95%B0+%E3%82%BC%E3%83%AD%E5%9F%8B%E3%82%81) > 次に、ご指摘の『イヤなのはその後の、if羅列のほうですよね。』 > 最後に自分の今持っている知識を遥かに上回ったアドバイスをして頂いた できるだけ平易に書いたつもりですが、わかりにくい点があるなら遠慮なく聞いてください。 foreachに直したのが分かりにくいですか?(forに戻しても動作は同じです) //Input1が入ったときのアクション内容を書く の内容を前回質問から推測して、↓としましたがこれ自体はわかりますよね? dataGridView1.Rows[0].Cells[count].Style.BackColor = Color.Blue; それとも全然違う内容ということでしょうか。 実行内容がてんでばらばらとなると、どこかしらに値と処理内容は書くことにはなるでしょう(その書き方は処理内容や個人の好み等でいろいろありえます) >> Input1が入っていることを条件にInput3はアクション可能というような使い方 のわかりやすい判定としてFlags enumをご紹介しました。 機器からの入力は250(1111_1010)だそうですが、プログラムでは扱いにくいのでビットを反転して5(0000_0101)として扱います(「~(チルダ)」のところ) if (flag.HasFlag(Flag.Input1) && flag.HasFlag(Flag.Input3)) enumを使用して「どちらもオンの時」という条件が分かりやすく書けました。 ただし本来はORを取って(「|(パイプ)」のところ)こう書いたほうがいいです(ビット演算を説明したくなかったので^^; if (flag.HasFlag(Flag.Input1 | Flag.Input3)) 詳しくは以下や以下の中で出てきたキーワードでさらにggってください。 [ビットごとの演算子とシフト演算子 - 整数型の個々のビットに対して、ブール演算 (AND、NOT、OR、XOR) とシフト演算を実行します - C# | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators) > "最低限"やりたい事はできるかも知れないが、最高(最適)ではない気がして やりたいことができるのがまず第一で美しさは2の次ですよね(特にお仕事なら) わたしは趣味グラマなので「最高」のものができなかったら、「しばらく寝かしておく」ようなことができますがw 「最高のものができた」と思っても、1年後に見たら書き直したくなるというのもよくある話です^^; > せっかくなので今回頂いたアドバイスを元にもう少し自分でも考えて試して見たいと思います。 > 少しお時間を頂くことになるかと思いますが、もう少しお時間をいただければと思います。 はい。別に1週間でも1か月でも構いませんが、個人的には1か月以内くらいには(自己解決でも誰かのBAでもいいですが)何らかの結論が欲しいですね。 解決後でもコメントいただければ返信します(内容によっては新たな質問として建てるよう誘導することもあります)
changryu

2023/11/06 23:36

フォロー含め、ご配慮に感謝致します。 私事ですが、零細企業の雇われ人の為、装置の設計から制御、納品、サポートまでしている関係で、また現在別の装置の設計フェーズに入っており、私の能力では設計業務と制御(プログラミング)を同時期に考えることができな為、お時間を下さい。 それは時間的な問題ですが、たぶんプログラミングが好きだったりするのか、または性格なのか経験的な問題なのか、理解していないこと、分かっていないことに対して「分かりました」と言えない性分でして、ちゃんと理解したい、使いこなしたい、という意識も働いて片手間でやりたくない意識も働いています。 また来週末にでもゆっくりと読ませて頂き、試させて頂きたいと思います。きっとまた躓くと思いますwその際は・・・ そんな訳でまずはお時間を頂いたこと、アドバイスをして頂いたことに感謝致します。ありがとうございました。
TN8001

2023/11/07 00:22

はい。わたし達(回答者)は誰も急いでいませんのでごゆっくりどうぞ^^
changryu

2023/12/15 00:47

この度はお世話になりました。回答をいただき誠にありがとうございました。 それと回答に時間がかかり申し訳ございませんでした。 僅かなスキマ時間にFlags enumについて調べていたりしたのですが、 「あ、そうか!このソースそのままコピペして試してみればいいんだ」と2週間位前に気づき(遅っ・・・)、試してみたのですが、 37行目、41行目で[インデックスが範囲を超えています。負でない値で、コレクションのサイズよりも小さくなければなりません。] というエラーが出て、調べようとしてまた時間が経ってしまいました。 順番代わりますが、 > 現状上位桁が0の時、取り逃してしまいますね。 そうですね。気づかせていただきありがとうございます。 それで話は代わりますが、今回は大変申し訳ございませんがfana様の回答にベストアンサーをさせていただきました。 気持ち的にはTN8001様の案のFlags enumとfana様の案のSwitchを組み合わせるとどうなんだろう?と思ったのですが、もう少し時間がかかりそうなのでSwitch案を今回のゴールとさせて頂きました。すみません。 おそらくもう少し時間がかかると思いますが、上記のエラーの件引き続き調べてみたいと思います。
TN8001

2023/12/15 10:03 編集

> というエラーが出て、調べようとしてまた時間が経ってしまいました。 すぐ言ってくれたらよかったのに。。w 画像を付けたのでわかるかなと省略してしまいましたが、デザイナでDataGridViewと9列分のDataGridViewTextBoxColumn(あとTimer)を追加済みという想定でした。すいません。 コピペだけで実行できる状態に回答コードを更新しました^^ > 気持ち的にはTN8001様の案のFlags enumとfana様の案のSwitchを組み合わせるとどうなんだろう?と思った switchは結局 if() {} else if() {} else{} と同義ですからひとつしか選べません。 if() {} if() {} if() {} と同じ意味でないことに注意が必要です(それはわかっていてこの質問ということでしょうけど^^; 条件が複雑なら複数のifやswitchが出てくるのは仕方がないでしょう。 switchで地味に困るのは、任意の値でいい部分があるときですね。 パターンマッチング等を使えれば、場合によってはわかりやすく書けるかもしれません。 .NET Frameworkでも使えないこともないですがいくつか準備が必要になります(ので回答コードはとりあえずコメント化しています)
guest

0

C#

1for(int i=1;i<0x100;i<<1){ 2 if(0==(xinput&i)){ なんやかや } 3}

でどうでしょう

投稿2023/11/02 05:45

y_waiwai

総合スコア87778

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

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

fana

2023/11/02 06:04

これだけだとすぐに分からない場合には 「ビット演算」とか「ビットフラグ」みたいな言葉を検索してみると良いかも.
changryu

2023/11/06 00:07

y_waiwai様 funa様 早々にご回答頂いていたのにも関わらず、別の仕事が立て込んでおり返信が遅くなり大変申し訳ございません。 この度はアドバイス頂きましてありがとうございました。 知識がなく大変恐縮なのですが、for文が何をしているのか分からず、検索してみたらfuna様の書かれていたビット演算がひっかかったのですが、今回の件についてはこう使うのが正解な気がしてきました。 ちょっとまだ理解しきれていないので、ちょっと自分でも試して血肉にしたいと思います。 理解するまでにもう少し時間が必要そうなので、先にお礼をさせて頂きます。
changryu

2023/12/15 00:48

この度はお世話になりました。回答をいただき誠にありがとうございました。 それと回答に時間がかかり申し訳ございませんでした。 もう少し勉強して出直して来ます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問