- ベストアンサー
C言語の条件式についての問題
- C言語でプログラムを作成しています。条件式「==」がうまく機能せず、問題が生じています。
- 条件式「==」を使用すると、特定の条件がスルーされる問題が発生しています。
- 非常に基礎的なことかもしれませんが、なぜ条件式「==」がうまく機能しないのかを教えていただきたいです。
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
>モータのエンコーダ値 これが実際どういう値かは分かりませんが、 何らかの測定値なら誤差を含んでいるのでは? 実際の配列の値を確認すれば分かると思いますが、 a[i] == a[i-1]となるデータは存在しますか? (特に実数の場合は==にはなりにくい) 例えば、下記のようにある程度誤差を考慮した プログラムにする必要があるのではないでしょうか? 整数の場合(誤差+-10) if(abs(a[i] - a[i-1]) < 10) 条件2; 実数の場合(誤差+-1.0) if(fabs(a[i] - a[i-1]) < 1.0) 条件2; 誤差は適当に調整してください。
その他の回答 (8)
- crew21
- ベストアンサー率26% (58/222)
おいおい全然「非常に一般的」じゃないよ。 「条件n」って書いてあるとこは、実際には式じゃないの? 式はどんなに短くてもカッコ{}でくくろうよ。 これでコンパイルは通ると思うけど、意味的に、 3行目のif文が次のelseと対応するものなのか、 実は1行目のif文の中に含まれるif文であって、elseに対応するのは1行目のif文なのかわからない(わかりにくい)よ。 こんな書き方のクセつけはダメだよ。マジで。
- jacta
- ベストアンサー率26% (845/3158)
> 原因を書くとながくなってしまいますので、 長くても、原因を書かないと、これを見ているほかの人にとってはまったく無益なものになってしまいます。 似たような状況で困っている人もいるはずですから、自己解決した場合には、可能な限り経緯を詳しく書いてください。
- jacta
- ベストアンサー率26% (845/3158)
> >では、if (a[i] == 1000) とした場合はどうなりますか? > この場合、プログラムは条件に関係なく実行され続けています。 すでに提示されている情報だけからは、コンパイラのバグの可能性があります。 コンパイル結果を調べてみることをお勧めします。 > なお、aの型ですが、longで定義しています。volatile修飾子は付いていません。 正確な型を教えてください。配列型ではなく、long型なのですか? だとすると、iが配列またはポインタ型なのでしょうか?
お礼
参考になるアドバイスありがとうございました。 再度、プログラム、出力値などを確認してなんとかなりました。 原因を書くとながくなってしまいますので、お礼のみとさせていただきます。ありがとうございました。
- jacta
- ベストアンサー率26% (845/3158)
問題をひとつずつ潰していくと同時に、状況を把握することにしましょう。 > if(a[i]>=1000) 条件2; > > というように、配列a(エンコーダ値)が1000以上になったら条件2を実行として確認しました。 では、if (a[i] == 1000) とした場合はどうなりますか? aの型を教えてください。浮動小数点数の可能性は低いと思いますが、volatile修飾子は付いていますか?
補足
>では、if (a[i] == 1000) とした場合はどうなりますか? この場合、プログラムは条件に関係なく実行され続けています。 なお、aの型ですが、longで定義しています。volatile修飾子は付いていません。 宜しくお願いします。
- Wakkey-san
- ベストアンサー率44% (85/191)
#1です。ハードウェアとの連携でしたか…。 すでに他の皆さんが書かれているとおり、実値をハード側が意図する値を返していないのか、 あるいはコーディングミスで a[i]==a[i-1] が成立していないのか確認する必要がありますね。 Windowsで動かしているのであれば、OutputDebugStringが使えばexeを直接走らせても外部で 情報を取得できます。 OutputDebugString http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdebug/html/_win32_OutputDebugString.asp 「デバッグモニタツール」(OutputDebugStringの内容をリアルタイムに表示) http://www.vector.co.jp/soft/dl/winnt/prog/se278126.html if(time>=2000) の中で char str[256]; // 文字列バッファ sprintf( str, "i=%d, a[i]=%d, a[i-1]=%d", i, a[i], a[i-1] ); // デバッグ情報文字列 if( (2000 <= time)&&(3000 <= time) ) OutputDebugString( str ); // リミッター とすればいいと思います。
お礼
参考になるアドバイスありがとうございました。 再度、プログラム、出力値などを確認してなんとかなりました。 原因を書くとながくなってしまいますので、お礼のみとさせていただきます。ありがとうございました。
- zwi
- ベストアンサー率56% (730/1282)
>if(a[i] == a[i-1]) プログラム的には正しく見えますので、データ的に間違いがあると思います。 1.配列aの格納とカウントが間違っている。iの使い方やカウントアップ忘れなど。 2.そもそも同じ値になることは無い。ロータリーエンコーダのパルスカウントに失敗している。 などなどが考えられます。 まず、条件を満たすデータがこの条件文に来ていることを確認してください。
お礼
参考になるアドバイスありがとうございました。 再度、プログラム、出力値などを確認してなんとかなりました。 原因を書くとながくなってしまいますので、お礼のみとさせていただきます。ありがとうございました。
- asuncion
- ベストアンサー率33% (2127/6289)
> if(a[i] == a[i-1]) 条件2; // エンコーダ値が変化しない、つまりモータが外力によって停止したら、現在の位置で待機 デバッグの基本技として、 このif文の直前で、iとa[i]とa[i-1]を出力してみてはいかがでしょうか。
お礼
参考になるアドバイスありがとうございました。 再度、プログラム、出力値などを確認してなんとかなりました。 原因を書くとながくなってしまいますので、お礼のみとさせていただきます。ありがとうございました。
- Wakkey-san
- ベストアンサー率44% (85/191)
具体的に、どんな処理結果を求めているのかがわかりません。 ご質問の内容は、他人から見れば timeが2000以上であれば「条件1」を実行し、 その次に配列aのi番目の値が配列aの(i-1)番目と等しければ条件2を実行。 timeが2000未満であるなら条件3を実行。 という内容のプログラムにしか見えないはずです。 省略されている部分でaのi番目の値が配列aの(i-1)番目の値は等しくなるような処理が入っていますか? iは1から始まる値ですか?(0から始まるような値であればメモリのとんでもないところを参照することになりますが)
補足
非常におおざっぱな記述でした。もう少し詳しく書きます。 現在扱っているプログラムはモータの駆動プログラムです。 配列aにはモータのエンコーダ値が入りますので、モータが駆動すると同時に配列aのエンコーダ値は増え続けます。このプログラムはエンコーダ値でモータが駆動しているかを判断し、エンコーダ値が変化がない、つまり直前の値と変わっていない場合は、条件2を実行するというものです。 もちろん、a[0]には初期値を与え、iは1からスタートします。 さきほどの内容にコメントを付け加えます。 if(time>=2000){ 条件1; // モータ駆動の指令 if(a[i] == a[i-1]) 条件2; // エンコーダ値が変化しない、つまりモータが外力によって停止したら、現在の位置で待機 }else{ 条件3; // timeが2000以下の場合、現在の位置で待機 } となります。 なお、「>=」で試したと書きましたが、 if(a[i]>=1000) 条件2; というように、配列a(エンコーダ値)が1000以上になったら条件2を実行として確認しました。その場合は条件文のとおり1000以上になった時点で条件2を実行することができています。
お礼
参考になるアドバイスありがとうございました。 再度、プログラム、出力値などを確認してなんとかなりました。 原因を書くとながくなってしまいますので、お礼のみとさせていただきます。ありがとうございました。