Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826

    [c++]copia array float

    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.

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    codice:
    memcpy(paperino, pippo, 6*sizeof(float));
    every day above ground is a good one

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da YuYevon
    codice:
    memcpy(paperino, pippo, 6*sizeof(float));
    io lo sconsiglio, sia perchè è "C" (e non C++), sia perchè non c'è garanzia nel padding e nella rappresentazione, in generale, dei tipi.
    può funzionare, oppure no. non c'è garanzia

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Un modo più "C++" sarebbe:
    codice:
    std::copy(pippo,pippo+6,paperino);
    Però in base all'impementazione (e VC++ la implementa), il tutto decade in:
    codice:
    memcpy(paperino, pippo, 6*sizeof(float));
    o meglio ancora usare std (boost) ::array;

    codice:
        array pippo<float,6> pippo;
        array pippo<float,6> paperino;
        // riempito pippo;
        paperino = pippo;

  5. #5
    Originariamente inviato da franzauker
    può funzionare, oppure no. non c'è garanzia
    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).

    @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.

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    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à.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    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).
    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.

    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

  8. #8
    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:
    When 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.
    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 che
    An object of array type contains a contiguously allocated non-empty set of N sub-objects of type T.
    e il "contiguously allocated" dovrebbe levare ogni dubbio (cfr. invece con le struct, dove invece si parla esplicitamente del padding che potrebbe essere richiesto).

    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:
    codice:
    size_t Dimensione = (size_t)(((unsigned char *)(array+NumElementi))-((unsigned char *)(array)));
    dato che
    • 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.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da MItaly
    Mi trovi completamente d'accordo per il punto 1, ma il punto 2 in linea teorica non si applica(...)
    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] MOVS

  10. #10
    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.
    Non conosci la libreria standard del C? Dacci un'occhiata spesso risulta veramente comoda.

    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.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.