传递大小为9的数组并变为大小1

时间:2014-02-01 00:59:01

标签: c++ arrays

通过引用简单调用

void foo(int* A)
{
    // ...
}

void main()
{
    int A[] = {1,1,1,1,1,1,1,1,1};
    foo(A);
}

不确定为什么,但它减少了数组的大小并丢失/泄漏数组上的信息....

4 个答案:

答案 0 :(得分:2)

您正在将指针传递给数组的第一个元素。使用原型

创建您的函数

void foo(int * A,int size);

您仍然可以像平常一样访问A [0 ... size-1]。

答案 1 :(得分:1)

  

不确定为什么,但它减少了数组的大小并丢失/泄漏数组上的信息....

foo()中,sizeof(A) == 8不是因为它是“泄漏”信息,而是因为8是int*类型指针的大小。无论在A中初始化了多少个整数main(),都是如此。

这可能会对正在发生的事情有所启发:

#include<iostream>
using namespace std;

void foo(int* A)
{
  cout << "foo: " << sizeof(A) << endl; // 8
}

void bar(int A[])
{
  cout << "bar: " << sizeof(A) << endl; // still 8
}

int main()
{
  int A[] = {1,1,1,1,1,1,1,1,1};
  cout << "main: " << sizeof(A) << endl; // 36 (=4*9)
  foo(A);
  bar(A);
  return 0;
}

输出:

main: 36
foo: 8
bar: 8

main中,sizeof“知道”A[]的大小 - 它是sizeof(int)* length = 4 * 9 = 36.当{{1}时,此信息会丢失转换为A[]中的指针A*

如果我们将foo改为A,那该怎么办?这会保留阵列长度吗?没有!在这种情况下,bar(int A[])仍然是8,指针的大小。仅在sizeof(A)中,编译器才会保留数组大小为main的信息。

如果您希望函数知道数组的大小,请使用A模板,或单独传递大小。

以下是对此的另一个讨论:When a function has a specific-size array parameter, why is it replaced with a pointer?

答案 2 :(得分:1)

你应该完全放弃C风格的数组并改用std::array。只需比较一下(这是你问题的解决方案):

void foo(int* A, std::size_t size) {
    // ...
}

int main() {
    int A[] = {1,1,1,1,1,1,1,1,1};
    foo(A, (sizeof(A) / sizeof(int)));
}

为:

template<std::size_t Size>
void foo(const std::array<int, Size>& array) {
    // ...
}

int main() {
    std::array<int, 9> A {{ 1, 1, 1, 1, 1, 1, 1, 1, 1 }};
    foo(A);
}

不漂亮吗?或者只是看看std::vector

的华丽程度
void foo(const std::vector<int>& vector) {
    // vector.size() is the size
}

int main() {
    std::vector<int> A = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
    foo(A);
}

如果你真的希望foo成为通用算法,我只会用迭代器来打击你的想法:

template<class Iterator>
void foo(Iterator begin, Iterator end) {
    // ...
}

int main() {
    std::array<int, 9> A {{ 1, 1, 1, 1, 1, 1, 1, 1, 1 }};
    std::vector<int> B = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
    foo(A.begin(), A.end());    // not a single problem
    foo(B.begin(), B.end());    // was given that day
}

C ++有一个惊人的(可以说是)标准库和一个惊人的类型系统(如果你不忽视C遗留“特征”,如void*):使用它们。

答案 3 :(得分:0)

通过引用传递数组的正确方法是

void foo(int (&A) [9])
{
    // sizeof(A) == sizeof(int) * 9
}

通用方式是这样的:

template <std::size_t N>
void foo(int (&A) [N])
{
    // sizeof(A) == sizeof(int) * N
}

您可以使用std::array(需要C ++ 11),其语法更直观

template <std::size_t N>
void foo(std::array<int, N> &A)
{
    // A.size() == N
}