Esiste una funzione per copiare un array in C / C ++?


93

Sono un programmatore Java che impara C / C ++. Quindi so che Java ha una funzione come System.arraycopy (); per copiare un array. Mi chiedevo se esiste una funzione in C o C ++ per copiare un array. Sono stato solo in grado di trovare l'implementazione per copiare un array utilizzando for loop, puntatori, ecc. C'è una funzione che posso usare per copiare un array?


7
man memmoveeman memcpy
Tim Cooper,

28
Non usare memcpy, usa std::copy. Se il tuo tipo ha un costruttore di copia significativo, allora memcpyfarà la cosa sbagliata.
Ed S.

10
Stai davvero cercando di imparare C e C ++ allo stesso tempo? Sono lingue molto diverse.
Ferruccio

1
Bene, ho imparato un po 'di C e ora ho iniziato a imparare C ++. Da quello che ho letto da una risorsa online, ho pensato che il C ++ fosse solo un linguaggio con molte funzionalità aggiuntive al linguaggio C.
JL

6
Dico questo perché nessuno lo ha menzionato prima: In C ++ dovresti usare std :: vector in quasi tutti i casi. Ci sono casi in cui sono utili anche altri contenitori, ma nella maggior parte dei casi std :: vector sarà l'opzione migliore. Non utilizzare array non elaborati in C ++ e cerca di evitare std :: array a meno che non sia necessario.
Skalli

Risposte:


79

A partire da C ++ 11, puoi copiare array direttamente con std::array:

std::array<int,4> A = {10,20,30,40};
std::array<int,4> B = A; //copy array A into array B

Ecco la documentazione su std :: array


@XAleXOwnZX: lo stesso che faresti con qualsiasi altro tipo che supporti l'assegnazione di copie. B = A.
Swalog

2
Penso che la funzione sia copiare l'indirizzo di memoria di A su B. Se provo a copiare i valori dell'elemento di A su B senza modificare l'indirizzo di memoria di B. Come lo posso fare?
Aaron Lee

@ Aaron_Lee: l'ho appena testato e copia veramente gli elementi in un array in una posizione di memoria separata. La classe array ha evidentemente un proprio sovraccarico per l'operatore di assegnazione.
Dave Rove

5
Ragazzi, vi rendete conto che nessun operatore di assegnazione appariva in quelle due righe di codice, giusto? Questo è il costruttore di copia che viene chiamato anche se la notazione assomiglia all'operatore di assegnazione.
Albino Cordeiro

143

Dato che hai chiesto una soluzione C ++ ...

#include <algorithm>
#include <iterator>

const int arr_size = 10;
some_type src[arr_size];
// ...
some_type dest[arr_size];
std::copy(std::begin(src), std::end(src), std::begin(dest));

2
erreur: 'begin' non è un membro di 'std'
David 天宇 Wong

23
@David 天宇 Wong: Stai usando un vecchio compilatore o non hai incluso l'intestazione. È in<iterator>
Ed S.

9
Forse dovresti dire quale include di cui hai bisogno. La copia è in <algorithm>?
Jerry Jeremiah

17
Chiedo solo perché se dovessi spiegare che std :: begin era in <iterator> ciò significa che le persone non stanno cercando su Google std :: begin per scoprire in quale intestazione si trova quindi è improbabile che Google std :: copy per lo stesso Motivo. È una risposta migliore se nessuno deve chiedere cose a cui si risponde solo nei commenti. Forse avrei dovuto modificare la risposta invece di chiederti di farlo.
Jerry Jeremiah

3
puoi cambiare inizio (src) in src e fine (src) in src + arr_size
Calvin

83

Come altri hanno già detto, in C useresti memcpy . Si noti tuttavia che questo esegue una copia di memoria non elaborata, quindi se le strutture di dati hanno un puntatore a se stesse o tra loro, i puntatori nella copia punteranno comunque agli oggetti originali.

In C ++ è possibile utilizzare anche memcpyse i vostri membri di matrice sono POD (che è, essenzialmente i tipi che si potrebbe anche avete usato invariato in C), ma in generale, memcpysarà non essere consentito. Come altri menzionati, la funzione da usare èstd::copy .

