返回一个数组的维度?

时间:2012-02-03 23:32:46

标签: c++ arrays 2d

如何只返回数组的一个维度,而忽略另一个维度?

如:

int map[4][8];

int MapManager::getMapX(int x)
{
    return map[x];
}

4 个答案:

答案 0 :(得分:5)

返回类型应为int*int[],而不是int

int* MapManager::getMapX(int x) {
    return map[x];
}

除此之外,你没事。

答案 1 :(得分:5)

使用二维数组,您只能通过转换为指针(例如

)直接返回内部数组的一维数组。
int map[4][8];

int* MapManager::getMapX(int x)
{
    return map[x];
}

对于其他'维度',您需要将另一个外部数组复制到:

int* MapManager::getMapY(int y, int *outArray, int numElements)
{
   for(int i = 0; i < numElements; i++) {
      outArray[i] = map[i][y];
   }
}

需要使用正确的大小分配此数组。 (在这种情况下为8)。

原因是y'列'的数组元素在内存中不是连续的,而是分布在几个数组(即'x'行)上。 C数组依赖于这个连续的概念来访问元素。

答案 2 :(得分:3)

由于此处没有其他答案返回实际数组(指针不是数组),我想我可能会展示如何真正返回一个数组。或者最接近的事情,即对数组的引用。

typedef int row_type[8];

row_type& MapManager::getMapX(int x) {
    return map[x];
}
  

这有什么意义?指针的工作方式相同!

不,它没有。指针丢失类型信息,即大小。您可以使begin() and end() functions使用数组,但不能使用指针:

// pointer version
int* MapManager::getMapX_ptr(int x) {
    return map[x];
}

row_type& row = getMapX(0);
// row is of type int(&)[8]
// notice the size is not lost in the type!
std::sort(begin(row), end(row));
// compiles fine! end() correctly finds the end of the row

int* ptr = getMapX_ptr(0);
// notice how ptr has no size information at all
std::sort(begin(ptr), end(ptr));
// can't possible be made to work!

您无法为end撰写int*

template <typename T, std::size_t N>
T* end(T(&arr)[N]) {
    return &arr[0] + N;
}

template <typename T>
T* end(T* ptr) {
    // what here?
    // guess?
    // pick a random number?
}

答案 3 :(得分:0)

您可以创建一个特殊类,提供数组的跨步视图。也就是说,它会超越价值观。这是类似的开头:

template<typename T>
class StridedView
{
public:
    StridedView(T * b, int stride, int count)
        :begin_(b), stride_(stride), count_(count)
    {}

    template<int N>
    StridedView(T (&arr)[N])
        :begin_(arr), stride_(1), count_(N)
    {}

    T & operator[](int index)
    {
        return *(begin_ + index * stride_);
    }

    const T & operator[](int index) const
    {
        return *(begin_ + index * stride_);
    }

    int size() const { return count_; }
private:
    T * begin_;
    int stride_;
    int count_;
};

然后你可以拥有适当的函数来获取行或列:

template<typename T, int R, int C>
StridedView<T> GetRow(T (&arr)[R][C], int row)
{
    T * begin = (*arr) + (row * C);
    return StridedView<T>(begin, 1, C);
}

template<typename T, int R, int C>
StridedView<T> GetColumn(T (&arr)[R][C], int column)
{
    T * begin = (*arr) + column;
    return StridedView<T>(begin, C, R);
}

Demo