C言語: プログラミング初心者でも理解できる左シフト演算
整数リテラル接尾辞と左シフトの目的
リテラルの型
接尾辞は、リテラルの型を指定するために使用されます。接尾辞を省略すると、リテラルは int
型になります。
U
: 無符号整数リテラルL
: 長整数リテラル
例えば、以下のリテラルはそれぞれ unsigned int
、long int
、long long int
型になります。
10U; // 無符号10進数
10L; // 長10進数
10LL; // 長長10進数
左シフト演算子
左シフト演算子は、オペランドの左側のビットを右側にシフトします。シフト数は、右側のオペランドで指定されます。
例えば、以下の式では、x
のビットが 2 ビット左にシフトされます。
x << 2;
接尾辞は、左シフト演算子で使用された場合の動作に影響を与えます。
U
: 無符号シフトL
: 符号付きシフト
無符号シフトでは、シフトされたビットが左端から溢れた場合、ゼロで埋められます。符号付きシフトでは、シフトされたビットが左端から溢れた場合、符号ビットが拡張されます。
例えば、以下の式では、x
は無符号シフトされ、y
は符号付きシフトされます。
unsigned int x = 10U;
int y = 10;
x << 2; // 40
y << 2; // -40
整数リテラル接尾辞は、リテラルの型と、左シフト演算子で使用された場合の動作を指定するために使用されます。
- リテラルの型:
U
は無符号整数、L
は長整数、LL
は長長整数 - 左シフト演算子:
U
は無符号シフト、L
は符号付きシフト、LL
は符号付きシフト
#include <stdio.h>
int main() {
// 無符号10進数リテラル
unsigned int x = 10U;
x <<= 2; // 無符号シフト
printf("x = %u\n", x); // 出力: 40
// 長10進数リテラル
long int y = 10L;
y <<= 2; // 符号付きシフト
printf("y = %ld\n", y); // 出力: 40
// 長長10進数リテラル
long long int z = 10LL;
z <<= 2; // 符号付きシフト
printf("z = %lld\n", z); // 出力: 40
return 0;
}
このコードを実行すると、以下の出力が得られます。
x = 40
y = 40
z = 40
- 接尾辞は、C99 規格で導入されました。
- C++ では、
unsigned int
型のリテラルはデフォルトで無符号になります。そのため、U
接尾辞は必要ありません。
整数リテラル接尾辞と左シフト演算子の代替方法
型変換
左シフト演算子の右側のオペランドを、リテラルの型に変換することができます。
unsigned int x = 10;
x <<= (unsigned int)2; // 無符号シフト
long int y = 10;
y <<= (long int)2; // 符号付きシフト
定数マクロ
左シフト演算で使用される定数をマクロとして定義することができます。
#define SHIFT_COUNT 2
unsigned int x = 10;
x <<= SHIFT_COUNT; // 無符号シフト
long int y = 10;
y <<= SHIFT_COUNT; // 符号付きシフト
ビット演算
ビット演算を使用して、左シフト演算を実装することができます。
unsigned int x = 10;
x = x << 2; // 無符号シフト
long int y = 10;
y = (y << 2) | (y >> (sizeof(long int) * 8 - 2)); // 符号付きシフト
これらの方法は、接尾辞を使用するよりも冗長になりますが、接尾辞を使用できない状況で使用できます。
接尾辞を使用する利点
接尾辞を使用する方法は、以下の利点があります。
- コードが簡潔になる
- 読みやすくなる
- 移植性が高くなる
整数リテラル接尾辞は、左シフト演算子を使用する際に便利な機能です。接尾辞を使用することで、コードが簡潔になり、読みやすくなります。
c bit-manipulation bit-shift