Newsgroup: it.comp.lang.c
Titolo: Invertire stringa in modo ricorsivo

Salve a tutti , qualcuno può
darmi dei suggerimenti per
fare una piccola funzione
che inverta una stringa
richiamando la stessa
in modo ricorsivo?
Grazie a tutti
Ciao

 in modo ricorsivo?
void reverse( char *s )
{
  int i;
  if( ( i = strlen( s ) ) > 0 ) {
  	putchar( s[ i - 1 ] );
  	s[ i - 1 ] = '\0';
  	reverse( s );
  }
  else
  	putchar( '\n' );
}
Ciao
-- 
oOO()             |Nicholas Wieland|
/ _/              |nicholas_wieland|
|/ [ Step on the ]|    @
yahoo.it
   |
\_)[  right foot ]|________________|

 
La tua soluzione non e' immune da side-effect.
E' preferibile la seguente :
void reverse( char *s )
{
  if(strlen(s)>0)
  {
   reverse(s+1) ;
   putchar(s[0]) ;
  }
}
ciao
Luca

 ciao


 > }
Si pero' a questo punto la lunghezza della stringa non e' piu' una
informazione necessaria se non per il fatto di capire che la stringa e'
terminata.
Al posto di
if(strlen(s)>0)
e' meglio
if(s[0]!='\0')

in modo ricorsivo?
Inverta in che senso?!? SI diventi NO, oppure SI diventi IS, oppure SI
diventi .... Sto scherzando ma ... se avessi detto (ad esempio se questo e'
quello che chiedi):
Salve a tutti, qualcuno puo' darmi dei suggerimenti per fare una piccola
funzione che riceve una stringa e ricorsivamente stampi uno alla volta i
caratteri di questa stringa nell'ordine inverso?
Con un testo del genere capisco cosa vuoi! Da quello che dici potrei fartene
una ricorsiva che stampa i caratteri a due a due !
Oppure che non stampa nulla ma che inverte l'ordine dei caratteri nella
striga stessa etc....
Tommy

 if(s[0]!='\0')
potrebbe anche essere:
if(s[0])
Tommy

if(s[0])
ANZI, io farei cosi:
<CODE>
void Reverse(char *s)
{
     if(*s){
          Reverse(s+1);
          putchar(*s);
     }
}
</CODE>
Ma l'algoritmo non cambia, no?!?
if(strlen(s)>0)  ->  if(s[0]!='\0')  ->  if(*s)
E' vero che con strlen era un attimo piu' dispendiosa cmq.
Avevo solo voglia di divertirmi ;-)
Tommy

 ha scritto nel messaggio
news:aveqdv$a5e$1...@venus.btinternet.com...

Certo ma a livello assembler non cambia nulla ed esprimere il fine stringa
con '\0' e' sicuramente meglio di 0.

 con '\0' e' sicuramente meglio di 0.
Di questo no sono tanto convinto, specialmente visto che non ho nemmeno
usato 0 esplicitamente!
Con '\0' e' forse piu' leggibile, ma dopo che uno si abitua al C, beh, non
ci vedo tanta differenza!
Tommy

 ci vedo tanta differenza!
Il problema sta nel fatto che non sono stato io a postare su un tuo
intervento dicendo che '\0' era meglio di 0 ma esattamente il contrario.
Di conseguenza ti ho semplicemente fatto notare che se ci doveva essere una
forma da preferire quella era lo '\0'.
Forse hai travisato il mio  primo intervento sullo strlen.
Ti vorrei far notare che quello strlen comprometteva la complessita' di
quella pur semplice funzione.
Quando si crea del codice sorgente le scelte da fare sono solitamente
orientate tra la  sua leggibilita' , la sua modificabilita' e soprattuto le
sue performance.
Risparmiare di scrivere un carattere non ha alcuna priorita'.

 Questo e' un motivo, ma ce ne sono anche altri.
TI RIPETO DIMMELI !!!!!!
NON CE NE SONO, E' UGUALE ED ANCHE TU USI LO 0 IMPLICITAMENTE.
Tommy

 NON CE NE SONO, E' UGUALE ED ANCHE TU USI LO 0 IMPLICITAMENTE.
