C++
 Computer >> コンピューター >  >> プログラミング >> C++

C言語の文字列化演算子(#)とトークン貼り付け演算子(##)を徹底解説

C言語のプリプロセッサには、マクロ定義をより柔軟に扱うための特殊な演算子が用意されています。本記事では、その中でも重要な「文字列化演算子(#)」と「トークン貼り付け演算子(##)」について、具体的なコード例を交えながら詳しく解説します。

文字列化演算子(#)とは

文字列化演算子「#」は、プリプロセッサで使用される演算子の一つです。マクロ定義内で引数の前に「#」を付けることで、コンパイラに対してそのトークンを文字列リテラルへ変換するよう指示します。

この演算子を活用すれば、通常はダブルクォート(")で囲む必要のあるテキストを、クォートなしで文字列として扱うことができます。

サンプルコード

#include<stdio.h>
#define STR_PRINT(x) #x
main() {
    printf(STR_PRINT(This is a string without double quotes));
}

実行結果

This is a string without double quotes

上記の例では、マクロ STR_PRINT に渡された引数「This is a string without double quotes」が、自動的に文字列リテラルへと変換されて出力されます。引数にダブルクォートを付けていないにもかかわらず、正しく文字列として表示されている点に注目してください。

トークン貼り付け演算子(##)とは

トークン貼り付け演算子「##」も、プリプロセッサで使用される演算子です。マクロ定義内で2つのトークンの間に「##」を記述すると、それらを連結して1つのトークンとして合成するようコンパイラに指示します。

サンプルコード

#include<stdio.h>
#define STR_CONCAT(x, y) x##y
main() {
    printf("%d", STR_CONCAT(20, 50));
}

実行結果

2050

この例では、STR_CONCAT(20, 50) と呼び出すことで、引数の「20」と「50」が「##」によって連結され、1つの数値リテラル「2050」として扱われます。その結果、printf 関数は 2050 を出力します。

まとめ

文字列化演算子(#)とトークン貼り付け演算子(##)は、いずれもマクロ定義内でのみ使用できるプリプロセッサ演算子です。「#」はトークンを文字列リテラルへ変換し、「##」は2つのトークンを1つに連結します。これらを活用することでマクロの柔軟性が大幅に向上し、デバッグ用のログ出力やコードの自動生成など、さまざまな場面で役立ちます。

  1. JavaScriptのビットごとのAND(&)演算子とは?仕組みと使い方をわかりやすく解説

    JavaScriptのビットごとのAND(&)演算子は、2つの数値を2進数(ビット列)に変換したうえで、対応する各ビット同士を比較する演算子です。比較の結果、両方のビットが1である場合のみ1を返し、それ以外の場合は0を返します。ビットAND演算の基本ルールビットごとのAND演算では、各桁のビットに対して次のような判定が行われます。1 & 1 → 11 & 0 → 00 & 1 → 00 & 0 → 0つまり、両方のオペランドの対応するビットが「1」のときだけ、結果も「1」になります。これは論理積(AND)と同じ考え方を、ビット単位で適用するものです。サンプルコー

  2. JavaScriptのTextEncoderとTextDecoderとは?文字列とバイト列の相互変換をわかりやすく解説

    JavaScriptでは、文字列とバイト列(バイナリデータ)を相互に変換したい場面がよくあります。そんなときに活躍するのが、TextEncoderとTextDecoderという2つの標準組み込みAPIです。本記事では、それぞれの役割と基本的な使い方を、実際に動くサンプルコードとともに解説します。 TextEncoderとは TextEncoderは、指定した文字列をUTF-8形式に変換(エンコード)するためのオブジェクトです。encode()メソッドに文字列を渡すと、変換結果がUint8Array(符号なし8ビット整数の配列)として返されます。 TextDecoderとは TextDecod