我有一个名为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);
那么我应该如何将一个结构数组复制到另一个数组中并返回呢?我甚至会返回正确的类型(我想要的类型)?我想我只是对实际传入的内容感到困惑,所以现在我只想尝试一些工作。
答案 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;
}