2012-01-30 60 views
0

我試圖在C語言中爲自己的學習效益做我自己的通用數據結構實現。我目前的努力是一個向量,我希望它能夠保存一個任意類型(或者至少是類型的大小,但並不是C中真正重要的東西?)。我的結構如下:將一個void指針施放到一個任意類型的指針上

struct vector 
{ 
    void *item; 
    size_t element_size; 
    size_t num_elements; 
} 

不過,我不明白的是我如何可以參照*項目數組中的特定元素,如果該類型應該是任意的。我知道element_size,但這對索引引用(例如item [5])沒有幫助,因爲void不是一種類型。我認爲將元素稱爲字節偏移是最容易的。因此,如果我持有大小爲12的結構向量,則項[5]與項*相距12 * 5 = 60個字節。但是,我不明白如何檢索這些數據。我知道我需要項目+ 60中的12個字節,但是我如何讓編譯器明白這一點?我正在進入預處理器領域嗎?

回答

2

sizeof的測量是以字符,所以你可以這樣做:

void *start_of_sixth_element = ((char*)item) + (5 * element_size); 

知道每個元素類型的人可以將start_of_sixth_element轉換爲正確的類型以使用它。

void*在某種程度上是一個不錯的選擇,因爲你不能做指針運算與標準C void*指針(有一個GNU的擴展,允許它,但移植的代碼使用char*unsigned char*至少算術)。雖然知道前的正確類型應用偏移5

代碼,可能只是這樣做:

correct_type *sixth_element = ((correct_type *)item) + 5; 

無效不是一個類型

它是一種類型,它只是不「完整類型」。 「不完全類型」幾乎意味着編譯器不知道void*真正指向什麼。

+0

給定一個類型,有沒有簡單的方法來找出'element_size'的正確值? (我在考慮對齊要求。) – NPE 2012-01-30 15:39:45

+0

@aix:給定類型,'element_size'是'sizeof(type)':對象的大小已經包含了對齊所需的任何填充。對齊取決於'item'指向的內存是如何分配的。只要它被分配了'malloc(element_size * num_elements)'(並且乘法不會溢出!),那麼就沒有對齊問題,因爲'malloc'被「保證」返回對齊任何對象的內存。我使用snigger引號,因爲用於SIMD指令的超大尺寸類型通常被實現排除在外。 – 2012-01-30 15:42:15

+0

@aix,'sizeof'運算符考慮了對齊。例如,如果'long'具有4字節的對齊方式,則應用於包含'long'和'char'的'struct'的sizeof'爲8. – Lindydancer 2012-01-30 15:43:45

0

void *是任何對象指針類型的泛型指針類型。您必須知道它指向哪種類型才能正確投射void *並取消引用指針。

下面是一個void *對象與不同指針類型一起使用的示例。

void *p; 
int a = 42, b; 
double f = 3.14159, g; 

p = &a; 
b = *(int *) a; 

p = &f; 
g = *(double *) f; 
0

所以,如果我拿着結構的一個向量,其具有尺寸12,項[5]將在從項目12 * 5 = 60個字節*。但是,我不明白如何檢索這些數據。我知道我需要項目+ 60中的12個字節,但是我如何讓編譯器明白這一點?

說你給定的類型是foo。正如您已經理解的那樣,您需要到達item + (5 * 12)的地址,然後在將它指向foo*之後將無效指針解除引用。

foo my_stuff = *(foo *)(item + 5 * 12); 

您也可以使用sizeof(),如果你可以在編譯時確定你的數據的類型:

foo my_stuff = *(foo *)(item + 5 * sizeof(foo)); 
相關問題