столбцы memcpy трехмерного массива в одномерный массив - PullRequest
0 голосов
/ 08 января 2019

У меня есть 3D-массив mat, и мне нужно извлечь первый столбец и скопировать в 1D-массив arr.

Я пробовал приведенный ниже код, где я могу скопировать первую строку mat в arr, но мне нужно скопировать первый столбец mat в arr. Есть ли лучший способ сделать это без копирования элемент за элементом?

#include <stdio.h>
#include <string.h>

int main()
{
int mat[4][2][4] = {{{1,2,3,4},{10,20,30,40}},{{11,12,13,14},{110,120,130,140}},{{21,22,23,24},{210,220,230,240}},{{31,32,33,34},{310,320,330,340}}};
int arr[4];
int index,idx;

for(index=0;index<4;index++){
    memcpy(arr, &mat[index][0], sizeof(arr));
    for(idx=0;idx<4;idx++){
        printf("%d\t",arr[idx]);
    }
    printf("\n");
}

return 0;
}

Фактические результаты:

1   2   3   4   
11  12  13  14  
21  22  23  24  
31  32  33  34

Ожидаемые результаты:

1       10
11      110
21      210
31      310

* Обновлено

Ответы [ 2 ]

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

Если вы хотите использовать memcpy, данные должны быть последовательными. Я собираюсь попытаться объяснить это с помощью следующего кода.

Первая часть: я использую вашу матрицу, чтобы показать вам порядок данных в памяти.

Вторая часть: я переставляю данные не меняйте его, чтобы сохранить ваши данные)

Третья часть: я использую memcpy, как и вы.

У меня есть вопрос. Вы пытаетесь адаптировать некоторый код из фортрана в C?

#include <stdio.h>
#include <string.h>

int main()
{
//First part
int mat[4][2][4]={{{1,2,3,4},{10,20,30,40}},{{11,12,13,14},{110,120,130,140}},{{21,22,23,24},{210,220,230,240}},{{31,32,33,34},{310,320,330,340}}};
int *ptr=mat;
int i=0;
for (int z=0; z<4; z++) for (int y=0; y<2; y++) for (int x=0; x<4; x++) printf("mat(%d,%d,%d)=%d\n",x,y,z,ptr[i++]);

printf("\n------------------------\n\n");

//Second part
/* int mat[4][2][4]=
    {{{1,2,3,4},            {10,20,30,40}},
    {{11,12,13,14},         {110,120,130,140}},
    {{21,22,23,24},         {210,220,230,240}},
    {{31,32,33,34},         {310,320,330,340}}}; */
// Written like that to show "a sort of matrix transposition" (do not take this words mathematically)of left and right part.

int mat1[4][2][4]={
    {{1,11,21,31},          {10,110,210,310}},
    {{2,12,22,32},          {20,120,220,320}},
    {{3,13,23,33},          {30,130,230,330}},
    {{4,14,24,34},          {40,140,230,340}}
};

int *ptr1=mat1;
i=0;
for (int z=0; z<4; z++) for (int y=0; y<2; y++) for (int x=0; x<4; x++) printf("mat(%d,%d,%d)=%d\n",x,y,z,ptr1[i++]);

//Third part
int arr[4];
int index,idx;

for(index=0;index<2;index++){
    memcpy(arr, &mat1[0][index], sizeof(arr));
    for(idx=0;idx<4;idx++){
        printf("%d\t",arr[idx]);
    }
    printf("\n");
}

return 0;
}
0 голосов
/ 08 января 2019

Если я хорошо понимаю, вы хотите, чтобы:

#include <stdio.h>
#include <string.h>

int main()
{
  int mat[4][2][4] = {{{1,2,3,4},{10,20,30,40}},{{11,12,13,14},{110,120,130,140}},{{21,22,23,24},{210,220,230,240}},{{31,32,33,34},{310,320,330,340}}};
  int arr[2];
  int index,idx;

  for (index=0; index<4; ++index) {
    /* only set */
    for (idx=0; idx<2; ++idx) {
      arr[idx] = mat[index][idx][0];
    }

    /* only print */
    for (idx=0; idx<2; ++idx) {
      printf("%d\t", arr[idx]);
    }
    printf("\n");
  }

  return 0;
}

Исполнение производит:

1   10  
11  110 
21  210 
31  310 

Я специально разделил циклы назначения и печати, даже если они одинаковы


Но странно использовать индекс 0 только для последнего измерения, поэтому я думаю, что на самом деле вы хотите, чтобы:

#include <stdio.h>
#include <string.h>

int main()
{
  int mat[4][2][4] = {{{1,2,3,4},{10,20,30,40}},{{11,12,13,14},{110,120,130,140}},{{21,22,23,24},{210,220,230,240}},{{31,32,33,34},{310,320,330,340}}};
  int arr[2];
  int idx0, idx1, idx2;

  for (idx2 = 0; idx2 != 4; ++idx2) {
    for (idx0=0; idx0<4; ++idx0) {
      /* only set */
      for (idx1=0;idx1<2;idx1++) {
        arr[idx1] = mat[idx0][idx1][idx2];
      }

      /* only print */
      for (idx1=0;idx1<2;idx1++) {
        printf("%d\t", arr[idx1]);
      }
      printf("\n");
    }
  }

  return 0;
}

Исполнение выдает:

1   10  
11  110 
21  210 
31  310 
2   20  
12  120 
22  220 
32  320 
3   30  
13  130 
23  230 
33  330 
4   40  
14  140 
24  240 
34  340
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...