簡體   English   中英

C語言按已知大小強制轉換void指針

[英]C language cast void pointer by known size

簡單的問題,我們可以用c語言按已知大小按未知數據類型轉換void指針嗎?

考慮這種情況:

函數assertEqual ,它應該得到2個指針作為參數,取消引用它們和相等的值。 你當然不能取消引用void指針,但是如果我知道指針所指向的數據大小呢? 我可以創建一些已知大小但未知數據類型的動態指針嗎? 該函數應該看起來像assertEqual(void * expected,void * current,size_t size)

您可以將參數轉換為unsigned char* ,然后比較第一個size字節(或者更好地使用memcmp來執行此操作),但不能保證在給定值有多個表示的情況下它會執行您想要的操作(例如,考慮在結構中填充,填充內容的差異可能是無害的,但是可以通過這種方法檢測到,還有其他情況,例如浮點格式的NaN值,並且在技術上可能發生在最原始的情況下類型)。

我可以創建一些已知大小但未知數據類型的動態指針嗎?

作為基本規則。 沒有。 您需要知道類型以對類型指針進行類型轉換。 例如float和int都有4個字節的大小,但類型不相等。

但是,如果您具有等效類型,則可以將類型轉換為等效類型。 例如,在某些系統上,int和long都是4個字節並且是等效的。

簡單的問題,我們可以用c語言按已知大小按未知數據類型轉換void指針嗎?

不可以。每個指針類型都有一個特定的類型。 這包括void * ,其引用類型( void )是語言提供的不完整類型。 有一個指針,指向一個未知的數據類型,沒有這樣的事情,雖然在void *你有一個指針類型是可以相互轉換與所有其他對象指針類型。

另一方面,通過指向字符類型的指針(例如char *unsigned char * )訪問任何類型的對象是有效的,並且一種方法是通過其類型為字符數組的左值。 你可以得到與你所要求的非常相似的東西:

int assertEqual(void* expected, void* current, size_t size) {
    unsigned char (*ep)[size] = expected;
    unsigned char (*cp)[size] = current;
    // ...
}

這使用了一個可變長度數組類型作為指向類型:指針epcp都指向unsigned char類型的size元素數組 該數組類型的sizesize ,因此,例如,您確實會發現sizeof(*ep) == size 也就是說,您有一個指向指定大小的對象的指針,您可以通過該指針訪問該對象的字節。

然而,正如其他人已經指出的那樣,你所要求的是有點無意義的。 如果您只想比較兩個字節序列而不知道它們代表什么類型的對象,那么您可以使用memcmp() 另一方面,這作為一般的相等性測試是不安全的,因為當作為給定類型的對象進行比較時,具有不同字節序列的兩個對象仍然可以是相等的。 發生這種情況是因為允許許多整數類型具有不對其值有貢獻的填充位,並且因為浮點表示完全取決於實現。

此外, structunion類型可以包含未指定的填充字節,並且不一定是一致的值。 您無法將復合類型與==運算符進行比較,但是比較構成此類對象的表示的字節數組不一定會產生與基於每個成員的對象進行比較相同的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM