ciao.
Come si fa a copiare "in un colpo solo" un array ad es di float?
se ho un :
float pippo[6];
e
float paperino[6]
vorrei copiare tutti i valori di pippo in paperino.
Se uso il memcpy è corretto?
com è precisamente la sintassi?
grazie.
ciao.
Come si fa a copiare "in un colpo solo" un array ad es di float?
se ho un :
float pippo[6];
e
float paperino[6]
vorrei copiare tutti i valori di pippo in paperino.
Se uso il memcpy è corretto?
com è precisamente la sintassi?
grazie.
codice:memcpy(paperino, pippo, 6*sizeof(float));
every day above ground is a good one
io lo sconsiglio, sia perchè è "C" (e non C++), sia perchè non c'è garanzia nel padding e nella rappresentazione, in generale, dei tipi.Originariamente inviato da YuYevon
codice:memcpy(paperino, pippo, 6*sizeof(float));
può funzionare, oppure no. non c'è garanzia
Un modo più "C++" sarebbe:
Però in base all'impementazione (e VC++ la implementa), il tutto decade in:codice:std::copy(pippo,pippo+6,paperino);
o meglio ancora usare std (boost) ::array;codice:memcpy(paperino, pippo, 6*sizeof(float));
codice:array pippo<float,6> pippo; array pippo<float,6> paperino; // riempito pippo; paperino = pippo;
Cioè?!Originariamente inviato da franzauker
può funzionare, oppure no. non c'è garanzia
Aparte che memcpy è standard, e poi "è C non è C++" non significa molto se consideri che molto della libreria standard del C++ in realtà non fa altro che richiamare funzioni tipiche del C come ad esempio la stessa memcpy, ottima a mio parere per casi del genere (probabilmente la migliore).
@shodan: se non ricordo male i boost::array utilizzano proprio la std::copy per l'overloading dell'operaotre di assegnamento (cosi come per il costruttore di copia).
Fracty - The Fractal Generator
If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.
Si, ma volevo evidenziare la facilità di gestione rispetto a un normale array C.
L'unico svantaggio è che non si può passare così com'è a una libreria / DLL che si aspetta un array C, ma non sapendo che ci deve fare l'OP ho suggerito anche questa possibilità.
1) che "libreria standard"? E' proprio l'idea stessa di usare "brutalmente" un puntatore così che è contro TUTTA la "logica" di C++. Almeno così mi disse Stroustrup, penso non ci siano state modifiche.Originariamente inviato da GliderKite
Cioè?!
Aparte che memcpy è standard, e poi "è C non è C++" non significa molto se consideri che molto della libreria standard del C++ in realtà non fa altro che richiamare funzioni tipiche del C come ad esempio la stessa memcpy, ottima a mio parere per casi del genere (probabilmente la migliore).
2) Dai per scontato che i float vengano allocati in blocchi contigui, senza padding.
Questo può essere (solitamente è) vero, ma non lo è sempre, o meglio "non necessariamente", soprattutto con CPU non-Intel.
Questa è una situazione più "delicata"; al 99.9999% non c'è padding per i tipi "atomici"; mentre può esserci (e spesso c'è) per strutture più complesse, una struct, ad esempio (per non dire classi).
sizeof è sempre, diciamo così... delicata.
Il punto "1" discrimina "scrivere in C con C++" oppure "scrivere in C++", che sono due cose ben diverse.
Il punto "2" è meno rilevante, più per "puristi" che di uso comune.
PS anzi riformulo: va benissimo come è stato indicato
Mi trovi completamente d'accordo per il punto 1, ma il punto 2 in linea teorica non si applica. I float infatti sono "arithmetic types", i quali a loro volta sono POD, e gli array di POD sono a loro volta POD (§3.9, ¶10). Per ogni tipo POD, si applica la regola descritta a §3.9, ¶3 per cui si possono copiare senza problemi con la memcpy specificando però correttamente le dimensioni del tipo; il busillis starebbe qui: se lo standard non garantisse che le dimensioni dell'array sono uguali al prodotto delle dimensioni del tipo base avremmo un problema. A §5.3.3, ¶2 si dice:
il che fa ben sperare, anche se viene da chiedersi se per "element" si possa intendere il tipo e il suo padding; d'altra parte a §8.3.4, ¶1 si dice chiaramente cheWhen applied to an array, the result is the total number of bytes in the array. This implies that the size of an array of n elements is n times the size of an element.
e il "contiguously allocated" dovrebbe levare ogni dubbio (cfr. invece con le struct, dove invece si parla esplicitamente del padding che potrebbe essere richiesto).An object of array type contains a contiguously allocated non-empty set of N sub-objects of type T.
Tutto questo in teoria; se poi in giro ci siano delle implementazioni che fanno diversamente (che per questo risultano quindi automaticamente non-standard) non saprei dire.
Tra l'altro, anche se non valesse l'assunto che non c'è padding tra gli elementi, per ottenere le dimensioni in memoria dell'array (cosa che serve a memcpy) noto il suo numero di elementi, dovrebbe essere sufficiente fare:
dato checodice:size_t Dimensione = (size_t)(((unsigned char *)(array+NumElementi))-((unsigned char *)(array)));
- array+NumElementi punta al (NumElementi+1)-esimo elemento sicuramente, dato che la sintassi array[i] è equivalente a *(array+i) (§8.3.4 ¶6), e, se non funzionasse quella prima sintassi, questi array sarebbero inutilizzabili ;
- array punta al primo elemento;
- la conversione a unsigned char * è sempre possibile per i puntatori a POD;
- l'unità di misura della memoria (usata da sizeof) è sizeof(char)==sizeof(unsigned char), e la differenza tra i due puntatori in questione pertanto è il numero di byte che compongono l'array;
- la (falsa) conversione da ptrdiff_t a size_t è lecita, dato che stiamo di fatto ottenendo la dimensione di un oggetto, e size_t può contenere valori di questo genere per definizione.
In ogni caso, rinnovo anch'io il consiglio ad usare std::copy; in primo luogo, è il modo idiomatico C++ per copiare degli elementi, in linea di principio meno libreria C si vede in un programma C++ meglio è.
Poi, anche se non valesse l'assunzione che non c'è padding tra gli elementi dell'array, std::copy non può fare casino, dato che, per effettuare la copia, usa puntatori al tipo corretto, quindi effettivamente copia gli elementi uno ad uno. Inoltre, std::copy funziona correttamente anche per i tipi non-POD, con i quali memcpy al 90% combina casini strani.
Poi probabilmente, se usata con POD, il compilatore dovrebbe essere sufficientemente intelligente per ottimizzarla con una chiamata a memcpy o roba analoga, per cui non si dovrebbe perdere nulla in efficienza.
Amaro C++, il gusto pieno dell'undefined behavior.
a mio parere, riassumendo, si può fare come si vuole, anzi in realtà c'è proprio l'istruzione opportuna per la copia di stringhe di memoria [REP] MOVSOriginariamente inviato da MItaly
Mi trovi completamente d'accordo per il punto 1, ma il punto 2 in linea teorica non si applica(...)
Non conosci la libreria standard del C? Dacci un'occhiata spesso risulta veramente comoda.Originariamente inviato da franzauker
1) che "libreria standard"? E' proprio l'idea stessa di usare "brutalmente" un puntatore così che è contro TUTTA la "logica" di C++. Almeno così mi disse Stroustrup, penso non ci siano state modifiche.
Mi discpiace che Stroustrup ti abbia detto questa cosa, perchè se c'è un buon motivo per imparare linguaggi di programmazione come il C/C++ è proprio per la possibilità di utilizzare puntatori in forma "bruta", ma se non si conosce cosa ci sta dietro o non si amplia la mente per poter davvero capire cosa si è in grado di fare tramite l'utilizzo dei puntatori ci si limiterà sempre alla conoscenza (che comunque non è cosa da poco, forse) delle librerie belle e pronte. Questo per me non significa saper programmare, assolutamente.
E comunque vorrei sottolineare che sia la mia risposta, ma in particolar modo la richiesta, si basano sul fatto che l'array sia di tipo float. Quindi ribadisco al 100% quello che ho precedentemente affermato.
Fracty - The Fractal Generator
If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.