2013-03-12 24 views
2

親愛的計算器愛好者,發現嵌套結構的成員變量的地址

首先我在計算器是新手,所以我提前爲我犯任何錯誤道歉。

這是一種C謎題。或者至少我感到困惑。代碼如下。

struct outer_str 
{ 
    struct nest_str1 
    { 
    int mem1; 
    }; 
    struct nest_str2 
    { 
    int mem2; 
    }nest_var2; 
}outer_var; 

int main() 
{ 
    outer_var.nest_var2.mem2 = 111; 
    printf("\n\nThe value of mem2 is %d\n\n",outer_var.nest_var2.mem2); 

    // Statement to assign mem1 of nest_str1 with a value say 333; 
    // Statement to print the value of mem1 of nest_str1; 

    return 0; 
} 

由於意見建議你訪問成員變量的嵌套結構nest_str1MEM1。另請注意,沒有爲嵌套結構nest_str1聲明結構變量。

盼望着希望我試了下面的代碼,模仿了一點C++。

outer_var.nest_str1.mem1=333; 

當我編譯使用GCC 4.6.3程序,下面的誤差顯示出

"struct outer_str has no member named 'nest_str1' ". 

然後我考慮從作爲該結構的nest_var2的地址查找nest_str1的地址嵌套結構變量nest_str2。我試了下面的代碼,

​​

該程序編譯爲O.K.但是輸出結果並不符合我的預期。我有一個運行時錯誤。

Segmentation fault (core dumped) 

現在我甚至不知道我的方法是否正確。所以我希望有一些建議。我也擔心我可能忽略了一些明顯簡單的解決方案。

我還想知道我們是否可以在下面給出的代碼中訪問mem1

struct outer_str 
{ 

    struct nest_str1 
    { 
    int mem1; 
    }; 

}outer_var; 

爲了您的時間和耐心,我提前感謝每一個人。

+1

有些人需要小心這個,因爲上面的語法被一些編譯器接受。他們會認爲'nest_str1'是結構的匿名(或未命名)成員,並允許直接訪問_its_成員,如:'outer_var.mem1 = 7;'可以很好地編譯。便攜式**!(這裏僅供參考,因爲有些人可以逃脫,其他人不可以 - 這裏有很多讀者......) – 2013-03-12 15:58:52

+0

@SteveValliere,如果結構是匿名的, ('struct {int mem1;};')AFAIK – Nim 2013-03-12 16:04:02

+0

@Nim結構_tag_的存在不會影響_instance_的結構是匿名的或不是。你可以命名一個沒有標籤的結構實例,那麼你不能在其他任何地方重新使用結構定義(因爲它是匿名的)。這可能並不清楚,對不起。這就是爲什麼我認爲值得一提的是,應該儘可能地避免匿名成員 - 他們是混亂和不可移植的。 – 2013-03-12 16:07:52

回答

2

沒有的outer_var成員,這將允許您訪問mem1(你沒有申報一個,你剛纔定義的稱爲nest_str1。)

更改爲:

struct outer_str 
{ 

    struct nest_str1 
    { 
    int mem1; 
    } nest_var1; // now there is a member! 

}outer_var; 

現在你可以:

outer_var.nest_var1.mem1 = 100; 

你的嘗試只是錯誤的,th對於mem1沒有存儲空間,所以即使您的代碼正常工作,您最有可能最終會寫入mem2的位置。

+0

謝謝。但是當結構outer_str的結構變量outer_var被創建時會發生什麼? – Deepu 2013-03-12 15:59:04

+0

但是我已經從mem2的地址中減去了偏移量。 – Deepu 2013-03-12 16:02:02

+1

因此,段錯誤,你正在寫入一些隨機存儲位置,正如我所說,沒有* mem1存儲*,默認情況下gcc不會將您的第一個結構視爲* anonymous *結構(您已將其命名,所以,它被視爲*類型*)。刪除名稱,然後'mem1'將可以從'outer_var'作爲'outer_var.mem1'訪問) – Nim 2013-03-12 16:06:07

0

你寫的代碼是絕對正確的。但是,儘管將類型轉換爲(char),即「addr =(struct nest_str1 *)((char *))」,但從第二個嵌套結構「outer_var.nest_var2」中減去「offset」值後,儘管將其類型轉換爲(int ) &(outer_var。你可以在第一個結構中填充變量。

#include<stdio.h> 
#include<stdlib.h> 

struct outer_str{ 
     struct nest_str1 
    { 
    int mem1; 
    }; 
    struct nest_str2 
    { 
    int mem2; 
    }nest_var2; 
}outer_var; 

int main() 
{ 
    int offset; 
    struct nest_str1 * addr; 
    offset=sizeof(int); // There is only one integer mem1 in nest_str1 
    addr=(struct nest_str1 *)((char *) & (outer_var.nest_var2) - (char   *)offset); 
    addr->mem1=333; 
    printf("\n\nThe value of mem1 is %d\n\n",addr->mem1); 
    return 0; 
}