第14章 複雑な演算子

基本的な演算子については第4章で説明しましたが、この章では、もう少し複雑な演算子について説明します。


14−1.ビット演算子

ビット単位でデータ操作をするものです。対象は整数に限られます

【ビット演算子】
演算子説明
 &ビットごとの AND
 |ビットごとの OR
 ^ビットごとの XOR
 ~ビットごとの反転(1 の補数)
 <<左シフト
 >>右シフト

(1) & (and)

両方のビットが 1 のときのみ結果が 1 になるビット演算です。
0 & 0 → 0
0 & 1 → 0
1 & 0 → 0
1 & 1 → 1

必要なビット以外をOFF(0)にする処理(マスクといいます)に使用されます。

例えば、10101010 という1バイトのビット列の下位4ビットを OFF する場合、そのままにしたいビットを 1 、OFFしたいビットを 0 にした、11110000 で and することにより実現できます。

	    10101010
	and 11110000
	-------------
	    10100000
(使用例)
unsigned char a = 0xaa;	/*     10101010 */
printf("%#x\n",a & 0xf0);	/* and 11110000 */

実行結果
0xa0

(2) | (or)

いずれかのビットが 1 なら結果が 1 になるビット演算です。
0 | 0 → 0
0 | 1 → 1
1 | 0 → 1
1 | 1 → 1

必要なビットをON(1)にする場合に or は使われます。

例えば、10101010 という1バイトのビット列の上位4ビットを ON する場合、ONにしたいビットを 1 、そのままにしたいビットを 0 にした、11110000 で or することにより実現できます。

	    10101010
	or  11110000
	-------------
	    11111010
(使用例)
unsigned char a = 0xaa;	/*    10101010 */
printf("%#x\n",a | 0xf0);	/* or 11110000 */

実行結果
0xfa

(3) ^ (xor)

両方のビットが異なるときに結果を 1 にするビット演算です。
0 ^ 0 → 0
0 ^ 1 → 1
1 ^ 0 → 1
1 ^ 1 → 0

特定なビットを反転する場合に xor は使われます。

例えば、10101010 という1バイトのビット列の下位4ビットを反転する場合、反転したいビットを 1 、そのままにしたいビットを 0 にした、00001111 で xor することにより実現できます。


	    10101010
	xor 00001111
	-------------
	    10100101
(使用例)
unsigned char a = 0xaa;	/*     10101010 */
printf("%#x\n",a ^ 0x0f);	/* xor 00001111 */

実行結果
0xa5

(4) ~ (補数)

ビットの反転を行うビット演算です。
0 → 1
1 → 0

全ビットの無条件反転を行います。

(使用例)
unsigned char a = 0xaa;	/*     10101010 */
printf("%#x\n",~a);

実行結果
0xff55		
(注)printf関数が unsigned char型を int型に符号拡張するために、0xff55 と表示されます。
   int型が4バイトの処理系では 0xffffff55 になります。

(5) << (左シフト)

x << n と書き、x を n ビット左へシフトします。

右側の空いたビットには 0 が入り、左側のビットは捨てられます。

左シフトは x が正の場合、x << 1 で「x * 2」を計算することと同じになります。

(例)
正の整数のとき

int x = 100;

x = x << 2;

(6) >> (右シフト)

x >> n と書き、x を n ビット右へシフトします。

左側の空いたビットには、x が符号無しなら 0 が入ります。x が符号付きなら、算術シフトを行う処理系では符号桁が入り、論理シフトを行う処理系では 0 が埋められます。 右側のビットは算術シフト、論理シフトにかかわらず捨てられます。

右シフトは x が正の場合 x >> 1 で「x / 2」を計算することと同じになります。

(例)
正の整数のとき

int x = 100;

x = x >> 2;

負の整数のとき(算術シフトを行う処理系の場合)

int x = -100;

x = x >> 2;

【参考】

演習

14−2.複合代入演算子

「a = a + b;」のような単純代入演算子を用いた演算は、「a += b;」のように、複合代入演算子を用いた形に書き換えることができます。

【複合代入演算子を使った例】
一般記法による例複合代入演算子を使った例
a = a + b;a += b;
a = a - b;a -= b;
a = a * b;a *= b;
a = a / b;a /= b;
a = a % b;a %= b;
a = a & b;a &= b;
a = a ^ b;a ^= b;
a = a | b;a |= b;
a = a << b;a <<= b;
a = a >> b;a >>= b;

14−3.条件演算子

条件式を用いて演算をおこなうことができます。これは、

条件式 ? 式1 : 式2

という書式で

条件式が「真」なら「式1」を、「偽」なら「式2」を値とします。

(例1)
int a, b, max;
scanf("%d%d", &a, &b);
max = (a >= b) ? a : b;

if文では・・・

int a, b, max;
scanf("%d%d", &a, &b);
if (a >= b) {
	max = a;
} else {
	max = b;
}
(例2)
int i;

for (i = 1; i <= 30; i++) {
	printf("%2d%c", i, (i % 10)? ' ': '\n');
}

if文では・・・

int i;

for (i = 1; i <= 30; i++) {
	printf("%2d", i);
	if ((i % 10) != 0) {
		printf(" ");
	} else {
		printf("\n");
	}
}
(実行結果)
 1  2  3  4  5  6  7  8  9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
演習

14−4.sizeof演算子

(1)sizeof( 型名 )

型名 int, double などのデータ型のサイズを求めるときに用います。

(2)sizeof( 式 )

式のサイズ ( バイト数 ) を求めるときに用います。

(注) (2)の場合 () は不要ですが、(1)に合わせ () を付けた方が混乱がありません。
(例)
char ch[20];
int data[20];

printf("char のサイズ : %2d\n", sizeof(char));
printf("int のサイズ : %2d\n", sizeof(int));
printf("配列 ch のサイズ : %2d\n", sizeof(ch));
printf("配列 data のサイズ : %2d\n", sizeof(data));
(例)
char のサイズ : 1
int のサイズ : 2
配列 ch のサイズ : 20
配列 data のサイズ : 40

14−5.演算子の優先順位と結合規則

一つの式の中に複数の演算子が含まれる場合、次のように優先順位と結合規則が決まります。

優先順位: 式中に現れた演算子のどれから先に演算を行うか

結合規則: 式中に現れた演算子の優先順位が同一であった場合に、どの演算子と結合し演算を行うか

 優先順位が曖昧な場合は記憶に頼らず、カッコ () を利用しましょう。
【演算子の優先順位と結合規則】
種類演算子結合規則優先順位
関数, 添字, 構造体,
後置増分減分
() [] . -> ++ --左=>右


|
|
|
|
|
|
|
|
|
|
|
|
|
|

前置増分減分, 単項式++ -- ! ~ + - * & sizeof左<=右
キャスト(型)
乗除余* / %左=>右
加減+ -
シフト<< >>
比較< <= > >=
等値== !=
ビットAND&
ビットXOR^
ビットOR|
論理AND&&
論理OR||
条件?:左<=右
代入= += -= *= /= %= &= ^= |= <<= >>=
コンマ,左=>右
◆◆前ページ  ▲TOP▲  次ページ◆◆

banner
「初心者のためのポイント学習C言語」
Copyright(c) 2000-2004 TOMOJI All Rights Reserved