2015-05-04 147 views
1

我對將結構指針去結構化爲 結構變量有點混淆。解引用指向結構變量的結構指針

如果我用一個例子證明我的問題,那將會很好。

所以我在這裏:

struct my_struct{ 
    int num1; 
    int num2; 
}tmp_struct; 

void Display_struct(void * dest_var){ 

    struct my_struct struct_ptr; 

    struct_ptr = *((struct my_struct *)dest_var); 

    printf("%d\t%d\n",struct_ptr.num1,struct_ptr.num2); 

} 

int main() 
{ 
    tmp_struct.num1 = 100; 
    tmp_struct.num2 = 150; 


    Display_struct(&tmp_struct); 
    return 0; 
} 

現在,當我運行這個例子我能得到的代碼在一個非常乾淨的方式進行編譯,並輸出是正確的。

但是我不能夠得到是這個結構指針引用到結構變量的正確的方式,因爲我們在其他簡單 數據類型的情況下,這樣做:

int example_num; 

void Display_struct(void * dest_var){ 

    int example_num_ptr; 

    example_num_ptr = *((int *)dest_var); 

    printf("%d\t%d\n",struct_ptr.num1,struct_ptr.num2); 
} 

int main() 
{ 
    example_num = 100; 


    Display_struct(&example_num); 
    return 0; 
} 

這裏我們可以將int指針取消引用到int變量,因爲它是一個簡單的數據類型,但在我看來,我們不能像結構變量那樣以類似的方式取消引用結構指針,因爲它不是簡單的數據類型,而是複雜的數據類型或數據結構。

請幫我解決這個背後的概念。

+0

爲什麼你不能取消引用指針結構?在一個指針中,你不能訪問底層對象的地方是什麼? –

+0

你的意思是這樣的:https://ideone.com/lduzh0? – mch

+2

這裏的實際問題是什麼?順便說一句第二個例子是錯誤的,你嘗試printf'struct_ptr.num1',但在第二個例子中沒有'struct_ptr'。 –

回答

1

唯一的問題是,你必須保證通過的void*指向正確的結構類型的變量。只要這樣做,一切都會正常工作。

問題是你爲什麼要使用void指針而不是期望的結構,但是我認爲這個函數是一些泛型編程設置的一部分,否則使用void指針是沒有意義的。

但是,如果你嘗試的東西「的hackish」是這樣的:

int arr[2] = {100, 150}; 
Display_struct(arr); // BAD 

然後不再有任何保證:上面的代碼可以編譯得很好,但它調用未定義的行爲,因此可能會崩潰&燒傷。該結構可以在任何地方包含填充字節的代碼也打破C的"strict aliasing"規則

(別名是指由C標準第6.5章表達式,7§規定的規則)

0

你所想起來沒有任何問題。 A struct -type(別名爲集合數據類型)在技術上與其他類型沒有太大區別。

如果我們看一下底層的東西,任何類型的變量(包括struct類型)都只是內存中的一些位數。

該類型決定變量中的位數及其解釋。

實際上,無論您取消引用指針到int還是指向指向struct的指針,只需獲取指針所指向的位塊即可。

0

在你的主要功能,你有struct tmp_struct。它不是一個指針。但沒關係,因爲您將tmp_structaddress傳遞給函數void Display_struct(void * dest_var)

然後函數接受輸入參數,你的指針(void *)。它包含'tmp_struct`的地址。

然後在函數內部正確解除引用。

struct_ptr = *((struct my_struct *)dest_var); 

你尊重void*struct my_struct類型。您的引用正確,因爲您傳遞了相同類型的對象。否則它會導致運行時間問題。

無論您的數據類型或數據結構多麼複雜,解引用都應該正常工作。

但是,如果輸入參數類型爲void *請確保通過struct my_struct函數。