Функция, которая копирует 3D-массив в C? - PullRequest
0 голосов
/ 10 января 2019

Привет, я наткнулся на вопрос в своем учебнике, который гласит: «Напишите функцию, которая делает копию содержимого трехмерного массива целых чисел. Функция должна поддерживать любой размер трехмерного массива. '

Обсудив это с моим лектором, он уточнил, что прототип функции должен выглядеть примерно так (это 2D, мне нужно 3D).

int sum2d(int rows, int cols, int ar[rows][cols]);

Теперь, как я сейчас его кодирую, это все, что делается в основной функции, и она работает как надо, т.е. копирует все содержимое и т. Д.

 int main()
    {
        int x,y,z;
        printf("Enter x value.\n");
        scanf("%d", &x);
        printf("Enter y value.\n");
        scanf("%d", &y);
        printf("Enter z value.\n");
        scanf("%d", &z);

        int *arrx = malloc(x * sizeof(*arrx));
        int *arry = malloc(y * sizeof(*arry));
        int *arrz = malloc(z * sizeof(*arrz));



        printf("The size of the array is %d.\n", x*y*z);
        /* 3D array declaration*/
        int disp[x][y][z];
        int cpydisp[x][y][z];


        /*Counter variables for the loop*/
        int i, j, k;
        for(i=0; i<x; i++) {
            for(j=0;j<y;j++) {
                for (k = 0; k < z; k++) {
                    printf("Enter value for disp[%d][%d][%d]:", i, j, k);
                    scanf("%d", &disp[i][j][k]);
                }
            }
        }

        memcpy(cpydisp,disp, sizeof(disp));

        //Displaying array elements
        printf("Three Dimensional array elements:\n");
        for(i=0; i<x; i++) {
            for(j=0;j<y;j++) {
                for (k = 0; k < z; k++) {
                    printf("%d ", cpydisp[i][j][k]);
                }
                printf("\n");
            }
        }
    }

Однако это не правильно, поскольку мне нужно реализовать функцию только для копирования, и я придумал это. Создайте функцию с именем void array_copy, которая практически копирует содержимое массива disp в другой массив cpydisp с помощью memcpy. Затем вызывается функция array_copy в основном, но это не работает.

       int i, j, k;
        int x,y,z;
        int disp[x][y][z];
        int cpydisp[x][y][z];


void array_copy() {

        memcpy(cpydisp, disp, sizeof(disp));

    //Displaying array elements
        printf("Three Dimensional array elements:\n");
        for (i = 0; i < x; i++) {
            for (j = 0; j < y; j++) {
                for (k = 0; k < z; k++) {
                    printf("%d ", cpydisp[i][j][k]);
                }
                printf("\n");
            }
        }
    }

    int main()
    {
        printf("Enter x value.\n");
        scanf("%d", &x);
        printf("Enter y value.\n");
        scanf("%d", &y);
        printf("Enter z value.\n");
        scanf("%d", &z);

        //int *arrx = malloc(x * sizeof(*arrx));
        //int *arry = malloc(y * sizeof(*arry));
        //int *arrz = malloc(z * sizeof(*arrz));



        printf("The size of the array is %d.\n", x*y*z);
        /* 3D array declaration*/

        /*Counter variables for the loop*/
        int i, j, k;
        for(i=0; i<x; i++) {
            for(j=0;j<y;j++) {
                for (k = 0; k < z; k++) {
                    printf("Enter value for disp[%d][%d][%d]:", i, j, k);
                    scanf("%d", &disp[i][j][k]);
                }
            }
        }

        array_copy();

    }

Любые мысли, пожалуйста, о том, как я могу это исправить, так как я не могу понять, что с ним не так, когда он явно может принять любой размер пользователем, вменяющим размер, который он хочет, прежде чем что-либо начинать.

Заранее спасибо

Edit:

#include<stdio.h>
#include <string.h>
int x,y,z;
int i, j, k;

void user_input(){

    printf("Enter x value.\n");
    scanf("%d", &x);
    printf("Enter y value.\n");
    scanf("%d", &y);
    printf("Enter z value.\n");
    scanf("%d", &z);
}


void array_copy() {

    int disp[x][y][z];
    int cpydisp[x][y][z];

    memcpy(cpydisp, disp, sizeof(disp));
    //Displaying array elements
    printf("Three Dimensional array elements:\n");
    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            for (k = 0; k < z; k++) {
                printf("%d ", cpydisp[i][j][k]);
            }
            printf("\n");
        }
    }
}


int main()
{
    user_input();
    int disp[x][y][z];
    int cpydisp[x][y][z];

    printf("The size of the array is %d.\n", x*y*z);
    /* 3D array declaration*/

    /*Counter variables for the loop*/
    for(i=0; i<x; i++) {
        for(j=0;j<y;j++) {
            for (k = 0; k < z; k++) {
                printf("Enter value for disp[%d][%d][%d]:", i, j, k);
                scanf("%d", &disp[i][j][k]);
            }
        }
    }

    array_copy();

}

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