La risposta la trovi sul testo che tu stesso hai riportato
"per enfatizzare la natura alfanumerica"
cio' non vuol dire solo migliore leggibilita' ma anche che equivale a
scrivere ((char)0) con conseguenti ed eventuali controlli di tipo.
Certo sono caxxate e non mi sognerei mai di riprendere qualcuno perche ha
usato 0 al posto di '\0' ma mi aspetto che nessuno abbia da ridire sul fatto
che qualcuno usi lo '\0'.
E' nota che non sono arrabiato ho semplicemente interpretato (probabilmente
male interpretato) il tuo intervento come una ottimizzazione al codice.
Ciao,
Drago.

 A quel punto i toni però si erano gia' fatti aspri.
???? ASPRI ?!?
<QUOTE>
Ma l'algoritmo non cambia, no?!?
Avevo solo voglia di divertirmi ;-)
</QUOTE>
Beh, chiudo questo post senza commento altrimenti non si finisce mai.....
sperando che questo thread si fermi!

 ha scritto nel messaggio
news:avf83e$nn9$1...@knossos.btinternet.com...

Ahimè è evidente che non sono stato chiaro.
STOP anche x me.

 wrote:

Qualche tempo fa ho provato a realizzare una 
funzione ricorsiva che invertisse una stringa, ma non ci ero 
riuscito; oggi quando ho visto la tua domanda ci ho provato 
ecco il risultato:
#include <stdio.h>
#include <string.h>
char*  reverse(char* a, size_t s1, size_t s2)
{char tmp;
 if(s1>=s2)
       return a;
 tmp=a[s1]; a[s1]=a[s2]; a[s2]=tmp;
 return reverse(a, ++s1, --s2);
}
int main()
{char  s[]="esrever";
 reverse(s, 0, strlen(s)-1);
 printf("%s :) \n", s);
 return 0;
}

>  tmp=a[s1]; a[s1]=a[s2]; a[s2]=tmp;
non c'è bisogno di usare una variabile tmp per fare lo scambio di due
variabili,
basta usare lo XOR.
ciao




Si e' vero non e' necessario avere una 3a variabile. Ma se uno puo' averla,
se uno non e' limitato a max due variabili, perche' mai non utilizzare una
bella variabile tmp ?!?
Tommy

 if(s[0]!='\0')
mmm, secondo il C99, va bene 
if (*s) 
oppure no?



Va bene per il C, in generale, a prescindere dall'ultimo standard.

