#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");
}
}