<C言語入門/車載ソフト> 演算子
こんにちは、レオハルです。
※通常のC言語解説とは、異なり組込み・車載ソフトに特化した記載があります。ご注意ください。
演算子とは
四則演算や論理演算などの各種演算を行う際に利用される記号のことです。
演算子一覧
分類 | 記号 | 記述例 | 説明 |
---|---|---|---|
算術演算子 | + | a + b | 加算。aにbを加える。 |
- | a - b | 減算。aからbを引く。 | |
* | a * b | 乗算。aにbをかける。 | |
/ | a / b | 除算。aをbで割る。 | |
% | a % b | 剰余算。aをbで割った余り。 | |
比較演算子 | == | a == b | イコール。aとbは等しい。 |
!= | a != b | ノットイコール。aとbは異なる。 | |
> | a > b | 大なり。aはより大きい。 | |
>= | a >= b | 大なりイコール。aはb以上。 | |
< | a < b | 小なり。aはbより小さい。 | |
<= | a <= b | 小なりイコール。aはb以下。 | |
ビット演算子 | & | a&b | AND。aとbの論理積。 |
| | a|b | OR。aとbの論理和。 | |
^ | a^b | XOR。aとbの排他的論理和。 | |
~ | ~a | NOT。0/1を反転させる。 | |
>> | a>>b | 右シフト。aを右へbビットシフト。 | |
<< | a< | 左シフト。aを左へbビットシフト。 | |
代入演算子 | = | a=b | 代入。 |
+= | a+=b | 加算代入。aにbを加え代入。 | |
-= | a-=b | 減算代入。aからbを引いて代入。 | |
*= | a*=b | 積算代入。aにbをかけて代入。 | |
/= | a/=b | 除算代入。aをbで割って代入。 | |
%= | a%=b | 剰余算代入。aをbで割った余りを代入。 | |
&= | a&=b | 論理積代入。aとbの論理積を代入。 | |
|= | a|=b | 論理和代入。aとbの論理和を代入。 | |
^= | a^=b | 排他的論理和代入。aとbの排他的論理和を代入。 | |
>>= | a>>=b | 右シフト代入。aを右へbビットシフトし代入。 | |
<<= | a<<=b | 左シフト代入。aを左へbビットシフトし代入。 | |
論理演算子 | && | a&&b | AND。aとbの両方が真の場合に真。 |
|| | a||b | OR。aとbのどちらかが真の場合に真。 | |
! | !a | aが真のとき偽、aが偽のとき真。 | |
インクリメント | ++ | ++a; a++; |
aを1増加させる。前置と後置。 |
デクリメント | -- | --a; a--; |
bを1減少させる。前置と後置。 |
条件演算子 | ? : | a ? b : c | aが真の場合b、aが偽の場合c。 |
キャスト演算子 | (型) | (u2)a | aをu2型に変換。 |
組込みソフト開発向けに知っておくと役立つポイント
算術演算子
「型」に注意して演算するよう心がけましょう。
- u1 = u1 + u1
右辺のMAX+MAXを考えるとu1のMAXを超えてしまい、オーバーフローすると正しい計算結果が得られません。
u2に型変換したうえでu2型の変数に代入する、MAXガード処理を入れる等の工夫が必要です。 - 整数型 / 整数型 の演算結果は、整数&切り捨て
例えば、「10 / 4 」を普通に計算すると、「2.5」になります。
しかし、これを 「u1 = u1 / u1」 で計算させると、「2」になります。
四捨五入も繰り上げもされず、「切り捨て」られます。
これを考慮した、計算方法を組み込む必要があります。桁上げして計算する、四捨五入するような関数を用意するなどです。
比較演算子
- うっかり「=」に注意
「==」を「=」にしてしまうケースがまぁまぁよくあります。
例えば
if ( a = b ) { ・・・ }
という記述があっても、C言語の構文的にはOKなのでコンパイルは通ってしまいます。すべてを救えるわけではありませんが、変数と定数の比較であれば、
if( 定数 == 変数 ) { ・・・ }
と記載しておくと、「=」だった場合、コンパイルエラーで検出できます。
変数と変数の比較の場合は、期待できませんので、やっぱり気を付けましょう。
ビット演算子
- 特定ビットのマスクするために利用される
u1_a = u1_b & 0xF0 ;
⇒ 上位4bitを抽出し、下位4bitはマスク。
u1_a = u1_b | 0x80 ;
⇒ 上位1bitの結果だけを抽出し、他のbitはマスク。 - シフトする場合は、「型」・「算術/論理」・「ローテーション」を確認
シフトすると、2倍する。1/2するなどが一般的に高速に行えます。
しかし、安易に利用すると、思わぬバグにつながるため、マイコン仕様をよく確認するようにしましょう。
論理演算子
- 副作用のある文を使わない
副作用とは、変数への代入やインクリメントのように、状態を実際に変化させる結果を伴う処理のことです。
論理演算子の右辺に副作用をともなう記述があった場合実行されないケースがあります。
if ( ( i < 10 ) && ( ++j > 10 ) ) { 処理 }
このようなif文があった場合は、i<10が非成立の時点で、if文の偽が成立します。
この時右側の式は実行されません。その後にjを利用するような記述があった場合、意図しない処理となりうる可能性が出てしまうため、副作用のある文は、使わないようにしましょう。
インクリメント・デクリメント
- 前置きと後置きの実行タイミングの違いに注意
先に言っておきますが、私は、前置きを使ったことがありません。使わなくても記述可能ですし、何より誤解を生みやすいからです。説明のために出しますが、代入文の横にインクリメントという記述もしたことはありません。
前置き:++a
後置き:a++
前置きと後置きの違いは、実行されるタイミングです。前置きの場合は先にインクリメント、後置きの場合は後でインクリメントという動作になります。
<前置き>
x = ++a;
⇒ a = a + 1 ;
x = a ;
<後置き>
x = a++;
⇒ x = a ;
a = a + 1 ;
C言語学習におススメの書籍
【C言語/プログラミング初心者の方】
【入門卒業レベルの方】
【組込み向け】