basta usare lo XOR.
Si, ma bisogna stare attenti al suo utilizzo (in determinate
circostanze, non e` portabile, vedi le FAQ di comp.lang.c).
L'uso di una variabile temporanea e` da consigliare per motivi di
leggibilita`.

 }
Allora si puo' anche scrivere cosi' :
#include <stdio.h>
#include <string.h>
 
void reverse(char * first, char * last )
 {
  char tmp;
  if( last > first )
  {
   tmp = *first; *first = *last; *last = tmp;
   reverse( first+1 , last-1 );
  } 
 }
 
 int main()
 {
  char  s[]="esrever";
  reverse(s, s+strlen(s)-1);
  printf("%s :) \n", s);
  return 0;
 }
bye
Luca

...
...non litigate, e' appena passato il Natale ;-)
'\0'  e' una costante di tipo char
0     e' una costante di tipo int
per motivi di "eleganza formale" (sulle prestazioni non saprei,
dipende dal compilatore e dalla macchina) e' "preferibile" scrivere
char c = '\0' ;
piuttosto che
char c = 0;
anche se i criteri di cast automatico del C rendono le cose
perfettamente equivalenti dal punto di visto semantico.
ciao 
Luca

 0     e' una costante di tipo int
   A dire il vero, le costanti carattere sono anch'esse di tipo int (in 
C, non in C++).
-- 
Alla prossima,
Marco

'\0'  e' una costante di tipo char
In C (almeno fino al C89) le costanti carattere sono di tipo intero.
Non e` cosi` in C++, tuttavia.

 char c = 0;
Concorde! ricordo che io ho usato semplicemente c pero' !!!
Ti spiego. Supponiamo che s[0] abbia valore 0:
se uno scrive if(s[0]!='\0'); s[0]!='\0' viene valutato e corrispondera' e
si avra' il seguente:
if(0!='\0'); ora questo viene trasformato in
if(0) metto zero ma potrei dire FALSE per essere piu' chiaro.
Invece io facevo:
if(*s); che diventa direttamente
if(0).
Ora ogni compilatore decente genera lo stesso codice assembler. NON HO MAI
DETTO CHE SIA MEGLIO COSI'!
Anzi, ho detto che mettendo la cosa per intero e' uguale, e se vogliamo piu'
leggibile.
Quello che sto cercando di dire e' che se usassi s[0]!=0 invece di
s[0]!='\0' il discorso mi starebbe anche bene (quello del controllo di
tipo...) ma cosi'....:
In pratica dire che '\0' e' meglio oltre che per motivi di leggibilita'
anche per controlli di tipo, come diceva drago: ((char)0), mi puo' stare al
limite anche bene, ma .... se uno usa lo 0 esplicitamente! Usarlo
implicitamente come ho fatto io salta un passaggio, non crea quel passaggio
con 0 invece di '\0' come forse pensate visto che non capite il mio punto!
Ovviamente tutto questo e' ridicolo visto che il codice macchina prodotto
nel 99% per cento dei casi e' identico.
Tommy

 Concorde! ricordo che io ho usato semplicemente c pero' !!!
Come mi hanno ricordato gli altri, le costanti carattere sono int in C.
Quindi confermo di essere concorde con te e Drago solo per i motivi di
leggibilita'.
Tommy

basta usare lo XOR
cioe'
a[s1]^=a[s2]; a[s2]^=a[s1]; a[s1]^=a[s2];?
fossi in te non ne sarei cosě sicuro: prova con "allergia"

 fossi in te non ne sarei cosě sicuro: prova con "allergia"
Spiegamela per favore...
Tommy

Spiegamela per favore...
effettivamente mi sono sbagliato poichč mi sembrava che
non si potessero invertire con gli xor due numeri uguali
(per esempio ascii 'a'==97 con ascii 'a'==97)
 ma se a1=97, a2=97
 a1=a1^a2=97^97=0  => a1=0
 a2=a2^a1=97^ 0=97 => a2=97
 a1=a1^a2=0 ^97=97 => a1=97
=> a1=a2=97
da che dovrebbe funzionare anche questa:
char*  reverse1(char* a, size_t s1, size_t s2)
{if(s1>=s2)
       return a;
 a[s1]^=a[s2]; a[s2]^=a[s1]; a[s1]^=a[s2];
 return reverse(a, ++s1, --s2);
}
(ma ho il sospetto che non funziona per 'size_t' (lo xor non sembra
essere il colpevole)
____________________
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
char*  reverse(char* a, long s1, long s2)
{char tmp;
 if(s1>=s2)
       return a;
 tmp=a[s1]; a[s1]=a[s2]; a[s2]=tmp;
 return reverse(a, ++s1, --s2);
}
char*  reverse1(char* a, long s1, long s2)
{if(s1>=s2)
       return a;
 a[s1]^=a[s2]; a[s2]^=a[s1]; a[s1]^=a[s2];
 return reverse(a, ++s1, --s2);
}
int main()
{unsigned char  s[]= "allergia", m[9];
 unsigned        u, h, j=0;
 srand((unsigned)time(NULL));
 for(u=0;u<800;++u)
  {for(h=0;h<7;++h)
       s[h]=rand();
   strcpy(m,s);
   reverse( s, 0, strlen(s)-1);
   reverse1(m, 0, strlen(m)-1);
   printf("1+");
   if(strcmp(s,m)!=0) 
    {printf("problemi con le stringhe \'%s\' \'%s\'\n", s, m); j=1;}
  }
 if(j==0)
    printf("ok %s\n", s);
 return 0;
}

 Va bene per il C, in generale, a prescindere dall'ultimo standard.
sul precedente, non avevo dubbi. era sull'ultimo che ne avevo, grazie


La leggibilità in questi casi non serve a nulla,
meglio puntare sull'efficienza.
Ciao.


l'uso del' or-esclusivo č piů efficiente.
dato che si tratta di un algoritmo ricorsivo e la funzione č molto corta,
č meglio puntare sull'efficienza.
Ciao.

 le FAQ di comp.lang.c non sono affidabili.
Potresti anche dirci in quali punti di quelle FAQ vengono dette cazzate?
C:\>iao Angelo
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 č meglio puntare sull'efficienza.
Ma prima di parlare (a sproposito) di efficienza, non e' meglio fare
qualche prova?
C:\>iao Angelo
[1] Per carita' cristiana, evito di postare il codice assembler che si
    ottiene in debug.


 è meglio puntare sull'efficienza.
Non lo credo.
Tommy


scherzavo,
comunque adesso ci vado a guardare e se trovo delle cazzate ti faccio
sapere.. ;)
ciao. :)

 ha scritto nel messaggio
news:avkdnv$8c4$1...@venus.btinternet.com...

in assembly è sicuramente più efficiente,
probabilmente in C dipende dall'ottimizzazione che fa il compilatore.
altrimenti non si spiega perchè ad esempio, molti algoritmi in C
usano l'or-esclusivo in modo massiccio.
mah...
ciao.

 qualche prova?
hai ragione, ma aspetta un attimo, è il compilatore che scazza..
(permettetemi questo termine)
non pensavo che il compilatore fosse cosi inefficiente...
e non avrei mai pensato in una cosa cosi orrenda.
voglio controllare se anche LCC fa la stessa cosa.
ciao.
newbie

 usano l'or-esclusivo in modo massiccio.
si, dovresti embeddare il codice assembler all'interno del codice C
altrimenti oltre agli assegnamenti (che gia' hai nel metodo con tmp) ti
trovi anche gli xor (poi il VC++ fa peggio e mette, come abbiamo visto,
"assegnamenti" aggiuntivi). Embeddando codice assemby pui provare di usare i
registri).
Il fatto e' che ad ogni modo non so di quanto sia piu' veloce lo xor (di un
pochino anche lo sara' ma.... tangibile?!?)
Ricordati comunque che quando abbiamo una funzione ricorsiva come questa
(che e' facilemente trasformabile in iterativa) l'incremento prestazionale
lo ottieni trasformandola in iterativa, non migliorando lo swap! La
rircorsione in generale e' lenta!
Ah, sull'assembly spero di non aver detto troppe cavolate visto che sono
anni che non lo uso.... e se le ho dette , scusate, vi do ragione, prima
ancora di iniziare una polemica. (non mi riferisco a te newbie che sei stato
gentile a chiedermi scusa, apprezzo).
Tommy

 voglio controllare se anche LCC fa la stessa cosa.
Ho controllato anche con MingW. Le cose non sono tanto diverse, ma
il codice generato non e' comprensibile come quello generato da VC++.
Sei vuoi, lo posto.
C:\>iao Angelo



grazie,
ma forse è inutile scervellarsi su queste cose.. ;)
per dovere di cronaca riporto il codice asm di lccwin32.
LCCWIN32
 .line 131 ---->  tmp=a[s1]; a[s1]=a[s2]; a[s2]=tmp;
 movb (%edi,%ebx),%al
 movb %al,-1(%ebp)
 movb (%edi,%esi),%al
 movb %al,(%edi,%ebx)
 movb -1(%ebp),%al
 movb %al,(%edi,%esi)
 .line 123 ----> a[s1]^=a[s2]; a[s2]^=a[s1]; a[s1]^=a[s2];
 movsbl (%edi,%ebx),%eax
 movsbl (%edi,%esi),%edx
 xorl %edx,%eax
 movb %al,(%edi,%ebx)
 movsbl (%edi,%esi),%eax
 movsbl (%edi,%ebx),%edx
 xorl %edx,%eax
 movb %al,(%edi,%esi)
 movsbl (%edi,%ebx),%eax
 movsbl (%edi,%esi),%edx
 xorl %edx,%eax
 movb %al,(%edi,%ebx)
il codice asm generato da lccwin32 è ottimizzato con l'opzione (-o).
la notazione ASM di lccwin32 è quella inversa di AT&T.
riporto il tuo codice di VC++ per il confronto.
VC++ 5.0 (maximize speed [1]) produce il seguente codice assembler
; 17   :  a[s1]^=a[s2]; a[s2]^=a[s1]; a[s1]^=a[s2];
mov eax, DWORD PTR _a$[esp]
push ebx
mov dl, BYTE PTR [esi+eax]
mov bl, BYTE PTR [ecx+eax]
xor bl, dl
mov BYTE PTR [ecx+eax], bl
mov dl, bl
mov bl, BYTE PTR [esi+eax]
xor bl, dl
mov BYTE PTR [esi+eax], bl
mov dl, bl
mov bl, BYTE PTR [ecx+eax]
xor bl, dl
mi sembra che il codice prodotto dai due compilatori sia abbastanza simile,
ovvio... ;)
ciao
newbie

 registri).
Ammetto di essere una schiappa in assembly, ma guarda questa prova:
<CODE>
#include <stdio.h>
#include <windows.h>
#include <limits.h>
int main()
{
    unsigned a=5,b=7,i=0;
    DWORD start_time;
    DWORD end_time;
    start_time=GetTickCount();
    for(i=0;i<(INT_MAX/2);++i){
        __asm{
            mov eax,a
            mov ecx,eax
            mov eax,b
            mov b,ecx
            mov a,eax
        }
    }
    end_time=GetTickCount();
    printf("Normal Swap: %d\n",(end_time-start_time));
    start_time=GetTickCount();
    for(i=0;i<(INT_MAX/2);++i){
        __asm{
            mov eax, a
            mov ebx, b
            xor eax,ebx
            xor ebx,eax
            xor eax,ebx
            mov a, eax
            mov b, ebx
        }
    }
    end_time=GetTickCount();
    printf("XOR Swap: %d\n",(end_time-start_time));
    return 0;
}
</CODE>
Funzia sotto PC compatibili e windows, insomma non il massimo della
portabilita', ma....
Uso __asm per lo swap con una var temporanea (registro in questo caso), e
__asm anche per lo swap con lo xor.
Se uso per uno dei due codice C va moooolto piu' veloce visto che
l'optimiser si accorge che il codice non viene usato (o chissa cosa) e ci
mette pressoche' tempo 0 !!!!
In questo modo ecco l'output:
<OUTPUT>
Normal Swap: 3234
XOR Swap: 4953
Press any key to continue
</OUTPUT>
Come vedi lo swap XOR ci mette piu' tempo.
Forse e' colpa della mia implementazione in assembly, ma ad ogni modo se
anche si  riuscisse a fare un pochino piu' veloce non sembra che possa
riuscire a battere la versione Normal.
Pare che lo XOR sia piu' lento anche a livello assembly, e non solo quando
prodotto da un compilatore. (ok, che quello che produco io e' sicuramente
peggio, ma se hai qualche idea....).
Tommy

è meglio puntare sull'efficienza.
No. Prima di preoccuparsi di ottimizzare basandosi su
un preconcetto le cose andrebbero misurate sotto due
aspetti: 1) e' importante velocizzare quello scambio ?
2) e' vero che con XOR ci si mette meno ?
Lo scambio basato su XOR e' buono solo come giochino
di logica, ma non ha nessuna utilita' pratica.
Questo, purtroppo, non e' quello che viene insegnato.
Addirittura a volte viene insegnato
    x^=y^=x^=y;
che non e' nemmeno una espressione valida in C (perche'
il valore di x viene modificato 2 volte nella stessa
espressione, cosa vietata).
HTH
Andrea

meglio puntare sull'efficienza.
La leggibilita` serve *SEMPRE*.
Le ottimizzazioni preventive, specie in casi come questi, sono sempre
dannose (Knuth docet).  L'uso di una variabile temporanea non fa
perdere nulla, tra l'altro, in termini di prestazioni.  

 (cosa non molto logica, a mio parere).
?
Watcom usa proprio l' xor per azzerare un registro.
Ciao,
Drago.


potresti motivare questa affermazione?
-- 
Ciao, Giuseppe
Windows NT: designed for the Internet.
The Internet: designed for Unix.

Watcom usa proprio l' xor per azzerare un registro.
Cosa centra ? Io non mi aspetto che se chiamo swap(&i,&i)
la variabile i venga azzerata.
Personalmente la trovo un'idiozia.
Diverso il discorso che per azzerare un registro in asm
convenga fare "xor eax,eax" visto che il tempo di
esecuzione e' lo stesso, ma il codice e' piu' corto.
Anche in questo caso pero' io troverei assurdo se uno
scrivesse nel suo programma C
    i ^= i;
perche' conta sul fatto che quella variabile sia
allocata in un registro. Queste sono banalita' che
i compilatori seri sanno gestire bene.
Andrea

 E allora se ne parli in un NG dedicato all'assembler.
Bhe non e' un thread che e' partito parlando di assembler,
se l'argomento capita pero' non mi sembra un delitto.
Comunque accetto il tuo invito a non parlarne.
Vorrà dire che andro' a it.comp.lang.assembler(che se non erro non esiste) e
posterò un nuovo thread intitolato
"risposta al post di Andrea Griffini fatto in it.comp.lang.c" :)
Ciao,
Drago.

