1

私はC++でのキャストを勉強していますが、その後のコードは私にとって魔法です。

#include <iostream>
using namespace std;

class Base {
public:
virtual void f() { }
};

#define SOME_VALUE 8

int main() {
cout << SOME_VALUE <<endl;
getchar();
}

出力は次のとおりです。8

コードは非常に単純ですが、SOME_VALUEのタイプは何ですか?int、またはdoubleまたはchar?

後はもっと複雑です:

#include <iostream>
using namespace std;

class Base {
public:
virtual void f() { }
};

#define SOME_VALUE 8
int main() {
cout << (Base*)SOME_VALUE-SOME_VALUE <<endl;
getchar();
}

出力は次のとおりです。FFFFFFE8

このコードに従うと、SOME_VALUEが数値型であることがわかります。sizeof(SOME_VALUE)もテストし、出力は4です。しかし、SOME_WHATが数値の場合、オブジェクトポインターにどのように変更できますか?そして、オブジェクトポインタはどのようにして整数にマイナスすることができますか?

4

3 に答える 3

5

#defineプリプロセッサコマンドです。コードがコンパイルされる前に評価されます。発生するのは、メイン関数のSOME_VALUEのテキストが、SOME_VALUEが定義されているテキストに置き換えられていることだけです。それは8です。

SOME_VALUE自体は、前処理の前にのみ存在するため、C++タイプを持っていません。前処理後、SOME_VALUEはC ++プログラムに存在しなくなり、intであるリテラル値8が得られます。

2番目の質問では、Base*へのキャストはCスタイルのキャストを使用します。これは、変換するものの生のメモリをターゲットタイプとして扱うだけで、何でも何にでも変換できます。したがって、キャストされるメモリがターゲットタイプと一致しない場合、非常に危険な場合があります。C ++の場合、static_castまたはreinterpret_castを使用して、何がキャストされているかをより明確にすることをお勧めします。

(Base *)SOME_VALUEは、最終的にメモリアドレス8へのBase *になると思います。したがって、これは、メモリの8バイト目から始まるBaseオブジェクトへのポインタです。メモリ内の8番目の場所にBaseオブジェクトがない可能性があるため、実際にはあまり役に立ちません。次に、「-8」はBase*タイプのサイズの8倍を取り除きます。32ビットコンピューターでは、ポインターは32ビットまたは4バイトです。したがって、8-(4 * 8)= -24の10進数で、16進数のFFFFFFE8です。

コンピューターが負の数を大きな数として表す理由を知りたい場合は、別の質問です。ここから始めてください:http://en.wikipedia.org/wiki/Signed_number_representations

于 2012-05-26T09:45:42.677 に答える
2
cout << (Base*)SOME_VALUE-SOME_VALUE <<endl;

基本的に(恐ろしい)方法です:

Base* b = 8;
b = b - 8;

ただし、8はベースのサイズで静かに乗算されます(したがって、8ではなく8つのベーススロットを減算します)。

ポインタは通常符号なしであるため、何が起こっているのかというと、符号なしポインタがラップアラウンドしているということです。

0xFFFFFFE8は4294967272または(通常のラップアラウンドで4バイトのunsigned intを想定)8-24です。

また、実際のコードでこれを行うことは絶対にしないでください。ポインタに任意の値を割り当てると、爆発的に爆発することは間違いありません。

理解しやすい状況は次のようになります。

int* p = (int*) 24;
p -= 4; //like ((char*) p) - 4 * sizeof(int)

4バイト整数の場合、p24-4 * sizeof(int)= 24-4 * 4 = 24-16 = 8であるため、の値は8になります。

于 2012-05-26T09:45:55.233 に答える
2

SOME_VALUEマクロです-タイプはありません。 8ただし、は整数です。

常にのように動作し#define SOME_VALUE ((Base*)8)たい場合は、を使用します。SOME_VALUEBase*

于 2012-05-26T09:46:53.913 に答える