一般來說,C++或C的工作人員有沒有辦法知道你有什麼類型的指針的方式。
解決此問題的常用方法是使指針指向一個結構,並在結構中具有一個已知位置來指示數據的類型。通常已知的位置是結構中的第一個位置。
例子:
// signature value; use any value unlikely to happen by chance
#define VAR_SIG 0x11223344
typedef enum
{
vartypeInvalid = 0,
vartypeInt,
vartypeFloat,
vartypeDouble,
vartypeString,
vartypeMax // not a valid vartype
} VARTYPE;
typedef struct
{
VARTYPE type;
#ifdef DEBUG
uint32_t sig;
#endif // DEBUG
union data
{
int i;
float f;
double d;
char *s;
};
} VAR;
然後,您可以做一個全面的檢查:你可以看到,如果type
場比vartypeInvalid
和小於vartypeMax
大的值(和你永遠需要編輯的那些名字健全性檢查代碼;如果添加更多類型,則將其添加到列表中的vartypeMax
之前)。另外,對於DEBUG
版本,您可以檢查簽名字段sig
是否包含某些特定的簽名值。 (這意味着你的初始化代碼初始化一個VAR
實例需要總是設置sig
字段,當然。)
如果你這樣做,那麼你如何初始化它?運行時代碼將始終工作:
VAR v;
#ifdef DEBUG
v.sig = VAR_SIG;
#endif // DEBUG
v.type = vartypeFloat;
v.data = 3.14f;
如果要在編譯時初始化它,該怎麼辦?這很容易,如果你想用一個整數值來初始化它,因爲int
類型在union
第一類:
VAR v =
{
vartypeInt,
#ifdef DEBUG
VAR_SIG,
#endif // DEBUG
1234
};
如果您使用的是C99兼容版本的C,你其實可以初始化與結構一個字段名稱,並分配任何類型。但是Microsoft C不符合C99標準,所以如果你想用float
或double
值初始化你的結構,上面是一場噩夢。(如果將float值轉換爲一個整數,C不會只改變類型,它會將值舍入;而且我不知道如何獲得一個32位整數值,這個值正確表示一個32位漂浮在C程序編譯時。)
Compile time float packing/punning
如果您正在使用指針工作,不過,這很容易。只要將聯合中的第一個字段名稱指向一個指針類型,就可以將指針指向void *
,並如上所示初始化結構(指針將在1234
之上)。
如果您正在閱讀由其他人的代碼編寫的表格,並且您沒有添加類型標識符字段的方法,則我沒有針對您的一般答案。我想你可以嘗試將指針作爲不同的類型讀出來,看看哪一個工作?
假設你已經讀取了地址:'char a = *(char *)0x8c334dd;' – ouah
我的假設是解引用指針在這裏不起作用,因爲如果我解引用具有地址的變量,那麼我會得到它的內容(這是相同的地址),而不是第二個變量的內容,對嗎?我也不知道我想從中獲取數據的變量的類型是什麼.. – attis
咦?什麼「第二變量」?如果您取消引用指針,則會得到存儲在該地址的任何內容。 (另外,如果這是一個C問題,它爲什麼標記C++?) –