基本的な演算子については第4章で説明しましたが、この章では、もう少し複雑な演算子について説明します。
ビット単位でデータ操作をするものです。対象は整数に限られます。
演算子 | 説明 |
---|---|
& | ビットごとの AND |
| | ビットごとの OR |
^ | ビットごとの XOR |
~ | ビットごとの反転(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
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
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
0 → 1 1 → 0
全ビットの無条件反転を行います。
unsigned char a = 0xaa; /* 10101010 */ printf("%#x\n",~a); 実行結果 0xff55 (注)printf関数が unsigned char型を int型に符号拡張するために、0xff55 と表示されます。 int型が4バイトの処理系では 0xffffff55 になります。
x << n と書き、x を n ビット左へシフトします。
右側の空いたビットには 0 が入り、左側のビットは捨てられます。左シフトは x が正の場合、x << 1 で「x * 2」を計算することと同じになります。
正の整数のときint x = 100; x = x << 2; |
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; |
「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; |
条件式を用いて演算をおこなうことができます。これは、
条件式 ? 式1 : 式2
という書式で
条件式が「真」なら「式1」を、「偽」なら「式2」を値とします。
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; }
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
型名 int, double などのデータ型のサイズを求めるときに用います。
式のサイズ ( バイト数 ) を求めるときに用います。
(注) (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
一つの式の中に複数の演算子が含まれる場合、次のように優先順位と結合規則が決まります。
優先順位: 式中に現れた演算子のどれから先に演算を行うか
結合規則: 式中に現れた演算子の優先順位が同一であった場合に、どの演算子と結合し演算を行うか
※ 優先順位が曖昧な場合は記憶に頼らず、カッコ () を利用しましょう。
種類 | 演算子 | 結合規則 | 優先順位 |
---|---|---|---|
関数, 添字, 構造体, 後置増分減分 | () [] . -> ++ -- | 左=>右 | 高 ↑ | | | | | | | | | | | | | | 低 |
前置増分減分, 単項式 | ++ -- ! ~ + - * & sizeof | 左<=右 | |
キャスト | (型) | ||
乗除余 | * / % | 左=>右 | |
加減 | + - | ||
シフト | << >> | ||
比較 | < <= > >= | ||
等値 | == != | ||
ビットAND | & | ||
ビットXOR | ^ | ||
ビットOR | | | ||
論理AND | && | ||
論理OR | || | ||
条件 | ?: | 左<=右 | |
代入 | = += -= *= /= %= &= ^= |= <<= >>= | ||
コンマ | , | 左=>右 |
「初心者のためのポイント学習C言語」 Copyright(c) 2000-2004 TOMOJI All Rights Reserved