C++动态数组大小

5
我在C++中遇到了一个关于一维数组的小问题。我有一个函数如下:
void func(int (&array)[???])
{
    // some math here;

    "for" loop {
        array[i] = something;
    }
}

我在代码中的某个地方调用函数,在进行数学运算之前,我无法知道数组的维度。该数组作为引用传递到函数中!因为我需要它在main()函数中。我如何分配这样的数组?这样,带有??维度的数组作为引用传递到函数中,然后我必须放置维度并向其写入一些值。

5
你的问题不太清楚。你的问题是关于分配、访问还是如何将数组传递给函数?请提供一些实际的代码以说明你的问题,或描述你真正想做什么。 - Björn Pollex
一个引用数组是一种不寻常的东西:你可能根本不想使用这样的引用。 - Eamon Nerbonne
@Eamon:你不能有一个引用数组,上面的代码是对数组的引用。 - Roger Pate
@Eamon Nerbonne: 我真的认为这是最好的方式,可以真正给func一个数组而不是像使用数组一样使用裸指针。 - Cedric H.
啊,我误读了声明为(无效的)int &*arr而不是不寻常但有效的int *&arr。我从未考虑过int&*arr - 有趣的是它不仅仅是一个坏主意,而且是无效的:-)。毕竟,您可以通过(同样不明智的)struct intRef { int & ref; intRef(int& ref):ref(ref){}}; void func(intRef * array) {}来做一些相当等价的事情 - 因此,指向引用的指针并没有根本性的问题,只是...不必要的。 - Eamon Nerbonne
6个回答

14

既然你正在使用C++,为什么不使用std::vector<>呢?


对于向量,我总是额外加上+1,因为每当我不知道“某物”有多大时,它们都很有用。 - user475353
你认为这个答案对于初学者有帮助吗? - Dave O.
@Dave:是的,它可以帮助他理解在这些简单情况下,在C++中使用“数组”的更好方法。 - rubenvb
2
我希望我不会冒犯nykon,如果我说从他的问题来看,我认为他还没有掌握数组和指针的概念。这使得他能够阅读API文档的可能性很小。甚至可以质疑一个C++初学者是否能够从代码片段"std::vector<>"中推断出标准模板库的存在。 - Dave O.

10

其他人提到你应该在C++中使用std::vector,他们是正确的。

但是你可以通过将func定义为函数模板来使代码工作。

template <typename T, size_t N>
void func(T (&array)[N])
{
    // some math here;

    "for" loop {
        array[i] = something;
    }
}

模板函数的实现方式是"如何实现已经存在于标准库中的功能"的一个典型例子。 - rubenvb
7
你的要求我能够理解。这句话的意思是什么? - Roger Pate
6
我同意“你应该使用向量”的观点;好的,但是这个答案提供了解决并理解OP主要问题的方法... - Cedric H.
@Roger, @Cedric:我并不是在批评答案的质量,它是相当有价值的,但是从我的角度来看,它好像绕开了std::vector::size()的存在。 - rubenvb

8

使用指针而不是引用:

void func(int *a, int N);

或者更简单的方法,使用向量:
void func(std::vector<int> &a);

向量可以通过简单地说出来分配

std::vector<int> a(10);

可以使用a.size()方法获取元素数量。

5

如果您传递给func的数组是一个栈数组而不是指针,您可以使用函数模板来保留其大小:

template <class T, size_t N>
void func(T(&array)[N])
{
    size_t array_length = N; // or just use N directly
}

int main() 
{
    int array[4];
    func(array);
}

话虽如此,正如其他人已经指出的那样,std::vector 可能是这里最好的解决方案。


但是这是不必要的,因为在函数内部,您可以使用包含相同信息(作为编译时常量)的模板参数N。 - Fabio Fracassi

0

除了建议使用向量之外,您还可以使用valarray,它也是STL的一部分,专门用于处理数学集合。


0
你需要认识到的是,数组就是指针。例如定义一个如下的数组:int array[5]会在堆栈上分配5个整数的空间,array将成为第一个值的地址。因此,要访问数组中的第一个值,可以写成:

array[0]*array(这与*(array+0)相同)

同样,要获取第三个元素的地址,可以写成:

&array[2]array+2

由于数组就是指针,如果要将其传递给函数,只需要将其作为指针即可,无需担心运行时数组的大小:
void func(int *array)
{
    int size;
    //计算数组的大小
    for (int i = 0; i < size; ++i)
    {
        //对array[i]进行任何操作
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接