2017-05-31 87 views
0

我有兩個具有相同名稱的不同大小字段的數據類型。我試圖訪問基於參數我傳遞給函數這些領域---說C中的數組類型?

struct smallindex 
{ 
    unsigned char index; 
    unsigned int count; 
}; 
struct largeindex 
{ 
    unsigned int index; 
    unsigned long count; 
}; 

這可能是不do--理想的事情,但實現的一種方式,這是,有函數將一個指針視爲不同大小的指針。說,像這樣:

void function(int index, void *ptr) 
{ 
    array[] = {struct smallindex, struct largeindex}; 
    array[index] *pointer = *ptr; 
    *pointer[1].index++; 
    return; 
} 

但是,編譯器根本不喜歡這個。我嘗試了幾個其他的實現 - 但他們都沒有工作。位字段大小的變化阻止了我嘗試聯合。這是可行的嗎?或者,如果我填充索引大小以確保它們的大小匹配(但它們的字段位置仍然不匹配) - 這是可行的嗎?

+3

我確定編譯器不喜歡它。它離有效的C語法很遠。 –

+0

@JohnBollinger雖然這在C中可行嗎?如果數據類型的大小相同,該怎麼辦? – Alex

+0

無論你想要做什麼:首先讓它在一種數據類型下正常工作。請記住:相同的尺寸或不同的尺寸? –

回答

2

函數內部,可以將ptr轉換爲char *int *或指向結構或聯合類型的指針,但每個指針只能指向一種類型。如果結果無法針對指針類型進行適當對齊,則此類轉換會產生未定義的行爲,但在投射到ptr實際上指向的對象類型時不會發生這種情況。

此外,您可以通過訪問通過字符類型的指針(char *,unsigned char *等)訪問任何對象的字節。但是,如果嘗試通過指向不同不兼容類型的對象的指針來訪問對象,則會產生未定義的行爲。訪問指向對象是將指針轉換爲不同指針類型的另一個考慮因素。

因此,你可以這樣做:

void function(int index, void *ptr) { 
    // treat `ptr` as pointing to the first element of an array of int 
    int *pointer = ptr; 
    pointer[index]++; // UB here if ptr really points to something other than int 
} 

這:

void function(int index, void *ptr) { 
    // treat `ptr` as pointing to the first element of an array of char 
    char *pointer = ptr; 
    pointer[index]++; 
} 

即使這樣:

void function(int index, void *ptr, _Bool is_int_ptr) { 
    // Treat ptr as pointing to char or int depending on the value of is_int_ptr 
    if (is_int_ptr) { 
     int *pointer = ptr; 
     pointer[index]++; 
    } else { 
     char *pointer = ptr; 
     pointer[index]++; 
    } 
} 

但指針值本身不攜帶哪些信息鍵入它指向。你需要一種機制來告訴程序它指向哪種類型。通常,這將通過函數參數的聲明類型(使該函數專用於該類型),但可以通過單獨的參數傳遞它,如上例所示。

+0

可能在這一點上做的更好的事情是,要有一個函數數組,並且要調用的函數將由數組的索引決定。謝謝! – Alex

+0

此外,如果原始指針未適當對齊,則轉換爲'int * –

+0

謝謝,@AnttiHaapala,我已經更新了答案,提到這一點。 –