Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo
Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo
Per diversi giorni il Galaxy S26 Ultra di Samsung è stato il nostro compagno di vita. Oltre alle conferme del colosso coreano come la qualità del display e una suite AI senza rivali, arriva il Privacy Display, un unicum nel mondo smartphone. Ci sono ancora alcuni gap che non sono riusciti a colmare lato batteria e fotocamera, seppur con alcuni miglioramenti.
Diablo II Resurrected: il nuovo DLC Reign of the Warlock
Diablo II Resurrected: il nuovo DLC Reign of the Warlock
Abbiamo provato per voi il nuovo DLC lanciato a sorpresa da Blizzard per Diablo II: Resurrected e quella che segue è una disamina dei nuovi contenuti che abbiamo avuto modo di sperimentare nel corso delle nostre sessioni di gioco, con particolare riguardo per la nuova classe dello Stregone
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup
Siamo tornati nel parco tecnologico di Trieste per il kick-off del programma che mette a disposizione di cinque startup le infrastrutture di ricerca, dal sincrotrone Elettra ai laboratori di genomica e HPC. Roberto Pillon racconta il modello e la visione
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 10-01-2009, 00:11   #1
legolas977
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.
legolas977 è offline   Rispondi citando il messaggio o parte di esso
Old 10-01-2009, 00:41   #2
variabilepippo
Senior Member
 
L'Avatar di variabilepippo
 
Iscritto dal: Mar 2007
Messaggi: 1792
Puoi usare la funzione memcmp, ma sinceramente non so se sia un modo "veloce" rispetto al for per un array di 5 elementi.
variabilepippo è offline   Rispondi citando il messaggio o parte di esso
Old 10-01-2009, 11:08   #3
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da variabilepippo Guarda i messaggi
Puoi usare la funzione memcmp, ma sinceramente non so se sia un modo "veloce" rispetto al for per un array di 5 elementi.
Certo, e' una buona idea, e secondo me e' la piu' veloce (certo, 5 e' proprio pochino... ma oggi una chiamata a funzione e' quasi gratis)

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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 10-01-2009, 11:58   #4
legolas977
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
legolas977 è offline   Rispondi citando il messaggio o parte di esso
Old 10-01-2009, 21:29   #5
cionci
Senior Member
 
L'Avatar di cionci
 
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
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 09:58   #6
legolas977
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;
legolas977 è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 10:44   #7
cionci
Senior Member
 
L'Avatar di cionci
 
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 ?
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 11:15   #8
crick_pitomba
Member
 
Iscritto dal: Oct 1999
Messaggi: 111
Quote:
Originariamente inviato da legolas977 Guarda i messaggi

appo_valore=((long)(buffer[1]<<32))+((long)(buffer[2]<<24))+((long)(buffer[3]<<16))+((word)(buffer[4]<<8))+buffer[5];
come giustamente ha notato cionci stai pretendendo un po' troppo da un povero intero a 32 bit...

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
crick_pitomba è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 11:25   #9
cionci
Senior Member
 
L'Avatar di cionci
 
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
Scrivere esplicitamente:
Codice:
if(v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2] && v1[3] == v2[3] && v1[4] == v2[4])
   prorva_ok
è probabilmente più veloce di scrivere un for, ma sicuramente, almeno secondo il mio punto di vista, è meno leggibile.

Ultima modifica di cionci : 11-01-2009 alle 12:02.
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 11:39   #10
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
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;
O, meglio ancora (forse), nell'implementazione sotto intel based userei la REP CMPSB
__________________
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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 12:01   #11
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Che castroneria ho scritto sopra
Corretto
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 12:06   #12
Unrue
Senior Member
 
L'Avatar di Unrue
 
Iscritto dal: Nov 2002
Messaggi: 6789
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
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.
Perchè?
Unrue è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 12:14   #13
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da Unrue Guarda i messaggi
Perchè?
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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 13:06   #14
legolas977
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;
legolas977 è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 13:12   #15
legolas977
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
legolas977 è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 13:14   #16
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 13:18   #17
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da legolas977 Guarda i messaggi
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
Ma perche' questi shift?
Se proprio si dovesse passare da qui, e io non lo farei, basterebbe

Codice:
long* lp1 = (long*)buffer;
e poi confrontare tra loro i contenuti dei long*
__________________
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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 13:24   #18
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Quote:
Originariamente inviato da legolas977 Guarda i messaggi
for (a=0,c=1,c==5;a++,c++)
array[a]=buffer[c];
Ribadisco che la sintassi non è corretta, devi mettere un ; dopo c=1.
Memcmp ritorna 0 se non ci sono differenza. Sulla sintassi...ti ho riportato appositamente il link per leggerla
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 23:14   #19
crick_pitomba
Member
 
Iscritto dal: Oct 1999
Messaggi: 111
Quote:
Originariamente inviato da legolas977 Guarda i messaggi
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
si, l'idea è quella ma dovrebbe essere
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 ;
crick_pitomba è offline   Rispondi citando il messaggio o parte di esso
Old 11-01-2009, 23:59   #20
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Quote:
Originariamente inviato da crick_pitomba Guarda i messaggi
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
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.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione Samsung Galaxy S26 Ultra: finalmente qualcosa di nuovo Recensione Samsung Galaxy S26 Ultra: finalmente ...
Diablo II Resurrected: il nuovo DLC Reign of the Warlock Diablo II Resurrected: il nuovo DLC Reign of the...
Deep Tech Revolution: così Area Science Park apre i laboratori alle startup Deep Tech Revolution: così Area Science P...
HP OMEN MAX 16 con RTX 5080: potenza da desktop replacement a prezzo competitivo HP OMEN MAX 16 con RTX 5080: potenza da desktop ...
Recensione Google Pixel 10a, si migliora poco ma è sempre un'ottima scelta Recensione Google Pixel 10a, si migliora poco ma...
'Se avete RAM, siamo pronti ad acquistar...
Veeam corregge diverse vulnerabilit&agra...
MacBook Neo segna una svolta per Apple: ...
Polestar pubblica il report LCA di Poles...
Il rame non basta più: NVIDIA, AM...
Velocissimo e consuma poco: ecco il nuov...
Le migliori Offerte di Primavera sui Rob...
Perplexity 'Personal Computer' è ...
TV QLED da 65 pollici da 449€ con sconti...
Il CEO di Adobe pronto a lasciare dopo q...
Non è bastato il maxi-accordo col...
Gestire e proteggere i backup è s...
AI in mezzo all'oceano: turbine eoliche ...
IDC rivede le stime del mercato PC: crol...
Microsoft 365 Family 12 mesi a 89,99€ pe...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 15:38.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v