C言語: プログラミング初心者でも理解できる左シフト演算

2024-07-27

整数リテラル接尾辞と左シフトの目的

リテラルの型

接尾辞は、リテラルの型を指定するために使用されます。接尾辞を省略すると、リテラルは int 型になります。

  • U: 無符号整数リテラル
  • L: 長整数リテラル

例えば、以下のリテラルはそれぞれ unsigned intlong intlong 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



C/C++ ビット操作入門: 単一ビットの設定、クリア、トグルの代替方法

C++とCでは、ビットレベルでの操作を行うことができます。これは、低レベルなシステムプログラミングや、効率的なデータ処理において重要です。ビット演算子& : AND| : OR~ : NOT<< : 左シフト>> : 右シフトビット位置は、通常0から始まり、右から左にインデックスされます。...


C言語のユニットテストにおけるサンプルコード解説

ユニットテストとは、ソフトウェア開発において、プログラムの最小単位である「ユニット」に対して行うテストのことです。C言語では、関数やモジュールがユニットとみなされます。ユニットテストでは、各ユニットが期待通りの動作をするかどうかを検証します。...


C++ struct のパディングを理解してメモリを効率的に使用しよう

アライメントとは、データがメモリ上でどのように配置されるかを制御するものです。多くの CPU は、特定のデータ型に対して特定のアライメント要件を持っています。例えば、int 型は 4 バイト境界に配置される必要があるかもしれません。パディングとは、構造体のメンバー間に挿入される空白のことです。コンパイラは、構造体のメンバーが適切に配置されるようにするためにパディングを追加します。...


C/C++ プログラミング:マクロにおける `do-while` と `if-else` ステートメントの謎を解き明かす

この解説では、do-while と if-else ステートメントがマクロでどのように使われ、なぜ一見無意味に見えるコードでも意味を持つのか、詳細に説明します。マクロとCプリプロセッサー:コード展開と処理Cプリプロセッサーは、C/C++ ソースコードをコンパイル前に処理するプログラムです。マクロは、プリプロセッサーによって展開されるテキスト置換規則です。マクロ呼び出しは、マクロ定義内のテキストで置き換えられます。...


C言語における配列の初期化の代替方法

C言語において、配列の全要素を同じ値で初期化する方法にはいくつかの手法があります。初期化リストを用いる方法小さな配列の場合、最も単純な方法は初期化リストを使うことです。この方法では、配列 num のすべての要素が値 1 で初期化されます。メモリセット関数 memset を用いる方法...



c bit manipulation shift

C/C++ ビット操作入門: 単一ビットの設定、クリア、トグルの代替方法

C++とCでは、ビットレベルでの操作を行うことができます。これは、低レベルなシステムプログラミングや、効率的なデータ処理において重要です。ビット演算子& : AND| : OR~ : NOT<< : 左シフト>> : 右シフトビット位置は、通常0から始まり、右から左にインデックスされます。


32ビット整数のセットビット数カウントのコード例解説

問題:32ビットの整数が与えられたとき、その中に含まれる1のビットの数を数える。アルゴリズム:初期化:ループ:結果:コード例:バイナリ表現:整数は2進数で表現される。1のビットは、その位置の値が1であることを示す。例えば、10進数の5は2進数で101と表される。この場合、セットビットの数は2である。


ビットシフト演算子の具体的なコード例と解説

ビットシフト演算子とは、プログラミングにおいて、整数値のビットパターンを左または右にシフトする操作を行う演算子です。この操作は、特定のビットを抽出したり、値を効率的に乗除算したりするために使用されます。ビットシフト演算子の種類:左シフト演算子 (<<):オペランドを指定されたビット数だけ左にシフトします。左にシフトされたビットは0で埋められます。これは、元の値を2の指定されたべき乗で乗算する効果があります。例: x << 2 は、x を 4 倍します。


++i と i++ の違い: C言語におけるインクリメントと for ループ

C言語において、++i と i++ はどちらも変数 i の値を 1 増やすインクリメント演算子ですが、そのタイミングが異なります。++i は、式の評価前に i の値を 1 増やします。つまり、++i 自体の値はインクリメント後の i の値になります。


C言語で配列のサイズを調べる方法:コード例と解説

C言語では、配列の要素数を直接取得する機能はありません。しかし、sizeof 演算子を用いて、配列のサイズ(バイト数)を計算し、要素数を求めることができます。基本的な方法配列の総バイト数を求める:int array[5] = {1, 2, 3, 4, 5}; size_t array_size_bytes = sizeof(array); // 配列全体のバイト数