"risposta al post di Andrea Griffini fatto in it.comp.lang.c" :)
Non capisco il tuo sarcasmo.
Fare lo scambio in C usando l'or esclusivo e' una
cretinata per diversi motivi; non ultimo quello
che e' tutto da dimostrare che la ragione prima che
viene addotta e' che sia piu' efficiente quando questo
e' invece *falso* nella grandissima maggioranza dei casi.
Ci sono *alcuni* casi in cui in assembler puo' aver
senso su *alcuni processori* fare lo scambio con xor,
ma certo *non* sono gli esempi che hai fatto tu e
sicuramente la cosa non centra nulla con il linguaggio C.
Fare lo scambio di interi in C usando lo xor e'
una stupidata su tutta la linea. Punto.
Andrea

 Dato x assodato che usare l'xor in C x eseguire una swap sia un'
assurdita',
A questo punto ti saluto, ti auguro una buona settimana e ti comunico che
non ho alcuna voglia di continuare su questi toni.
Ciao,
Drago.

 Andrea
N.B.
se hai intenzione di rispondermi ti prego di stare molto attento a non
offendere
perché saprò come rispondere... quindi cerchiamo di evitare parole INUTILI.
io ho espresso solo la mia opinione e se gli altri daranno ragione a te, io
non mi farò dei problemi.
se sono convinto di quello dico è SOLO perchè la mia esperienza PRATICA mi
dice cosi.
ciao
newbie

 Tommy
