【问题标题】:How do I populate a struct pointer with global struct reference inside a C function?如何在 C 函数中使用全局结构引用填充结构指针?
【发布时间】:2012-03-15 23:37:09
【问题描述】:

我是 C 新手,无法理解为什么 my_struct_ptr (main) 在以下示例中为 nil。如何将 my_structs 数组中结构的地址分配给 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

【问题讨论】:

  • 你说的这个“nil”是什么? :-)
  • @Ed S. printf %p 说明符在 main 中生成“(nil)”而不是 my_struct_ptr 的地址。我更新了问题以帮助其他人澄清。谢谢

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


【解决方案1】:

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

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);
    // ...
}

如果您只是按值传递指针,就像您所做的那样,您只会修改指针的本地副本,而不是原始指针。

道德:如果您希望函数更改调用范围内的变量,则必须在某处说&amp;。

【讨论】:

    【解决方案2】:

    解决方案是在函数get_my_struct_by_name 中使用pointer to pointer。 注意在声明中添加*(星号),然后在赋值中(在get_my_struct_by_name 中)和&amp; 与号在调用中(在main 中)。这样,您将传递一个指向您在main 中定义的my_struct_ptr 的指针,并将正确的值直接分配给您在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;
    }
    

    【讨论】:

      【解决方案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; 
      }
      

      然后你需要获取指针的地址并从主程序中传入。

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

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

      【讨论】:

        猜你喜欢
        • 2019-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-03
        • 1970-01-01
        • 2013-02-26
        相关资源
        最近更新 更多