使用C中的函数复制结构数组

时间:2015-07-31 06:27:41

标签: c arrays struct memcpy

我有一个名为Record的结构,其中包含与之关联的数据,在我的程序中,我有一个这些Record的数组。结构如下所示:

#define MAX_RECORDS 1024

typedef struct
{
    char    title[80];
    char    artist[80];
    int     year;
    char    genre[80];
    char    label[80];
    double  price;
} Record;

Record record_inventory[MAX_RECORDS];

由于我正在编写的程序需要将record_inventory的不同字段排序到Record的新数组中,但实际上没有更改与原始数组关联的数据,我想我需要一个简单的将一个数组复制到另一个数组的方法。

我在网上找了一篇关于stackoverflow的帖子说要像这样说出来:

void copy_record(Record (*copy_to)[MAX_RECORDS], Record (*copy_from)[MAX_RECORDS])
{
    memcpy(copy_from, copy_to, sizeof *copy_from);
}

现在,在排序方法中,我有一个像这样的函数原型:

Record* sort_by_title()
{
    Record ret[MAX_RECORDS];
    copy_record(&ret, record_inventory); // compilation error saying incorrect pointer type
    // do sorting here
    return ret;
}

上面的评论给出了错误的指针类型错误。但是,执行以下所有操作都不会起作用:

copy_record(&ret, &record_inventory);
copy_record(&ret, *record_inventory);
copy_record(ret, record_inventory);
copy_record(ret, &record_inventory);
copy_record(*ret, *record_inventory);

那么我应该如何将一个结构数组复制到另一个数组中并返回呢?我甚至会返回正确的类型(我想要的类型)?我想我只是对实际传入的内容感到困惑,所以现在我只想尝试一些工作。

5 个答案:

答案 0 :(得分:1)

由于某种原因,您的函数声明表明它需要指针指针。它应该是:

void copy_record(Record *copy_to, Record *copy_from)
{
    memcpy(copy_to, copy_from, sizeof(*copy_from) * MAX_RECORDS);
}

然后将其称为copy_record(ret, record_inventory);

答案 1 :(得分:1)

您的复制功能具有正确的签名,您可以通过以下方式调用它:

copy_record(&ret, &record_inventory);

然而,你以错误的方式得到memcpy的论点;目的地是第一位的。它应该是:

memcpy(copy_to, copy_from, sizeof *copy_from);

但是你的sort_by_title()函数存在设计缺陷。 ret是该函数的本地数组。当函数返回时,它将被销毁。如果你成功地返回一个指向它的指针,那么指针就会悬空。

相反,您可以使sort_by_title获取输入和输出参数,然后返回void

避免必须使用指针到数组语法的另一种方法是将数组包装在结构中:

struct RecordInventory
{
    Record records[MAX_RECORDS];
};

然后您可以使用具有值语义的该类型的对象,例如按价值回报。

答案 2 :(得分:0)

小心,因为括号在声明变量时可能具有特殊含义。 Record *x是指向Record的指针,但Record (*x)()是指向函数的指针,该函数返回Record作为结果。你正在给编译器一个很难的时间来试图找出你想要的东西。

此外,Record *x相当于Record x[],而Record *x[](正如您所做)相当于Record **x(指向指针的指针),这与Record *x,因此您的编译器无法识别类型。

此外,memcpy()首先获取目标地址,因此您的参数被反转,并且您还要从数组而不是整个数组复制单个元素,如keltar pointed out in his answer

答案 3 :(得分:-1)

事实上,通过简单地将数组本身作为参数来排序数组是不可能的。因为在c中,如果你写了一个像

这样的函数
void func(int arr[100]);

参数arr实际上是指针而不是数组。也就是说,以下几行没有什么不同。

void func(int *arr);
void func(int arr[]);
void func(int arr[100]);

因此,当您尝试sizeof arr时,您只需获得指向int的指针的大小。你得到的是sizeof(int *)

如果函数想要接收数组,则必须将数组的长度作为参数给出:

void func(int arr[], size_t length);

复制Record数组的功能应该是

void copy_array(Record dest[], Record from[], size_t length)
{
    memcpy(dest, from, sizeof(Record) * length);
}

您的代码无法编译,因为您搞砸了指针指向数组的指针。
在您的代码中,Record (*copy_to)[MAX_RECORDS]copy_to是指向Record数组的指针。并且指向的数组的长度是固定的(MAX_RECORDS)。

更重要的是,就地排列大型物体的速度相当慢。您应该考虑创建一个指针数组(或索引)并对指针进行排序。

非常抱歉英语不好。

答案 4 :(得分:-2)

修改您的代码,如下所示。

void copy_record(Record (*copy_to), Record (*copy_from))
{
    memcpy(copy_from, copy_to, sizeof(*copy_from) * MAX_RECORDS);
}

Record* sort_by_title()
{
    Record ret[MAX_RECORDS];
    copy_record(ret, record_inventory); 
    return ret;
}