Как разделить массив на два массива в C

#c #arrays #split #memcpy

#c #массивы #разделить #memcpy

Вопрос:

Допустим, у меня есть массив в C

 int array[6] = {1,2,3,4,5,6}
  

как я мог бы разделить это на

 {1,2,3}
  

и

 {4,5,6}
  

Возможно ли это с помощью memcpy?

Спасибо,

nonono

Комментарии:

1. да, но в зависимости от того, что вам нужно сделать с частями, это может оказаться ненужным. что вы пытаетесь сделать с частями?

2. запустите их через функцию, которая работает с ними. Однако я не могу изменить функцию.

3. memcpy скопирует содержимое (по порядку) из исходного буфера в буфер назначения. ваш массив на самом деле не будет разделен надвое. вы должны создать два новых массива и скопировать содержимое из первого в новые

Ответ №1:

Конечно. Простое решение состоит в том, чтобы выделить два новых массива с помощью malloc , а затем с помощью memcpy скопировать данные в два массива.

 int array[6] = {1,2,3,4,5,6}
int *firstHalf = malloc(3 * sizeof(int));
if (!firstHalf) {
  /* handle error */
}

int *secondHalf = malloc(3 * sizeof(int));
if (!secondHalf) {
  /* handle error */
}

memcpy(firstHalf, array, 3 * sizeof(int));
memcpy(secondHalf, array   3, 3 * sizeof(int));
  

Однако, в случае, если исходный массив существует достаточно долго, вам может даже не понадобиться это делать. Вы могли бы просто «разделить» массив на два новых массива, используя указатели на исходный массив:

 int array[6] = {1,2,3,4,5,6}
int *firstHalf = array;
int *secondHalf = array   3;
  

Комментарии:

1. НО помните, пожалуйста, что (1) всегда проверяйте возвращаемое значение из malloc( ); и (2) не приводите возвращенный ptr.

2. @Pete Не приводит его? Почему бы и нет?

3. Потому что это не требуется в C и считается плохой практикой.

4. @Pete Wilson: Я опустил проверку ошибок для краткости, возможно, это было преувеличено. Не знал, что приведение из void* в int* не требуется, я делал это годами и никогда не задумывался, нужно ли это. Спасибо за это понимание! 🙂

Ответ №2:

 // create space for 6 ints and initialize the first 6
int array[6] = {1,2,3,4,5,6};
// reserve space for two lots of 3 contiguous integers
int one[3], two[3]; 
// copy memory of the first 3 ints of array to one
memcpy(one, array, 3 * sizeof(int)); 
// copy 3 ints worth of memory from the 4th item in array onwards
memcpy(two, amp;array[3], 3 * sizeof(int)); 
  

Комментарии:

1. Спасибо, но, пожалуйста, не могли бы вы прокомментировать строки кода, я не понимаю, что они делают — особенно int one[3] = (int[3])array; . Является ли это приведением array к массиву длиной 3?

2. 1 от меня, мне нравится, как вы показываете решение, которое выполняет глубокое копирование и которому не требуется malloc / free . Незначительный вопрос от не носителя английского языка: вы имели в виду написать for two *s*lots в своем комментарии к коду?

3. @Frerich Raabe: Нет, я имею в виду использовать lots. Смотрите второе определение для английского языка: en.wiktionary.org/wiki/lot , можно сгруппировать вещи в «лоты». Обычно в C я бы рекомендовал абсолютно минимальное использование malloc.

Ответ №3:

Вам не нужно их разделять. Если у вас есть

 int *b = array   3;
  

у вас есть второй массив. Когда вы передаете массив в функцию, он все равно превращается в указатель.

Ответ №4:

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

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

double *** double3d(long int dim1,long int dim2,long int dim3)
{
    long int i,j,k;
    double ***array;
    array=(double ***)malloc(dim1*sizeof(double **));
    for(i=0;i<dim1;i  )
    {
     array[i]=(double **)malloc(dim2*sizeof(double *));
     for(j=0;j<dim2;j  )
      array[i][j]=(double *)malloc(dim3*sizeof(double ));
    }
    return array;
}// end double3d

void summ(double ***A,double ***B, double ****C)
{
    int i ,j ,k;
    for(i=0;i<10;i  )
    for(j=0;j<5;j  )
    for(k=0;k<5;k  )
    (*C)[i][j][k]=A[i][j][k] B[i][j][k];
}

void main()
{
   int i,j,k,nx,ny;
   double ***M1, ***M2, ***M3, ***M4,***M5,***M6;
   nx=5;ny=5;
    M1=double3d(10,nx,ny);
    M2=double3d(10,nx,ny);
    M3=double3d(10,nx,ny);
    M4=double3d(5,nx,ny);
    M5=double3d(5,nx,ny);
    M6=(double ***)malloc(10*sizeof(double **));

    for(i=0;i<10;i  )
    {
        for(j=0;j<nx;j  )
           for(k=0;k<ny;k  )
           {
           M1[i][j][k]=i;
           M2[i][j][k]=1;
           }
    }

// Note random values are in M4 and M5 as they are not initalised
    memcpy(M6,     M4, 5 * sizeof(double **));
    memcpy(M6 5,   M5, 5 * sizeof(double **));

    for(i=0;i<5;i  )
    {
       for(j=0;j<nx;j  )
          for(k=0;k<ny;k  )
          {
               M4[i][j][k]=200;
               M5[i][j][k]=700;
          }
    }

printf(" printing M6 Memcpy before addtionn");
    for(j=0;j<nx;j  )
    {
       for(k=0;k<ny;k  )
           printf("%f ",M6[4][j][k]);
       printf("n");
       for(k=0;k<ny;k  )
           printf("%f ",M6[9][j][k]);
       printf("n");
    }
    // calling for non memcpy array
    summ(M1,M2,amp;M3); printf(" Non memcpy output last value : %f n",M3[9][nx-1][ny-1]);
    // calling for memcpy
    summ(M1,M2,amp;M6); printf(" memcpy output last value : %f n",M6[9][nx-1][ny-1]);
printf(" printing M6 Memcpy for two sets after addtionn");
    for(j=0;j<nx;j  )
    {
       for(k=0;k<ny;k  )
           printf("%f ",M6[4][j][k]);
       printf("n");
    }
    for(j=0;j<nx;j  )
    {
       for(k=0;k<ny;k  )
           printf("%f ",M6[9][j][k]);
       printf("n");
    }

    free(M6);// cleared M6

printf(" printing M4 Memcpy after deleting M6n");
    for(j=0;j<nx;j  )
    {
       for(k=0;k<ny;k  )
           printf("%.1f ,%.1f ,%.1f ,%.1f ,%.1f ",M4[0][j][k],M4[1][j][k],M4[2][j][k],M4[3][j][k],M4[4][j][k]);
       printf("n");
    }

printf(" printing M5 Memcpy after deleting M6n");
    for(j=0;j<nx;j  )
    {
       for(k=0;k<ny;k  )
           printf("%.1f ,%.1f ,%.1f ,%.1f ,%.1f ",M5[0][j][k],M5[1][j][k],M5[2][j][k],M5[3][j][k],M5[4][j][k]);
       printf("n");
    }
 }