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

C/C++の右辺値(R値)式パズル:~xだけ書いても値が変わらない理由とは?

今回は興味深いパズルを紹介します。次のようなプログラムがあったとき、出力はどうなるか、そしてその理由は何かを考えてみてください。

#include<iostream>
using namespace std;
int main() {
    int x = 0xab;
    ~x;
    cout << hex << x;
}

さて、出力はどうなるでしょうか?「~x」はビット反転(1の補数)演算を行っています。では、反転された結果が16進数で表示されるのでしょうか?

実際の出力は次のとおりです。

出力

ab

結果はまったく変わりません。では、なぜこのような動作になるのでしょうか?

理由:~x は右辺値(R値)式だから

答えのカギは「~x が右辺値(R値)式である」という点にあります。~x は x のビットをすべて反転した値を計算しますが、その結果はどこにも代入されていません。右辺値式が生成する値は一時的なものであり、左辺値(L値)に代入されるまでメモリ上に保存されることはありません。つまり、計算された反転結果はその場で捨てられてしまうのです。

そこで、左辺値に代入するようにコードを修正してみましょう。

例(修正版)

#include<iostream>
using namespace std;
int main() {
    int x = 0xab;
    x = ~x;
    cout << hex << x;
}

出力

ffffff54

今度は反転結果が x に代入されるため、0xab のビット反転である 0xffffff54 が正しく表示されました。

なお、0xab は int 型(多くの環境で32ビット)として扱われるため、~x は上位ビットも含めてすべてのビットを反転します。その結果、0x000000ab は 0xffffff54 になるというわけです。このように、C/C++では演算結果を実際に利用するには、必ず変数などに代入する必要がある点に注意しましょう。

  1. C/C++のmemcpy()関数の使い方と実例解説

    この記事では、C++ STLにおけるmemcpy()関数の動作、構文、および具体的な使用例について詳しく解説します。 memcpy()とは? memcpy()関数は、C++ STLに組み込まれた標準関数の一つで、<cstring>ヘッダーファイルで定義されています。この関数はメモリブロックをコピーするために使用され、あるメモリ位置から別のメモリ位置へ、指定されたバイト数分のデータを転送します。 関数の実行結果は、データのバイナリコピーとなります。重要な点として、memcpy()は終端のNULL文字やその他の終端記号をチェックしません。単純にソースから指定されたバイト数(num)をそ

  2. C/C++で学ぶAA木(AA Tree)とは?基本概念と平衡化操作を徹底解説

    AA木(AA Tree)とはコンピュータサイエンスにおいて、AA木(AA Tree)とは、順序付きデータを効率的に格納・検索するために実装された平衡木(バランスドツリー)の一種です。AA木は、赤黒木(Red-Black Tree)の変種として扱われます。赤黒木は二分探索木の一形態であり、要素の追加や削除を効率的にサポートします。赤黒木と大きく異なる点は、AA木では赤いノードを右の子としてのみ追加でき、左の子としては配置できないという制約があることです。この制約により、2-3-4木ではなく2-3木をシミュレートすることになり、その結果、木の保守操作が大幅に簡素化されます。赤黒木の平衡化アルゴリズ