Detto questo, in C ++ raramente dovresti usare array non elaborati. Invece dovresti usare uno dei contenitori standard ( std::vectorè il più vicino a un array integrato, e penso anche il più vicino agli array Java - più vicino dei semplici array C ++, in effetti -, ma std::dequeo std::listpotrebbe essere più appropriato in alcuni casi) oppure, se usi C ++ 11,std::array che è molto simile agli array incorporati, ma con semantica dei valori come altri tipi C ++. Tutti i tipi che ho menzionato qui possono essere copiati per incarico o copia di costruzione. Inoltre, puoi eseguire il "cross-copy" da opne a un altro (e persino da un array integrato) utilizzando la sintassi dell'iteratore.

Questo fornisce una panoramica delle possibilità (presumo siano state incluse tutte le intestazioni pertinenti):

int main()
{
  // This works in C and C++
  int a[] = { 1, 2, 3, 4 };
  int b[4];
  memcpy(b, a, 4*sizeof(int)); // int is a POD

  // This is the preferred method to copy raw arrays in C++ and works with all types that can be copied:
  std::copy(a, a+4, b);

  // In C++11, you can also use this:
  std::copy(std::begin(a), std::end(a), std::begin(b));

  // use of vectors
  std::vector<int> va(a, a+4); // copies the content of a into the vector
  std::vector<int> vb = va;    // vb is a copy of va

  // this initialization is only valid in C++11:
  std::vector<int> vc { 5, 6, 7, 8 }; // note: no equal sign!

  // assign vc to vb (valid in all standardized versions of C++)
  vb = vc;

  //alternative assignment, works also if both container types are different
  vb.assign(vc.begin(), vc.end());

  std::vector<int> vd; // an *empty* vector

  // you also can use std::copy with vectors
  // Since vd is empty, we need a `back_inserter`, to create new elements:
  std::copy(va.begin(), va.end(), std::back_inserter(vd));

  // copy from array a to vector vd:
  // now vd already contains four elements, so this new copy doesn't need to
  // create elements, we just overwrite the existing ones.
  std::copy(a, a+4, vd.begin());

  // C++11 only: Define a `std::array`:
  std::array<int, 4> sa = { 9, 10, 11, 12 };

  // create a copy:
  std::array<int, 4> sb = sa;

  // assign the array:
  sb = sa;
}

1
L'esempio di memcpy è sbagliato; l'origine e la destinazione vengono cambiate.
AT - studente

1
In realtà, quello non era l'unico errore memcpynell'esempio; anche la dimensione era sbagliata. Ora l'ho risolto, grazie.
celtschk

perché stai scrivendo std tutto il tempo invece di usare solo lo spazio dei nomi di std ???
Nero

non puoi fare memcpy (b, a, sizeof a); pure?
rodi

Un array Java è più simile std:arrayche simile std::vector, perché ha una dimensione fissa.
Bart van Heukelom

17

Puoi usare il memcpy(),

void * memcpy ( void * destination, const void * source, size_t num );

memcpy()copia i valori dei numbyte dalla posizione puntata da sourcedirettamente al blocco di memoria puntato da destination.

Se destinatione si sourcesovrappongono, puoi usare memmove().

void * memmove ( void * destination, const void * source, size_t num );

memmove()copia i valori dei numbyte dalla posizione puntata da sourceal blocco di memoria puntato da destination. La copia avviene come se fosse utilizzato un buffer intermedio, consentendo la sovrapposizione di destinazione e sorgente.


3
Devo -1 qui. L'OP richiede specificamente una soluzione C ++ e questa risposta non dice nulla delle situazioni in cui memcpyè sbagliato, cioè, la copia dei byte è insufficiente.
Ed S.

2
@EdS. Nel caso non l'avessi notato, l'OP ora richiede una soluzione C o C ++.
autistico

4
Quando ho risposto all'OP chiedevo soluzioni C / C ++, anche se personalmente credo che "C / C ++" sia un insulto per entrambi i linguaggi. :)
Deepu

abbastanza giusto, non mi rendevo conto che stava cambiando. Forse l'ha anche detto prima e l'ho perso. -1 rimosso.
Ed S.