ciao Tommy, che piacere risentirti. :)
sei veramente convinto che gli esempi in assembly che hai fatto siano
sufficienti per dimostrare
che la XOR sia piu' lenta ???
si? allora č inutile che ti risponda.. ;)
ciao
newbie

 si? allora č inutile che ti risponda.. ;)
No, non ne sono convinto ed e' per questo che ho scritto:
"Ammetto di essere una schiappa in assembly, ma guarda questa prova:"
"Forse e' colpa della mia implementazione in assembly"
In pratica non ne sono convinto. Quegli esempi sono cio' che sono riuscito a
produrre. Tu cosa sei riuscito a produrre che dimostri il contrario?!?
Se hai delle argomentazioni rispondi pure. Non sono mai cosi' testardo e
presuntuoso da essere totalmente convinto delle mie cose e non ascoltare gli
altri....
A presto,
Tommy

             mov a,eax
Questo codice del SWAP normale e' fatto male: basta fare:
__asm{
     mov eax,a
     mov ebx,b
     mov b,eax
     mov a,ebx
}
e di conseguenza il tempo 3234 diventa 3000 aumentando ancora il vantaggio
sullo SWAP XOR!
Tommy

esperienza PRATICA mi dice cosi.
Io ad esempio compilando uno scambio classico di
due variabili { int t=x; x=y; y=t; } ottengo con
gcc questo codice:
    movl    _x, %ecx
    movl    _y, %eax
    movl    %ecx, _y
    movl    %eax, _x
