2010-03-24 82 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); 

(我不能完全肯定你实际上要达到,尽管!)