2
@EdS Pensavo fossero 2 minuti, ma a prescindere, nel momento in cui è stata pubblicata questa risposta, la domanda si riferiva sia a C che a C ++. Anche se mi sbagliavo e la domanda a un certo punto diceva solo C ++, il voto negativo non era garantito.
Jim Balter

16

Usa memcpyin C, std::copyin C ++.


Per un piccolo array presumo che nessuno dei due incorra in alcun overhead di chiamata di funzione ( memcpydovrebbe essere un compilatore intrinseco)?
wcochran

@ Mehrdad non ho detto diversamente; sto solo facendo un commento. E non l'ho nemmeno svalutato.
MD XF

12

Mi piace la risposta di Ed S., ma funziona solo per array di dimensioni fisse e non quando gli array sono definiti come puntatori.

Quindi, la soluzione C ++ in cui gli array sono definiti come puntatori:

#include<algorithm>
...
const int bufferSize = 10;
char* origArray, newArray;
std::copy(origArray, origArray + bufferSize, newArray);

Nota : non è necessario detrarre buffersizecon 1:

  1. Copia tutti gli elementi nell'intervallo [primo, ultimo) a partire dal primo e procedendo fino all'ultimo - 1

Vedi: https://en.cppreference.com/w/cpp/algorithm/copy


10

In C puoi usare memcpy. In C ++ usa std::copydall'intestazione <algorithm>.


3

in C ++ 11 puoi usare Copy()che funziona per i contenitori std

template <typename Container1, typename Container2>
auto Copy(Container1& c1, Container2& c2)
    -> decltype(c2.begin())
{
    auto it1 = std::begin(c1);
    auto it2 = std::begin(c2);

    while (it1 != std::end(c1)) {
        *it2++ = *it1++;
    }
    return it2;
}

Sarebbe un'idea migliore estrarre il std::endciclo, per motivi di prestazioni (c1 non cambia o invalida gli iteratori durante il ciclo, quindi non è necessario ricalcolare la fine).
celtschk

3

Fornisco qui 2 modi per gestire gli array, per il linguaggio C e C ++. memcpy e copy sono entrambi utilizzabili su C ++ ma copy non è utilizzabile per C, devi usare memcpy se stai cercando di copiare array in C.

#include <stdio.h>
#include <iostream>
#include <algorithm> // for using copy (library function)
#include <string.h> // for using memcpy (library function)


int main(){

    int arr[] = {1, 1, 2, 2, 3, 3};
    int brr[100];

    int len = sizeof(arr)/sizeof(*arr); // finding size of arr (array)

    std:: copy(arr, arr+len, brr); // which will work on C++ only (you have to use #include <algorithm>
    memcpy(brr, arr, len*(sizeof(int))); // which will work on both C and C++

    for(int i=0; i<len; i++){ // Printing brr (array).
        std:: cout << brr[i] << " ";
    }

    return 0;
}

4
using namespace std;è una cattiva pratica . Non usarlo mai. Invece di cplusplus.com, utilizzare cppreference.com, che include una documentazione molto migliore e aggiornata dello standard. L' stdio.hequivalente in C ++ è cstdio, usalo invece. Inoltre, il codice è un C ++ abbastanza non idiomatico. Penso che sarebbe molto più chiaro se avessi mostrato soluzioni separate per C e C ++.
tambre

3

Basta includere la libreria standard nel codice.

#include<algorithm>

La dimensione dell'array sarà indicata come n

Il tuo vecchio Array

int oldArray[n]={10,20,30,40,50};

Dichiara New Array in cui devi copiare il tuo vecchio valore di array

int newArray[n];

Usa questo

copy_n(oldArray,n,newArray);

1

In primo luogo, poiché stai passando a C ++, si consiglia di utilizzare il vettore al posto del tradizionale array . Inoltre, copiare un array o un vettore std::copyè la scelta migliore per te.

Visita questa pagina per scoprire come utilizzare la funzione di copia: http://en.cppreference.com/w/cpp/algorithm/copy

Esempio:

std::vector<int> source_vector;
source_vector.push_back(1);
source_vector.push_back(2);
source_vector.push_back(3);
std::vector<int> dest_vector(source_vector.size());
std::copy(source_vector.begin(), source_vector.end(), dest_vector.begin());
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.