是否允许通过引用传递数组?
void foo(double& *bar)
似乎我的编译器说没有。为什么?通过引用传递数组的正确方法是什么?还是一个解决方法?我有一个数组参数,我的方法应该修改,然后我应该检索。或者,我可以使这个数组成为一个类成员,它工作正常,但它对我的代码的其他部分有很多缺点(我想避免)。
谢谢和问候。
答案 0 :(得分:95)
数组只能通过引用传递,实际上是:
void foo(double (&bar)[10])
{
}
这可以防止您执行以下操作:
double arr[20];
foo(arr); // won't compile
为了能够将任意大小的数组传递给foo
,使其成为模板并在编译时捕获数组的大小:
template<typename T, size_t N>
void foo(T (&bar)[N])
{
// use N here
}
您应该认真考虑使用std::vector
,或者如果您的编译器支持c ++ 11,std::array
。
答案 1 :(得分:13)
是的,但是当参数匹配为引用时,隐式数组为 指针不是自动的,所以你需要像:
void foo( double (&array)[42] );
或
void foo( double (&array)[] );
但请注意,匹配时,double [42]
和double []
是
不同的类型。如果你有一个未知维度的数组,它会
匹配第二个,但不是第一个,如果你有一个42的数组
元素,它将匹配第一个但不匹配第二个。 (后者是,
恕我直言,非常反直觉。)
在第二种情况下,您还必须传递维度,因为 一旦进入该功能,就无法恢复它。
答案 2 :(得分:6)
如果您只想修改元素:
void foo(double *bar);
就够了。
如果您想将地址修改为(例如:realloc
),但它不适用于数组:
void foo(double *&bar);
是正确的表格。
答案 3 :(得分:6)
当您使用C ++时,此处仍然缺少的强制性建议是使用std::vector<double>
。
您可以通过引用轻松传递它:
void foo(std::vector<double>& bar) {}
如果你有C ++ 11支持,也可以查看std::array
。
供参考:
答案 4 :(得分:3)
8.3.5.8如果参数的类型包含“指向未知T的数组的指针”或“参考”的形式类型 对于T的未知界限的数组,“该程序是不正确的
答案 5 :(得分:2)
与其他答案一样,将&
放在*
之后。
这引出了一个有趣的观点,有时候会让人感到困惑:类型应该从右到左阅读。例如,这是(从最右边的*
开始)指向指向int的常量指针的指针。
int * const *x;
你所写的内容因此是指向引用的指针,这是不可能的。
答案 6 :(得分:0)
此处,Erik解释了通过引用传递数组的所有方式:https://stackoverflow.com/a/5724184/5090928。
类似地,您可以像这样创建数组引用变量:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
// The Data + length struct
struct data{
void* s;
size_t len;
};
//mmap on opened file descriptor into a data struct
struct data* data_ffile(int fd)
{
struct data* ret = malloc(sizeof(struct data));
//Get the length of the file
struct stat desc;
fstat(fd, &desc);
ret->len = (size_t)desc.st_size;
//Calculate the length after appending
size_t new_len = ret->len + 1;
if((new_len % 64) > 56)
new_len += (64 * 2) - (new_len % 64);
else if((new_len % 64) <= 56)
new_len += 64 - (new_len % 64);
//Map the file with the increased length
ret->s = mmap(NULL, new_len, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if(ret->s == MAP_FAILED) exit(-1);
return ret;
}
//Append a character to the mmap'ed data
void data_addchar(struct data* w, unsigned char c)
{
((char*)w->s)[w->len++] = c;
return;
}
void md5_append(struct data* md)
{
data_addchar(md, 0x80);
while((md->len % 64) != 56){
data_addchar(md, (char)0);
}
}
int main(int argc, char** argv)
{
int fd = open(argv[1], O_RDONLY);
struct data* in = data_ffile(fd);
close(fd);
md5_append(in);
}