изменение 2d массива в функции - PullRequest
1 голос
/ 12 марта 2011

Итак, я написал функцию, которая поворачивает 2D-массив на 90 градусов, и мне сказали на IRC, что я не могу передать 2D-массив по ссылке (например, void test (char A [] [10] &) ) и что я просто должен передать свой массив обычным способом, однако, когда я делаю это, эта функция не меняет фактический массив. Итак, как мне изменить мой исходный массив в функции?

void one(char A[][10], int N)
{
    char B [10][10];
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            B[j][N-i-1] = A[i][j];
    A = B;
}

Ответы [ 5 ]

3 голосов
/ 12 марта 2011

A = B ; не копирует элементы массива B постоянно.Это недопустимое назначение для изменения элементов A навсегда.A сохраняет свои исходные значения при возврате функции.Вам нужно сделать членскую копию для постоянного копирования элементов с B на A.

1 голос
/ 12 марта 2011

Чтение, предложенное ссылкой @FredOverflow: Как использовать массивы в C ++? .

Чтобы повернуть массив NxN по часовой стрелке на 90 °, вы можете разделить задачу на два меньших шага:

  • перевернуть матрицу в направлении вверх / вниз
  • транспонировать ее

void rot90cw(char A[][N]) {
  // flip in up/down direction (swap rows)
  for (int i = 0; i < N/2; i++)
    std::swap_ranges(&A[i][0], &A[i][0] + N, &A[N-i-1][0]);

  // transpose (swap top-right and bottom-left triangles)
  for (int i = 0; i < N-1; i++)
    for (int j = i+1; j < N; j++)
      std::swap(A[i][j], A[j][i]);
}

Я использовал swap() и swap_ranges() для выполнения операций на месте.

Пример

// -*- coding: utf-8 -*-
#include <algorithm>
#include <iostream>

namespace {
  const int N = 3;

  // rotate 90° clock-wise
  void rot90cw(char A[][N]) {
      // ... defined above
  }

  void print(char a[][N]) {
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++)
        std::cout << a[i][j];
      std::cout << '\n';
    }
    std::cout << std::endl;
  }
}

int main() {
  char a[][N] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' };
  print(a);
  rot90cw(a);
  std::cout << "Rotated 90° clock-wise:" << std::endl; //note: utf-8
  print(a);
}

Вывод

abc
def
ghi

Rotated 90° clock-wise:
gda
heb
ifc
1 голос
/ 12 марта 2011

Когда вы передаете массив (например, char A[][10]), вы фактически передаете указатель на исходный массив, поэтому выполнение A = B заставляет A указывать на B и не изменяет исходный массив.Вместо этого вы можете использовать такую ​​функцию, как memcpy, чтобы фактически скопировать содержимое B в A:

memcpy(A, B, sizeof(B));
0 голосов
/ 12 марта 2011

То, что вы пытаетесь передать массив по ссылке и изменить эту ссылку. Это работает, но не обязательно.

Вы можете изменить массив непосредственно элемент за элементом:

void one(char A[][10], int N)
{
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
        {
            char b = A[j][N-i-1];
            A[j][N-i-1] = A[i][j];
            A[i][j] = b;    
        }
}
0 голосов
/ 12 марта 2011

Массивы не работают так в C ++.Когда вы передаете массив в функцию, вы передаете указатель на первый элемент и ничего более, поэтому вы создаете локально определенный массив B, затем устанавливаете указатель, переданный в вашу функцию, чтобы указывать на головуиз массива B.Ни при каких условиях память, назначенная вашему исходному A, фактически не изменяется.Затем, когда функция возвращается, указатель A из вашей функции удаляется, оставляя исходный массив A без изменений.Если вы хотите изменить массив, переданный в качестве аргумента функции, вам придется изменить элементы напрямую.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...