第13章 その他の演算子

1 ビット演算子

教科書P142〜145

2-1 ビットごとの論理演算

C言語は数値を2進表現('0'または'1')したときの各ビットごとの演算を行うことができる。

ビット演算の期論論理にはNOTANDORXORがある。

《真理値表》

NOT(否定)
〜a

AND(論理積)
a&b

OR(論理和)
a|b

XOR(排他的論理和)
a^b

C言語ではそれぞれという論理演算子を使う。

《論理演算子サンプルプログラム》

#include <stdio.h>

void main(void)
{
    int not, and, or, xor;
    int n = 0xff1a, mask = 0xffff;

    not = ~n;
    and = n & mask;
    or = n | mask;
    xor = n ^ mask;

    printf("n    = %4x\n", n);
    printf("mask = %4x\n\n", mask);
    printf("NOT n      : %4x\n", not);
    printf("n OR  mask : %4x\n", or);
    printf("n AND mask : %4x\n", and);
    printf("n XOR mask : %4x\n", xor);

}

[実行結果(intが2byteの場合)]
n    = ff1a
mask = ffff

NOT n      : 00e5
n OR  mask : ffff
n AND mask : ff1a
n XOR mask : 00e5

2-2 シフト演算

シフト演算は指定された数だけ各ビットを左または右にシフトする演算子である。

左シフト:<<
a<<bで、aの各ビットを左へbビット分シフトさせる。空いた右のビットにはが入る。
右シフト:>>
a>>bで、aの各ビットを右へbビット分シフトさせる。空いた右のビットには、変数aが符号なし変数(unsigned intなど)なら0が、符号あり変数(intなど)なら符号ビット(一番左のビット)の値が入る。

《シフト演算サンプルプログラム》

#include <stdio.h>

void main(void)
{
    int a = 1, i, w;

    for (i=0 ; i<16 ; i++)
    {
        w = a << i;
        printf("左へ %2d ビットシフト : %d\n", i, w);
    }

}

[実行結果(intが2byteの場合)]
左へ  0 ビットシフト : 1
左へ  1 ビットシフト : 2
左へ  2 ビットシフト : 4
左へ  3 ビットシフト : 8
左へ  4 ビットシフト : 16
左へ  5 ビットシフト : 32
左へ  6 ビットシフト : 64
左へ  7 ビットシフト : 128
左へ  8 ビットシフト : 256
左へ  9 ビットシフト : 512
左へ 10 ビットシフト : 1024
左へ 11 ビットシフト : 2048
左へ 12 ビットシフト : 4096
左へ 13 ビットシフト : 8192
左へ 14 ビットシフト : 16384
左へ 15 ビットシフト : -32768 ←あやしい

2 条件演算子

教科書P148〜149

条件演算子3つの項目を評価する演算子である。

《書式》

条件式 ? 値1 : 値2;

《解説》

《使用例》得点が60点以上なら1を、60点未満なら0を返す

#include <stdio.h>

void main(void)
{
    int ten, chk;

    scanf("%d", &ten);
    chk = (ten >= 60) ? 1 : 0;
    if (chk == 1)
        printf("合格\n");
    else
        printf("追試\n");

}

つまり、次の式と同じ意味になる。

if (ten >= 60)
  chk = 1;
else
  chk = 0;

練習問題

教科書149ページ練習問題35

3 カンマ演算子

教科書P150〜151

式を次のようにカンマ「,」で区切っていったものをカンマ演算子と呼ぶ。

式1,式2,・・・,式n;

《例1》入力を繰り返すプログラム

while (printf("データ入力:"), scanf("%d", &data)!=EOF)
{
    ・
    ・
    ・

《例2》1つのfor文で・・・

for (i=0, cnt=0 ; i<N ; i++, cnt++)
{
    ・
    ・
    ・

《例3》{ }を使いたくないから

if (a < b)
  c = a, a = b, b = c;

例3のプロうグラムは、プログラミングの作法から言うと「下品」な書き方である。

練習問題

教科書151ページ練習問題36

4 型変換とキャスト演算子

教科書P178〜181

4-1 データ型の混合演算と型変換について

'a' + 5 や 10000 * 1.05 のように文字型と整数型、整数型と実数型というような異なる型のデータ同士の演算混合演算といい、C言語では文字型、整数型、実数型の間で混合演算を認めている。
演算の際、次の規則で自動的に型変換が行われている(char<short=intとする)。

《第1段階の変換》

第1段階の変換が行われた後、次の優先度で型の高いほうに変換されて演算が行われる。

《第2段階の変換》

long double>double>unsigned long>long>unsigned int>int

《例》どのように変換されるかを見る

double c;
c = 10.5 + 5 + 'a';
               ↓intに変換
           ↓doubleに変換
      double型で演算され、cに代入される

4-2 キャスト演算子

C言語の型変換規則は厳格でないため、型変換においてあいまいさが生じ、思ったような結果にならない場合がある。そこで、キャスト演算子を用い、明確に型変換を行う

《構文》

(型)

《例》商品の税込価格を求める

#include <stdio.h>

void main(void)
{
    int teika, kakaku;

    scanf("%d", &teika);
    kakaku = (int)((double)teika * 1.05);
    printf("定価 %d 円の税込価格は %d 円です。\n", teika, kakaku);

}

《解説》

キャストをしない場合、kakaku = teika * 1.05;となるが、型の自動変換によりteikaはdouble型になり、teika * 1.05の演算結果はdouble型になる。double型の演算結果をint型変数に代入するので、また自動変換が行われ、小数点以下が切り捨てられる。つまり、キャストをしなくても演算結果は正しい。
しかし、キャストを用いてプログラマが意図する変換を行うことにより、データのあいまいさを防ぐ。


[ TOP ]