Enter x value.
1

Enter y value.
2

Enter z value.
3

The size of the array is 6.

Enter value for disp[0][0][0]:1
1
Enter value for disp[0][0][1]:2
2
Enter value for disp[0][0][2]:3
3
Enter value for disp[0][1][0]:4
4
Enter value for disp[0][1][1]:5
5
Enter value for disp[0][1][2]:6
6
Three Dimensional array elements:
797168 0 6421264
0 3 0

Process finished with exit code 0

Правильный вывод должен быть 1,2,3,4,5,6

Еще раз спасибо

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Напишите функцию, которая делает копию содержимого трехмерного массива целых чисел. Функция должна поддерживать любой размер массива 3D

Что-то вроде

int sum2d(int rows, int cols, int ar[rows][cols]);

Подход OP к использованию глобального массива переменной длины (VLA) завершается ошибкой, поскольку VLA не разрешены в области видимости файла.

VLA не может быть инициализирован (задано значение при объявлении). Однако их элементам можно присвоить во время выполнения.


С VLA d[x][y][z] (доступно в C99 и опционально в C11) это легко сделать с memcpy().
Внутри функции , используйте размер: sizeof d[0] * x.

memcpy(d, src, sizeof d[0] * x);

Замечания по реализации:

s, d являются указателями.

size_t - это некоторый тип без знака, который является правильной шириной для обработки индексов размера и массива. int может быть слишком узким.

С параметром int d[x][y][z] информация о размерах x теряется.
x здесь может использоваться компилятором для некоторых оптимизаций и проверок, но код видит d как тип int (*)[y][z].

#include <stddef.h>

void copy3d(size_t x, size_t y, size_t z, int d[x][y][z], int src[x][y][z]) {
  printf("s[%zu][%zu][%zu]\nSizes: d:%zu, d[]:%zu, d[][]:%zu, d[][][]:%zu\n\n",
      x, y, z, sizeof d, sizeof d[0], sizeof d[0][0], sizeof d[0][0][0]);
  // 'sizeof' on array function parameter 'src' returns 
  //     size of 'int (*)[(sizetype)(y)][(sizetype)(z)]
  memcpy(d, src, sizeof d[0] * x);
}

Пример использования

#include <stdio.h>

int main(void) {
  size_t x = (unsigned) rand() % 4 + 1;
  size_t y = (unsigned) rand() % 4 + 1;
  size_t z = (unsigned) rand() % 4 + 1;
  int src[x][y][z];
  int i = 0;

  for (size_t xi = 0; xi < x; xi++) {
    for (size_t yi = 0; yi < y; yi++) {
      for (size_t zi = 0; zi < z; zi++) {
        src[xi][yi][zi] = ++i;
      }
    }
  }

  int dest[x][y][z];
  // Call with two 3D: dest, and src, along with dimension info.
  copy3d(x, y, z, dest, src);

  for (size_t xi = 0; xi < x; xi++) {
    printf("{");
    for (size_t yi = 0; yi < y; yi++) {
      printf("{");
      for (size_t zi = 0; zi < z; zi++) {
        printf("%2d ", dest[xi][yi][zi]);
      }
      printf("}, ");
    }
    printf("}\n");
  }
}

Выход * * тысяча пятьдесят-один

s[2][4][3]
Sizes: d:8, d[]:48, d[][]:12, d[][][]:4

{{ 1  2  3 }, { 4  5  6 }, { 7  8  9 }, {10 11 12 }, }
{{13 14 15 }, {16 17 18 }, {19 20 21 }, {22 23 24 }, }
0 голосов
/ 10 января 2019

Учитывая, что у вас есть фактический 3D-массив, функция просто:

memcpy( dst, src, sizeof(int[x][y][z]) ); 

Если вы хотите написать менее эффективную версию самостоятельно, для учебных целей, то это выглядит так:

void copy (size_t x, size_t y, size_t z, int dst[x][y][z], int src[x][y][z])
{
  for(size_t i=0; i<x; i++)
    for(size_t j=0; j<y; j++)
      for(size_t k=0; k<z; k++)
        dst[i][j][k] = src[i][j][k];
}

Причина, по которой ваш код не работает, заключается в том, что вы использовали массивы переменной длины (VLA), но объявили их в области видимости файла («global»), что недопустимо. VLA должен быть объявлен в локальной области видимости, а границы массива должны быть установлены в допустимые значения до объявления VLA.

Приведенный выше код не заботится о том, как распределяется трехмерный массив, но оставляет его вызывающей стороне.

...