mentre con lo scambio XOR { x^=y; y^=x; x^=y; }
che tu dici essere piu' efficiente ottengo:
    movl    _y, %eax
    movl    _x, %ecx
    xorl    %eax, %ecx
    xorl    %ecx, %eax
    xorl    %eax, %ecx
    movl    %eax, _y
    movl    %ecx, _x
Ti spiacerebbe mostrare un frammento di codice C,
citando quale hardware e quale compilatore hai
usato e quali sono i risultati che hai ottenuto ?
Andrea

ma in assembly (e non in assembler...) si puo' fare.
Come? Mostrami un codice assembly piu' veloce con lo xor rispetto ad un
assegnamento normale!
A presto,
Tommy

 mov var1, registro2
Ci tengo a precisare che questo e' codice ottimizzato.
tmp=a;
a=b;
b=tmp;
non sempre produce codice cosi' buono, spesso proprio l'uso della var tmp si
riflette sul codice assembly gonfiandolo parecchio.
Ad esempio il VC++ 6 senza optimiser:
mov   ecx, a
mov   tmp, ecx
mov   edx, b
mov   a, edx
mov   eax, tmp
mov   b, eax
in questo caso dando per buono il tuo 4 cicli di clock per MOV, otteniamo:
6*4=24.
Sempre il VC++ 6 con:
a^=b;
b^=a;
a^=b;
produce:
mov   eax, a
xor     eax, b
mov   a ,eax
mov   ecx, b
xor    ecx, a
mov   b ,ecx
mov   edx, a
xor    edx, b
mov   a,edx
6*4 + 3*2 = 30!
Anche il Vc++, nonostante gonfi la prima produce codice piu' veloce per
versione normale!
Tommy

 usato e quali sono i risultati che hai ottenuto ?
