2010-03-24 81 views
0

我想知道sample1和sample2之間有什麼區別。爲什麼有時我必須將結構作爲參數傳遞,有時我可以在不傳遞函數的情況下做到這一點?如果samplex函數需要幾個結構來處理,它將會如何呢?你會通過幾個結構作爲一個論點?C Struct作爲參數

struct x 
{ 
    int a; 
    int b; 
    char *c; 
}; 

void sample1(struct x **z;){ 
    printf(" first member is %d \n", z[0]->a); 
} 

void sample2(){ 
    struct x **z; 
    printf(" first member is %d \n", z[0]->a); // seg fault 
} 

int main(void) 
{ 
    struct x **z; 

    sample1(z); 
    sample2(); 

    return 0; 
} 
+0

太好了!謝謝(你的)信息!我有點困惑! – Brian 2010-03-24 15:52:50

回答

1

首先,你的參數類型不是結構,但一個指針指向struct(或指針結構的陣列 - 這是從視被叫方的點語義上等價,不同之處在於地址一個數組不能改變)。

在第二種情況下,您使用的局部變量完全獨立於main中具有相同名稱的局部變量。由於未初始化,因此嘗試訪問其中一個成員時會遇到seg故障。 (main中的那個也未初始化,但訪問它似乎偶爾在sample1中工作)。

您應該在使用它們之前初始化您的變量,否則您將進入未定義行爲的範圍。例如。

void sample1(struct x **z){ 
    printf(" first member is %d \n", z[0]->a); 
} 

void sample2(){ 
    struct x z[1]; 
    z[0].a = 1; 
    ... 
    printf(" first member is %d \n", z[0].a); 
} 

int main(void) 
{ 
    struct x z[1]; 

    z[0].a = 1; 
    ... 
    sample1(z); 
    sample2(); 

    return 0; 
} 
0

兩者都是無效和訪問記性不好。結果是不確定的,所以兩個結果都是正確的。

0

C和C類語言有一個「範圍」的概念。查看所有大括號({})?那些是「塊」。它們基本上將它們之間的所有代碼封裝到獨立於同一級別任何其他塊的捆綁包中。您在該塊中創建的任何變量只能在該塊中訪問 - 您無法在其他任何地方參考該變量。

您可以創建一個嵌套塊。例如:

int f() { 
    int x; 
    scanf("%d", &x); 
    if (x == 3) { 
     return 7; 
    } 
    else { 
     return x; 
    } 
} 

正如你所看到的,else塊嵌套函數的塊中,因此可以訪問函數的變量。

當您在mainsample2中聲明struct x **z時,實際上是創建了兩個變量,都稱爲z。這些是完全獨立的 - 它們根本不是同一個變量。他們沒有關係。他們唯一的共同點是他們的名字和類型 - 實際價值是不同的。在這兩種方式中使用相同變量的唯一方法是通過傳遞,就像在sample1中那樣。

當然,你的z指針是垃圾 - 你還沒有分配任何東西。我建議你在嘗試解引用它之前實際存儲了一些內容。

0

你的宣言

struct x **z; 

只需創建一個指針的指針類型爲x的結構。你實際上並沒有初始化指針,即使它們指向任何地方。

試着這麼做

struct x z; 
struct x *pZ = &z; 

sample1(&pZ); 

(我不能完全肯定你實際上要達到,儘管!)