ものづくりBLOG blog page

第4章 何もしない(3):式−演算子−

2011-01-01 (Sat) 04:01
H8+C言語入門:第4章 何もしない(3):式−演算子−
 
 第4章の式について、補足をします。
 式は、変数や定数を組み合わせたものです。
 数学や算数の式と同じです。
 そこでは演算子を使って、変数や定数を組合せて式を組み上げます。
 式の基本要素である演算子について、そして、その組合せにおける処理の優先度について
 説明しましょう。
 
   ・算術演算子
   ・代入演算子
   ・単項演算子:~(チルダ)
   ・前置演算子、後置演算子
   ・ビットごとの論理演算子
   ・条件式:三項演算子
   ・切り捨て、計算の符号
   ・優先度
 
 
 ■算術演算子
  難しい日本語単語の様に思いますが、特に難しくもありません。
  四則演算と知っていますよね。
  そう、加算、減算、乗算(掛け算)、除算(割り算)というものですよ。
  記号で表すと、そう大変身近なものであることをご存じです。
 
   + 加算
   − 減算
   × 乗算(掛け算)
   ÷ 除算(割り算)
 
  これをC言語のプログラミングができる様に記号化したものが、「算術演算子」という
  ものです。これを特別に「二項算術演算子」ともいいます。二つの値、変数の計算をさ
  せるものです。
 
   算術演算子 算数で使う記号
    +      +
    -      −
    *      ×
    /      ÷
    %     (なし)
 
  一番最後に「%」があります。
  これは、モジュロ演算子というものです(BASICでは、mod というような表現で使われ
  ていますよね)。整数の割り算では、小数部分は切り捨てられます。
 
   x % y
 
  上記の式は、xをyで割った余りで、xがyでちょうど割りきれるなら0となる。
  整数の時にだけ、使います。型がfloatやdoubleでは使えません。
 
 
 ■代入演算子
  次の様な左辺が右辺に再び現れる式がある時、
 
   i = i + 2;
 
  次の様な圧縮した形に書くことができます。
 
   i += 2;
 
  上記の例では、加算+を使いました。
  この代入演算子として使える算術演算子、ビット毎の論理演算子は次の通りです。
 
   + - * / % << >> & ^ |
  !ビット毎の論理演算子については、後述しています。参照ください。
 
  代入演算子は、その処理順序に理解を深めておく必要があります。
  左辺を式leftとし、右辺をrightとして、演算子をop(operator)とした時、代入演算子の
  一般形式は次の様に表現することができます。
 
   left op= right;
 
  で、これは、先に倣い次の様に変形することができます。
 
   left = (left) op (right);
 
  で、ここで要注意な点は、rightを括っている()です。
  実際の式で見てみましょう。
 
   x *= y + 1;
 
  これは、前述の一般形式に当てはめて、
   x = x * ( y + 1); であって、
   x = x * y + 1; ではありません。
 
  結構、陥りやすい見誤りをするところなので、注意ですぞ!
 
 
 ■単項演算子:~(チルダ)
  単項演算子とは、1の補数を計算するものです。
  数値の各ビットの1を0に、0を1にします。
  次の様に使います。
 
   例 ~0x55
     16進数表記の0x55を0と1の表記としてみます。
      0x55 → 01010101
     ~を付けて、0と1を反転する。
      ~0x55 →10101010
     16進数表記で結果を表すと、0xaaとなります。
 
  勿論変数にもこの単項演算子は使えます。次の様に使います。
 
   例 ~i
 
 
 ■前置演算子、後置演算子
  インクレメントとデクレメントというものがあります。
  インクレメントは、++と表し、被演算数に1加え、
  デクレメントは、--と表し、被演算数から1を引きます。
  被演算数、つまり変数との組合せで次の様に使います。
 
   i++; //(1)
   ++i; //(2)
 
  (1)の様に演算子が後ろにあるものを、後置演算子といいます。
   書き換えると i = i + 1 となります。
  (2)の様に演算しが前にあるものを、前置演算子といいます。
   書き換えると i = i - 1 となります。
  後置演算子、前置演算子の働きは、その結果を変数に代入する時に、理解し易くなりま
  す。
  例えば、変数jに代入する式として、前記(1)と(2)を書き直してみます。
 
   j = i++; //(3)
   j = ++i; //(4)
 
  iの初期値を10とした時、
  (3)では、jに10を代入した後、iがインクレメントされます。
   jは、10になります。
  (4)では、jにiのインクレメントした後に代入します。
   jは、11になります。
 
  また、(1)と(2)の文の実行結果は?
  そうです。同じです。iの値がインクレメントされた値になります。
 
 
 ■ビットごとの論理演算子
  C言語は、次の様なビット処理用演算子を用意しています。
  H8のような制御系のプログラミングでは、よく使いますのでしっかり覚えましょう。
  これらは、signedでも、unsignedでもよいのですが、char、short、int及びlongの整
  数被演算数にのみ使うことができます。
 
   & →ビット毎のAND(論理積)
   | →ビット毎のOR(論理和)
   ^ →ビット毎の排他的OR
   << →左シフト(シフト演算子)
   >> →右シフト(シフト演算子)
   ~ →1の補数:(チルダ:単項演算子)
 
  単項演算子は、前述しているので、使い方はそこを参照してください。
 
  前記論理演算子の中で、排他的OR演算子というものがありました。この説明を少しし
  ます。
  ビット毎の排他的OR演算子では、対応するビットが異なる時には、そのビットが1とな
  り、同じであるビットは、0にセットされます。
  つまり、0x03と0x03の排他的ORの計算結果は、0になります。
 
   0x03 ^ 0x03 →結果は、0
 
  そして、0x03と0x01との排他的ORの計算結果は、次の様になります。
 
   0x03 ^ 0x01 →結果は、0x02
   0x03は、0と1(ビット)で表すと 00000011
   0x01も、0と1(ビット)で表すと 00000001
   排他的ORの結果、ビットが同じであれば0、異なれば1となりますから、その結果を
   ビットで表すと、00000010 となります。16進数表記では、0x02となります。
 
  シフト演算子<<と>>は左被演算数を右被演算数で指定したビット数だけシフトするの
  に使われます。
 
   x << 2 →xを左へ2ビットシフトします。
   x >> 2 →xを右へ2ビットシフトします。
 
  シフトをする時、空になるビットには0が入ります。
   符号なし数の右シフトでは、左から0が入ります。
         左シフトでは、右から0が入ります。
   符号付き数の右シフトでは、CPUによって符号桁が左から入ってくる場合(算術シフ
   ト)と、0が入ってくる場合(論理シフト)と、二通りがあります。これは、対象CPUの
   取扱説明書やC言語コンパイラの同様な説明書を調べる必要があります。左シフトに
   ついても同じ様です。
 
  ここで注意すべきことがあります。
  また、論理演算子に&&と||があります。&&と&とは違います。また、同様に||と|は違い
  ます。
 
 
 ■条件式:三項演算子 ?:
  これ、結構面白い式です。三項演算子?:というものを使うのですけどね。
  ええ?こんな書き方ができるんだってね。
  では、例を使って説明していきましょう。
 
  次のif文、そんな面倒なものではありませんよね。
  aとbを比較し、最大値zを求めるものです。
 
   if( a > b )
    z = a;
   else
    z = b;
 
  これを三項演算子を使って書き直すと、次の様になります。
 
   z = ( a > b ) ? a : b;
 
  どう、C言語ってすごいでしょ。
 
 
 ■切り捨て、計算の符号
  割り算/に対する切り捨ての方向、及びモジュロ演算子%に対する結果の符号は、負の
  被演算数に対しては機種(CPU)に依存する。オーバーフローやアンダーフローの扱いも
  同じです。
 
 
 ■優先度
  演算子は、計算の優先度を持ちます。
  +と-は、同じ優先度を持つが、
  それは、同じ優先度の*、/、%よりも低い。
  更に、後者は単項演算子や+や-より低い。
  算術演算子は、左から右へまとめられて評価される。
  優先度を次の様にまとめてみました。
 
  同一行の演算子は、同じ優先度をもっています。
  結合規則は、各行頭に記載しています。
  優先度は、上から下へ向かって、減少する順となっています。
  例えば、*、/、%は全て同じ優先度を持っていて、二項演算子の+と-よりも高いことを
  示しています。
  ()演算子は、関数呼び出しを表します。
 
    左→右) ()
    右→左) ~ ++ -- + - * & (type)
    左→右) * / %
    左→右) + -
    左→右) << >>
    左→右) < <= > >=
    左→右) == !=
    左→右) &
    左→右) ^
    左→右) |
    左→右) &&
    左→右) ||
    右→左) ?:
    右→左) = += -= *= /= %= &= ^= |= <<= >>=
 
  論理演算子の==と!=が結構上にあります。ビットのテスト(評価)を行う際、正しい結果
  を得るには、括弧()を使って式を括り、計算処理の順序に気を遣う必要があります。
  この中には、まだ説明していないけれど、使うものを上げておりますし、この他にも、
  もう少し、C言語の演算子があります。それは、みなさんで調べてみてください。

ものづくりBLOG

Blog Category

Blog Calendar

RSS 2.0