【问题标题】:Assigning values to properties of a 'struct ** record'为“结构**记录”的属性赋值
【发布时间】:2017-03-02 08:59:42
【问题描述】:

我在理解 C 双指针概念时遇到了麻烦。本质上,我正在尝试编写代码来检查 record_1 是否尚未设置。如果没有,请设置它。如果已设置,我们将在第一条记录.next 指针中添加一个新的struct record newRecord

我使用的是双指针,因为它是教授要求的

我尝试使用 firstRecord = malloc(sizeof(struct record*)); 没有任何运气,并尝试取消引用 firstRecord

遍历位于addRecord 函数中的记录的while 循环也无法按预期工作,因为我不知道如何处理双指针。

struct record
{
    int                accountno;
    char               name[25];
    char               address[80];
    struct record*     next;
};

int addRecord (struct record ** firstRecord, int accountno, char name[], char address[])
{
    if (firstRecord == NULL)
    {
        // Segmentation Fault here
        // (*firstRecord)->accountno = accountno;
        // Assign the name to the newRecord
        // strcpy((*firstRecord)->name, name);
        // Assign the name to the newRecord
        // strcpy((*firstRecord)->address, address);
        // Initialize the next record to NULL
        // (*firstRecord)->next = NULL;
    }
    else
    {
        // Define a new struct record pointer named newRecord
        struct record newRecord;
        // Assign the accountno of newRecord
        newRecord.accountno = accountno;
        // Assign the name to the newRecord
        strcpy(newRecord.name, name);
        // Assign the address to the newRecord
        strcpy(newRecord.address, address);
        // Initialize the next record to NULL
        newRecord.next = NULL;
        // Create a new record and add it to the end of the database
        struct record ** iterator = firstRecord;
        // Iterate through the records until we reach the end
        while (iterator != NULL)
        {
            // Advance to the next record
            *iterator = (*iterator)->next;
        }
        // Assign the address of newRecord to the iterator.next property
        (*iterator)->next = &newRecord;
    }

    return 1;
}

int main() {
    struct record ** firstRecord;
    firstRecord = NULL;

    addRecord(firstRecord, 1, "Foo", "Bar");
    addRecord(firstRecord, 2, "Foo", "Bar");

    return 0;
}

【问题讨论】:

  • 那么您的具体问题是什么?你试过做什么? (显示的代码实际上并没有做任何事情)
  • 你问是因为你试图编写一个函数来做到这一点,有没有机会?你用指针的地址来调用它?
  • 根据经验:如果您不了解某些内容,请不要使用它。此代码中绝对不需要指针到指针。因此,您对它的理解问题可能源于这样一个事实:在这里使用它没有任何意义。
  • 这里不需要双指针。
  • 如果使用的是链表数据结构,则不需要使用双指针。

标签: c pointers struct pointer-to-pointer


【解决方案1】:

这不仅是教授要求的,也是你的申请要求的。您想要分配内存,并设置一个在您的函数外部定义的指针指向该内存。所以很自然,您需要引用该指针。而 C 允许您通过指向指针的指针来做到这一点。

所以你希望你的调用代码看起来像这样:

struct record * firstRecord = NULL;
addRecord(&firstRecord, 1, "Foo", "Bar");
addRecord(&firstRecord, 2, "Foo", "Bar");

您传递常规指针的地址,以便addRecord 可以写入它。它通过取消引用它的论点来做到这一点,如下所示:

int addRecord (struct record ** pFirstRecord, /* ... */ )
{
    if (pFirstRecord == NULL)
      return 0; // We weren't passed a valid address of a pointer to modify

    if(*pFirstRecord == NULL)
    {
      // Here we check if the pointed to pointer already points to anything.
      // If it doesn't, then proceed with adding the first record
    }
}

【讨论】:

  • 感谢您解释发生了什么!
【解决方案2】:

你不需要双指针,一个简单的指针就足够了。首先,您需要为新记录动态分配内存,然后为其设置值:

int main() {
    struct record *record1;
    record1 = NULL;

    if (record1 == NULL)
    {
        printf("\nrecord_1 is NULL\n");


        //dynamically allocate memory for record1
        record1 = malloc(sizeof(struct record);
        if (record_1 == NULL)
        {
            printf("Error allocating memory\n");
            return -1;
        }

        //set values to record1
        record1->accountno = ...;
        strcpy(record1->name, ...);
        strcpy(record1->address, ...);
        record1->next = NULL;
        return 0;
    }
    else
    {
        //do the same for record1->next
        record1->next = malloc(sizeof(struct record);
        if (record1->next == NULL)
        {
            printf("Error allocating memory\n");
            return -1;
        }

        //set values to record1
        record1->next->accountno = ...;
        strcpy(record1->next->name, ...);
        strcpy(record1->next->address, ...);
        record1->next->next = NULL;
        return 0;
    }
}

但请注意,在编写此程序的方式中,永远不会到达 else 部分,因为 record1 始终初始化为 NULL 并且没有任何形式的迭代。

您可以阅读this link 作为结构及其内存分配的参考。

【讨论】:

    猜你喜欢
    • 2013-08-03
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-18
    相关资源
    最近更新 更多