Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
strlen( ), strcpy( ), strctnp( ). rilerilset( ), rnemcpy( 1 e<br />
rnemcinp( ). Per usarle occorre includere il file "strings.liV<br />
che provvede a ridefinire tali nomi anteponendo loro la<br />
stringa "-builtin-". Il vantaggio risulta anche notevole<br />
sotto il profilo della velocità.<br />
Esiste anche un'altra funzione analoga: si tratta di printf( ):<br />
se si include il file "stcIio.hn e si usa printf( 1 con una semplice<br />
stringa, il compilatore genererà una cliiaiiiata a -write( ),<br />
invece che alla funzione di libreria linked printf( 1; se si<br />
usano invece solo le opzioni di formattazione %S. %d, %p il<br />
compilatore userà una forma ridotta di printf( 1 chiainata<br />
tinyprintf( ), che non include la gestione dei floating point.<br />
I'roviaino allora ad usarla con il nostro sorgente ed ecco il<br />
risultato: 4796 byte invece dei 6060 precedenti, una<br />
riduzione superiore ai 1000 hyte (questa dirninuzioile .non<br />
è comunque proporzionale al numero di volte che printf( )<br />
viene chiainata nel codice). Ovviamente risultati analoghi<br />
possono essere ottenuti usando direttamente delle<br />
combinazioni adeguate di puts( ) o di altre analoghe<br />
funzioni di I/O, ma l'uso di printfc 1 risulta più elegante e piì~<br />
immediato.<br />
Altre riduzioni della lungl-iezza del codice si possono<br />
ottenere facendo attenzione acl alcune piccole cose: per<br />
esempio, le operazioni con i nu~neri interi possono<br />
generare delle chiamate di funzioni piuttosto lunghe. Se si<br />
sta attenti ad evitare inoltiplicazioni o divisioni inutili o<br />
sostituibili con shift od operazioni logiche. si ottiene<br />
sempre una certa riduzione negli ingombri (e un aumento<br />
velocità): per esempio, le divisioni per 2 o multipli di 2<br />
possono essere sostituite con estrema facilità da shift a<br />
destra, che si traducono a livello di eseguibile in una sola<br />
istruzione assembly e lo stesso può dirsi per le<br />
moltiplicazioni.<br />
Un altro elemento, fra i tanti, da considerare è la<br />
dichiarazione degli interi: se sono usati come unsigned,<br />
dichiarateli come tali, perché la gestione degli unsigned è,<br />
in generale, più semplice per il compilatore e si traduce in<br />
risparmio di codice.<br />
Un altro fattore che può incidere negativamente sulla<br />
lunghezza del codice è l'uso di variabili long come indici per<br />
gli array: è preferibile l'uso di unsigned short, quando è<br />
possibile.<br />
Ma ci fermiamo qui, proseguendo per questa strada si arriva<br />
nel dominio delle ottimizzazioni, che è sicuramente un<br />
territorio più ampio e complesso di quello da noi trattato e<br />
risulta strettamente connesso alla attività di<br />
programmazione e alle scelte degli algoritmi da utilizzare.<br />
Ricordo per finire che il programma Go della SAS e<br />
l'opzione -ms consentono di ottenere delle ottirnizzazioni<br />
automatiche che incidono sempre sulla lungliezza del<br />
codice.<br />
Se vogliamo però giungere a ridurre in maniera cospicua il<br />
programrila, dobbiamo operare delle scelte radicali e<br />
rinunciare, come dicevamo all'inizio. ai vantaggi offerti<br />
dall'ambiente standard del C.<br />
Le funzioni di I/O<br />
E' qui che potreri-io ottenere i vantaggi più cospicui: le<br />
f~inzioni di I/O di alto livello del C sono inolto comode, ma<br />
anche molto ingombranti. L'uso di printf( ) nella foriiia -tiny<br />
opera già una certa riduzione, ma parziale. Se vogliamo<br />
diminuire drasticamente il codice, dobbiaino rinunciare a<br />
queste funzioni. Ci6 non vuol dire rinunciare alla funzione<br />
printf( ), ma significa usare la funzione printf( ) contenuta<br />
nella libreria amiga.li11 invece di quella contenuta in Ic.lib.<br />
La fiinzione di ainiga.lil-> è infatti bre~lissiina, in quanto usa<br />
delle funzioni di forinattazione contenute nella libreria<br />
sharecl Exec. La printf( ) di ainiga.lih ha lo stesso formato di<br />
una printf( ) standard e usa il solito carattere ?h co111e codice<br />
di escape per indicare la presenza di un parametro sullo<br />
stack. Da questo punto di vista non cambia nulla rispetto a<br />
quello in lc.lil->, se non il fatto che i parametri sullo stack<br />
sono di default considerati degli sliort e per forzare il<br />
forniato long occorre usare il carattere opzionale "1":<br />
"ad" è un lntero a 16 bit<br />
"ild" è un ~ ntero a 32 bit<br />
e lo stesso vale per gli altri forinati di conversione consentiti<br />
(%C %d %x %s, quindi non sono permessi i numeri in virgola<br />
inabile). Un altro inconveniente di questa funzione è la<br />
lentezza, dovuta al modo particolare con cui è<br />
iinpleinentato 1'11'0 (la stringa viene stampata carattere per<br />
carattere, senza alcun buffer), ma se si tratta di stampare dei<br />
semplici messaggi di errore o dei testi l~revi, la sua velocità<br />
risulta accettal~ile e ripagata ainpiamente dalla riduzione di<br />
codice.<br />
Un ultimo limite sta nella lunghezza delle stringhe. la quale<br />
non deve essere superiore ai 110-130 byte circa (il valore<br />
esatto non lo conosco, immagino che sia di 128 byte - coine<br />
un signed char -, ma so che oltre una certa lunghezza si va<br />
direttamente in guru). Infine, ricordo che il controllo del<br />
break utente (CTRL-C) avviene durante l'uso delle fiinzioni<br />
di I/O standard del C, se si usano quelle di amiga.lib, tale<br />
controllo non verrà niai effettuato. Per poter usare tali<br />
funzioni occorre creare e inizializzai-e la variabile esterna<br />
BPTR (long) "stdout" chiariiando la funzione Output (del<br />
110s):<br />
longstdout; /*variab1leesternak/<br />
dopodiché si potrà usare liberamente la printf( ) (e le altre<br />
funzioni di output verso la console) contenuta in arniga.lib.<br />
Per indicare al linker di usare la funzione contenuta in