如何在C函数中使用全局结构引用填充结构指针?

时间:2012-03-15 23:37:10

标签: c arrays pointers struct pass-by-reference

我是C的新手,在以下示例中无法理解为什么my_struct_ptr(main)为nil。如何将my_structs数组中的struct的地址分配给get_my_struct_by_name函数中的my_struct_ptr指针?

struct my_struct {
    char *name;
    char *descr;
    char *value;
} my_structs[3] = {
    {"a", "a description", "value 1"},
    {"b", "b description", "value 2"},
    {"c", "c description", "value 3"}
};

int get_my_struct_by_name(char *name, struct my_struct *my_struct_ptr) {

    int i;
    for (i=0; i < (sizeof(my_structs)/sizeof(struct my_struct)); i++) {
            if (strcmp(name, my_structs[i].name) == 0) {

                    my_struct_ptr = &my_structs[i];

                    printf("works: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, my_struct_ptr->value);
                    return 0;
            }
    }

    return -1;
}


int main() {
    int res = 0;
    struct my_struct *my_struct_ptr;

    if (res = get_my_struct_by_name("b", my_struct_ptr))
            return res;

    printf( "nil: %p\n", my_struct_ptr);

    printf("seg fault: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, my_struct_ptr->value);

    return res;
}

编辑:添加示例输出以帮助其他人。谢谢所有回复的人。这正是我一直在寻找的帮助!

输出:

[prompt ~]$ ./test
works: b,b description,value 2
nil: (nil)
Segmentation fault

3 个答案:

答案 0 :(得分:4)

您必须将指针作为指针传递(即传递其地址):

int get_my_struct_by_name(char *name, struct my_struct **my_struct_ptr)
{                                                   // ^^^
    // ...
    *my_struct_ptr = /* ... */
}

int main()
{
    struct my_struct * my_struct_ptr;
    get_my_struct_by_name(name, &my_struct_ptr);
    // ...
}

如果您只是按值传递指针,则只修改指针的本地副本,而不是原始指针。

道德:如果你想要一个函数来改变调用范围中的变量,你必须在某个地方说&

答案 1 :(得分:1)

解决方案是在函数get_my_struct_by_name中使用指向指针的指针。 注意在声明中添加*(星号),然后在invokation(在get_my_struct_by_name内)的赋值(&}和main&符号中。这样,您就会将指针传递给my_struct_ptr中定义的main指针,并将正确的值直接指定给main中的变量。

此解决方案假设您使用纯C(在C ++中具有对指针的引用可能更方便)。

int get_my_struct_by_name(char *name, struct my_struct **my_struct_ptr)
{
    int i;
    for(i=0; i < (sizeof(my_structs)/sizeof(struct my_struct)); i++)
    {
        if(strcmp(name, my_structs[i].name) == 0)
        {
            *my_struct_ptr = &my_structs[i];
            printf("works: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr,     
                   my_struct_ptr->value);
            return 0;
        }
    }

    return -1;
}


int main()
{
    int res = 0;
    struct my_struct *my_struct_ptr;

    if (res = get_my_struct_by_name("b", &my_struct_ptr))
        return res;

    printf( "nil: %p\n", my_struct_ptr);

    printf("seg fault: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, 
    my_struct_ptr->value);
    return res;
}

答案 2 :(得分:0)

如果我没记错的话,你需要传递指针的地址,然后在例程中取消引用它。由于这是按值调用,因此需要传递指针的地址来设置指针的值。我已经更新了下面的例程。

int get_my_struct_by_name(char *name, struct my_struct **my_struct_ptr) 
{      
    int i;    
    for (i=0; i < (sizeof(my_structs)/sizeof(struct my_struct)); i++) 
    {             
        if (strcmp(name, my_structs[i].name) == 0) 
        {                      
           *my_struct_ptr = &my_structs[i];
           printf("works: %s,%s,%s\n", my_struct_ptr->name, 
                   my_struct_ptr->descr, my_struct_ptr->value);
           return 0;             
        }     
    }      
 return -1; 
}

然后你需要获取指针的地址并从主例程传递它。

if (res = get_my_struct_by_name("b", &my_struct_ptr))                 
   return res;

这样你就可以传回结构的地址。