|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Jul 2007
Messaggi: 58
|
[C] Confrontare elementi array
Ho due array di 5 elementi.
Esiste un modo veloce per poter confrontare i due array per appurare che contengano gli stessi valori? Senza dover utilizzare for etc? Grazie saluti. |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Ma solo se l'array e' fatto direttamente di valori. Se e' fatto di puntatori e si vuole confrontare l'uguaglianza degli elementi contenuti ovviamente non va bene.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
|
#4 |
|
Member
Iscritto dal: Jul 2007
Messaggi: 58
|
In pratica vi spiego meglio il mio problema, che si risolva con array o altro è la stessa cosa:
Mi trovo ad avere 5 byte da salvare e riconfrontare. La prima prova che ho fatto è stata questa: Solo che oltre il long (4 byte), è un incasino impaccarli, perchè occorre assegnare la variabile double, e quando unisco i 5 byte in questo modo,coi cast il borland impazzisce: double valore; double appo_valore appo_valore=((long)(buffer[1]<<32))+((long)(buffer[2]<<24))+((long)(buffer[3]<<16))+((word)(buffer[4]<<8))+buffer[5]; if (appo_valore==0x1122334455l) prova_ok; else prova_non_ok; (Fatto nel modo sopra, putroppo ha dei problemoni) In alternativa allora ho pensato di salvarmi con un for i 5 elementi del buffer all'interno di un mio array di 5 elementi: char array[5]; char appo_array[5]={11,22,33,44,55}; char appo_array2[5]={22,22,33,44,00}; char appo_array3[5]={33,22,33,44,00}; for (a=0,c=1,c==5;a++,c++) array[a]=buffer[c]; A questo punto però volevo trovare un modo comodo per confrontare array con i vari appo_array,per non scrivere tanto codice tutte le volte che andrò ad aggiungere dei nuovi appo_array. Potete aiutarmi? Grazie mille |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Chiaro che è un casino, stai cercando di mettere 5 byte in un intero che ne contiene 4.
Questo: buffer[1] << 32 ha come risultato 0. Il confronto più semplice lo puoi appunto fare con memcmp: http://www.cplusplus.com/reference/c...ng/memcmp.html |
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Jul 2007
Messaggi: 58
|
scritto cosi:
Puo andar bene cosi?
Si puo sintetizzare di più? grazie char array[5]; char appo_array[5]={11,22,33,44,55}; char appo_array2[5]={22,22,33,44,00}; char appo_array3[5]={33,22,33,44,00}; b,d,e char; for (a=0,c=1,c==5;a++,c++) array[a]=buffer[c]; b = memcmp (appo_array, array,5); if (b) prova_non_ok; else prova_ok; d = memcmp (appo_array2, array,5); if (d) prova_non_ok; else prova_ok; e = memcmp (appo_array3, array,5); if (e) prova_non_ok; else prova_ok; |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quel for non è corretto, cosa vuoi fare ?
|
|
|
|
|
|
#8 | |
|
Member
Iscritto dal: Oct 1999
Messaggi: 111
|
Quote:
tuttavia per il confronto il metodo è effettivamente più veloce rispetto al for col for hai 5 confronti + l'overhead nel caso di tutti i valori impacchettati in un solo valore hai un solo confronto e se il valore deve essere confrontato più volte vale la pena fare lo sforzo di impacchettare i valori. provo a suggerirti un'alternativa impacchetta 4 valori in un long e lasci il quinto nel char long valore=((long)(buffer[2]<<24))+((long)(buffer[3]<<16))+((word)(buffer[4]<<8))+buffer[5]; e lasci buffer[1] in un char poi if (valore == LowLongCONST1) && (buffer[1]==HiByteCONST1) prova_ok else prova_non_ok LowLongCONST1 contiene i 4 byte meno significativi del valore che devi confrontare e HiByteCONST1 il byte più significativo (o mettili come più ti aggrada... Li ho messi così perchè se ad esempio hai 5 valori di confronto che potrebbero iniziare con lo stesso valore puoi mettere il confronto col byte più significativo in evidenza e saltare 5 confronti in una volta sola se il byte iniziale non è quello atteso) il vantaggio in questo caso è avere al massimo 2 confronti (se fallisce il primo il secondo non viene effettuato) per confrontare questa soluzione con memcmp, bisognerebbe sapere memcmp come è implementata puoi provare a fare qualche decina di migliaia di confronti con questa soluzione e con quella con memcmp prendere i tempi e vedere tra le due quale è più efficiente |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Sicuramente è più efficiente fare il confronto byte a byte che usare memcmp...ma poi non capisco perché tu non voglia usare un for. Nota che memcmp è di fatto implementata con un for.
L'implementazione di memcmp è qualcosa di questo tipo: Codice:
for(i = 0; i < n; i++)
{
if(*((char *)ptr1 + i) != *((char *)ptr2 + i))
return *((char *)ptr1 + i) - *((char *)ptr2 + i);
}
return 0
Codice:
if(v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2] && v1[3] == v2[3] && v1[4] == v2[4]) prorva_ok Ultima modifica di cionci : 11-01-2009 alle 12:02. |
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Giocando con i puntatori si possono limitare i confronti ad essere solo 2.
Ma io continuo a votare per la memcmp. Piu' compatta, meno errori e piu' chiara (almeno per molti) E forse anche piu' veloce del ciclo for, a meno che al posto dell'indice non si cicli direttamente su puntatori. Penso che la memcmp lavori con puntatori direttamente al posto degli indici. Almeno, io la scriverei cosi' (non ho provato a compilare ne ovviamente ad eseguire) Codice:
for(char* u1=ptr1, char* u2=ptr2, i=0; i<5; i++, u1++, u2++)
{
char val = *u1-*u2;
if (val!=0) return val;
}
return 0;
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 11-01-2009 alle 11:46. |
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Che castroneria ho scritto sopra
Corretto |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Nov 2002
Messaggi: 6789
|
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Intendo, se l'array al posto che contenere direttamente dei valori contenesse elementi complessi, ovvero fosse un puntatore di puntatori, ovviamente confrontare tra loro i puntatori di tali elementi non garantirebbe l'uguaglianza o la diversita' del loro contenuto.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#14 |
|
Member
Iscritto dal: Jul 2007
Messaggi: 58
|
""Quel for non è corretto, cosa vuoi fare ?""
Salvo nell'array "array" (nelle posizioni dalla 0 alla 4) valori che mi arrivano su un buffer (dalla posizione 1 alla 5). Poi dovrei confrontare singolarmente: "array" con "appo_array", "array" con "appo_array2", "array" con "appo_array3" Ma la sintassi del memcmp è arabo. Io appunto avevo provato a far cosi: char array[5]; char appo_array[5]={11,22,33,44,55}; char appo_array2[5]={22,22,33,44,00}; char appo_array3[5]={33,22,33,44,00}; b,d,e char; for (a=0,c=1,c==5;a++,c++) array[a]=buffer[c]; b = memcmp (appo_array, array,5); if (b) prova_non_ok; else prova_ok; d = memcmp (appo_array2, array,5); if (d) prova_non_ok; else prova_ok; e = memcmp (appo_array3, array,5); if (e) prova_non_ok; else prova_ok; |
|
|
|
|
|
#15 |
|
Member
Iscritto dal: Jul 2007
Messaggi: 58
|
Fatto in alternativa nel modo seguente:
-------- long valore=((long)(buffer[2]<<24))+((long)(buffer[3]<<16))+((word)(buffer[4]<<8))+buffer[5]; e lasci buffer[1] in un char poi if (valore == LowLongCONST1) && (buffer[1]==HiByteCONST1) prova_ok else prova_non_ok ------------- Dovrei dichiarare "LowLongCONST1" come long e "HiByteCONST1" come char e assegnarli i valori per poterli poi utilizzare da confronto? Ad esempio: long LowLongCONST1[4] ={11,12,13,14}; char HiByteCONST1[1]={15}; Cosi andrebbe bene crick_pitomba ? Grazie mille |
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
non e' necessario usare l'array di appoggio, puoi confrontare direttamente su buffer.
Se proprio devi copiare i valori dell'array, userei memcpy, e non il ciclo for. Per sapere se 3 array diversi contengono gli stessi valori, non e' necessario effettuare 3 cicli di confronti. Per la proprieta' transitiva se A==B e B==C allora A==C per forza.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quote:
Se proprio si dovesse passare da qui, e io non lo farei, basterebbe Codice:
long* lp1 = (long*)buffer;
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
|
|
|
|
|
|
#19 | |
|
Member
Iscritto dal: Oct 1999
Messaggi: 111
|
Quote:
long LowLongCONST1 = 0x11121314; char HiByteCONST1=0x15; nel modo in cui tu hai indicato avresti 4 long con i valori 11,12,13,14 (giuto cionci? il mio c è irrimediabilmente arrugginito) mi è piaciuta la soluzione di gugoxx che riduce ulteriormente il costo abolendo anche gli shift... molto elegante, anche se in questo caso sarebbe interessante vedere a basso livello la cosa come funziona: se i byte non sono correttamente allineati quel cast ha comunque un costo in termini di shift. Indipendentemente da questo c'è sempre un problema molto serio e ti spiego per quale motivo potrebbe essere necessario usare gli shift: su piattaforma intel un cast interpreterebbe il valore come little endian e questo potrebbe creare dei problemi per ottenere il valore 0x00929190 devo avere un buffer di questo tipo buffer[4]={0x90,0x91,0x92,0x0}; solo in questo caso il cast *(long *)buffer restituirebbe 0x00929190 era questo il motivo per cui non ho toccato gli shift nella mia risposta iniziale: di solito gli header o alcuni caratteri di controllo di alcuni formati di file usano il sistema big-endian (ad esempio i marker jpg) quindi gli shift ti servono per ricostruire l'header del file in formato little endian. insomma se non sappiamo esattamente lui cosa deve fare discutere su cosa sia meglio è inutile... la mia soluzione era semplicemente la più vicina al suo codice continuando a non usare i cicli for... e preservando la costruzione del dato A scatola chiusa, voi tutti potreste avere ragione... ho visto cose nel corso degli anni veramente raccapriccianti. la soluzione più semplice potrebbe essere scrivere una funzione di confronto esterna da chiamare in questo modo mycmp(buffer, "app0") se gli appo sono in formato testuale oppure mycmp(buffer, constval) dove constval è un intero a 64 bit se il compilatore consente questo tipo di variabile entrambe con un ciclo for all'interno... e l'opportuna "logica" per il confronto oppure usare come avete correttamente suggerito memcmp insomma le soluzioni possibili sono infinite per problemi di questo genere bisogna solo sapere uno cosa deve fare. Ultima modifica di crick_pitomba : 11-01-2009 alle 23:14. Motivo: ps. cionci ha ragione.... ci vuole un ; |
|
|
|
|
|
|
#20 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
Quale che sia, little o big endian, se devo confrontare 2 serie da 4 byte e lo faccio mediante un long, non importa la loro codifica. Verranno letti e codificati allo stesso modo, e il confronto sara' corretto.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:38.




















