C ++通过引用传递数组

时间:2012-04-04 09:00:17

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

是否允许通过引用传递数组?

 void foo(double& *bar) 

似乎我的编译器说没有。为什么?通过引用传递数组的正确方法是什么?还是一个解决方法?我有一个数组参数,我的方法应该修改,然后我应该检索。或者,我可以使这个数组成为一个类成员,它工作正常,但它对我的代码的其他部分有很多缺点(我想避免)。

谢谢和问候。

7 个答案:

答案 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);
}