mi hai dato del cretino e dell'imbecille e vuoi pure che ti risponda??
non meriti nemmeno uno SCHIFO di risposta.

 altri....
beato tè che hai tutta sta pazienza. :)
ciao
newbie

 xor   var2, registro1
questo codice si avvicina molto come velocità a quello "NORMALE"
e si puo' ancora ottimizzare,
ti prego di aspettare ancora qualche giorno per avere una mia risposta
definitiva.
ciao
newbie

 definitiva.
Ok, no problem.
Ricordati pero' che xor registro registro ci siamo messi d'accordo che ci
metta 2 cicli. E ci siamo messi d'accordo che mov memoria, registro ce ne
metta 4.
Qui tuttavia stai facendo xor rmemoria, registro e quindi per stare alla
nostra regola dovrebbero essere piu' o meno 4 cicli.
Inoltre col lo xor non e' possibile il parallelismo, quindi qua sono 4*4=16.
mentre con 4 mov e' 4*4=16, ma in realta' le prime due e le ultime due
possono avvenire contemporaneamente, dando: 4*2=8.
La cosa strana e' che con questo tuo nuovo metodo ci mette 6110, mentre
viene 4953 con il mio metodo piu' lungo:
            mov eax, a
            mov ebx, b
            xor eax,ebx
            xor ebx,eax
            xor eax,ebx
            mov a, eax
            mov b, ebx
In altre parole lo xor registro memoria pare essere mooolto piu' lento di
quello registro-registro.
Aspetto il aggiornamento, anche se siamo entrambi un pochino OT.
Tommy

>>mov var1, registro2
1+1+1+1= 4 cicli di clock! Meno della meta'! (non 16 come con i tuoi dati)
Inoltre ti ricordo che queste MOV possono avere parallelismo due a due, le
tue XOR no.
E' un tantino diverso lavorare ora che mov=1 cilco e non come dicevi tu 4 !
eh?
Prima entrambe ci mettevano 16 cicli di clock, ora una 9 e l'altra solo 4 !!
In tutta franchezza non penso sia possibile generare con lo xor codice piu'
veloce rispetto a quello con mov.
Se riesci posta pure, anche per email, altrimenti, chiudiamo questo thread
che e' oramai TROPPO OT!
Tommy

 1+2+3+3= 9 cicli di clock! (non 16 come con i tui dati)
vedi sopra.
comunque non c'era un secondo fine,
mi hai veramente deluso Tommy...
ciao ciao

>siano sbagliati, solo un tantino presi male....
Scusa per averti deluso... I tuoi dati non erano falsi, erano solo il
migliore per lo XOR ed il peggiore per il MOV.
Mi fido che non ci fosse un secondo fine pero'!
Chiedo scusa se hai preso male il mio messaggio e ti sei offeso (e mi
dispiace averti deluso). (non e' il fine che volevo ottenere).
Tommy

Io non ho risposto a Lorenzo solo perche' non ho capito cosa voglia....
una funzione che la stampi invertita o che inverta una stringa.[...]
.. , esatto , chiedevo una funzione ricorsiva
che stampasse una stringa al contrario, richiamando se stessa
fino alla fine della stampa.Se non sbaglio sul K&R c'è
un esercizio di questo tipo, se trovo la pagina ...
Ciao

[cut cut]
.. hey , ma che 3ed ho scatenato!
azza! in ogni modo thanks at all!
Ciao