Come scrivere programmi incomprensibili |
Home Page | Commenti | Articoli | Faq | Documenti | Ricerca | Archivio | Storie dalla Sala Macchine | Contribuire | Imposta lingua:en it | Login/Register
Capita spesso di dover mettere le mani nel codice scritto da altri e di domandarsi "ma l'ha fatto apposta ???" perche' lo stesso e' ASSOLUTAMENTE INCOMPRENSIBILE. Questo documento non e' fatto per insegnarvi come scrivere del codice, semmai come NON scriverlo. Mi e' venuta voglia di scriverlo tanto tempo fa'... quando mi capitava in mano il codice scritto da qualcun altro che sembrava essere fatto per vincere un campionato di "obfuscated code", poi non ci ho piu' pensato per un po'. Mi e' ritornata la voglia qualche giorno fa' quando ho ricevuto uno spezzone di codice da controllare e mi sono ritrovato a dover riscrivere e verificare ogni riga per cercare di capire che accidente fa' sta' cosa... Ecco quindi il mio contributo all'argomento. Per cortesia, non seguite i miei consigli... se non altro non dite che ve li ho dati io. Per raggirare un programmatore che deve mantenere o modificare il vostro codice, dovete sapere come pensa. Ok, lui ha il vostro gigantesco programma, non ha il tempo per leggerlo completamente, figuriamoci per capirlo. Quello che vuole, e' trovare rapidamente il punto dove fare i suoi cambiamenti, farli alla svelta, andarsene a casa e non avere nessun effetto collaterale per questo. Lui vede il vostro codice come attraverso un tubo, puo' vedere solo una piccola parte del codice, quello di cui volete essere sicuri e' che non arrivi MAI a capire il disegno generale, e che sia il piu' difficile possibile per lui trovare il punto in cui apportare i suoi cambiamenti. Ma ancora piu' importante e' che sia incredibilmente difficile per lui modificare qualsiasi cosa senza avere disastrosi effetti su tutto il resto del codice. Per fare cio' dovete rendervi conto che ogni particolare aspetto di un linguaggio (se inpropriamente utilizzato) rende il codice incomprensibile. La parte migliore nello scrivere codice assolutamente incomprensibile e' data dalla capacita' (quasi un'arte) di trovare nomi assurdi per variabili, funzioni e metodi. Questi nomi non significano nulla per il computer, questo vi da' l'opportunita di usare tutte le tecniche possibili per instupidire il programmatore. 1. Nuovi usi per il "libro dei nomi" (ISBN: 0-380-78047-X) Comperatevene subito una copia e non vi troverete mai in difficolta' nell'inventare il nome di una variabile. "Gino" e' un ottimo nome, e' breve, si scrive alla svelta ed ha una marea di altre possibilita' (Lino, Pino, Dino...) tutte molto simili e facilmente confondibili tra di loro. Se state cercando per dei nomi "facili" provate "adsf" o "aeou" 2. Errori grammaticali Se dovete necessariamente utilizzare dei nomi descrittivi per le vostre variabili e funzioni, e' il momento di scordarvi della grammatica e di come si scrivono le parole. 3. Siate astratti Utilizzate pesantemente l'astrazione "come", "quello", "data", "gestione", "varie", "fai" e le cifre, Es. Gestione325, FaiQualcheCosa, Data234... 4. A.C.R.O.N.I.M.I. Usate gli acronimi per rendere il codice piu' "pulito", E ricordate che I "veri" uomini non spiegano *mai* gli acronimi: li capiscono per via genetica... 5. Sinonimi e contrari Per evitare la monotonia utilizzate un bel vocabolario dei sinonimi e dei contrari. Soprattutto se avete una serie di funzioni/variabili il cui significato e' praticamente lo stesso, utilizzando dei sinonimi "sottintenderete" delle differenze nell'utilizzo. Tuttavia, se avete diverse funzioni che differiscono in particolari cruciali, curatevi di usare sempre lo stesso nome o quasi. Es. "print" per stampare sulla stampante, scrivere su un file o visualizzare a video... Non soccombete MAI alla richiesta di documentare il vostro codice e di scrivere un glossario. 6. Usate lingue straniere Uno script che tiene traccia dei vari "statil" ritornati dai "vaxen"... Esperanto, Klingon, Hobbitese sono linguaggi qualificati per questi scopi. 7. maIusColE Se usate le lettere maiuscole per identificare le singole parole in una parola lunga, fatelo casualmente, questo e' molto piu' efficace se usate un mix di parole inglesi ed italiane. 8. Riciclate i nomi Assicuratevi di usare la stessa variabile per almeno 3 cose diverse nello stesso pezzo di codice, se lavorate in C/C++/Java potete creare dei "blocchi" usando { }, all'interno definite altre variabili locali con lo stesso nome di altre variaibli globali. Lo scopo e' che la ricerca di una variabile porti il maggior numero possibile di risultati nello stesso blocco di codice, in modo che il VERO scopo della variabile (se c'e') non sia affatto chiaro senza una attenta analisi del codice. 9. Lettere accentate Usate gli accenti per i nomi delle variabili, per esempio: typedef struct { int i; } ìnt;Se non ve ne siete accorti, la 'i' dell'ultimo 'int' e' una lettera accentata, questa pero' passa facilmente inosservata, cosi' vi ritrovate una cosa che sembra una variabile mentre e' una struttura.
10. Usate a vostro vantaggio la massima lunghezza delle variabili
Se il vostro compilatore supporta ad esempio solo 8 caratteri, usate categoricamente nomi piu' lunghi, cambiando solamente la fine. Per esempio var_unit_dimension e var_unit_expression, queste due sembrano diverse, ma per il compilatore sono una sola... devo dire altro ? 11. Sottolineato, un'amico. Usate _ e __ come identificatori 12. Mescolanza di lingue Mescolate liberamente le lingue estere note (ed ignote) nel vostro codice, chi legge non puo' dire che non avete commentato il codice, potra' chiedersi perche' parte dei commenti sono in Tedesco o in Thailandese.... 13. Il codice ASCII e' composto da 255 caratteri E sono quasi tutti validi per le variabili, compresi §, ¿ e cose di questo genere. 14. Usare nomi comuni per le variabili Cercate di scegliere dei nomi "comuni" per le variabili, ma che abbiano significati completamente diversi da quello per cui le variabili sono pensate, per esempio: marypoppins = (julieAndrews + starship) / mailbox; Questo confonde il lettore che ha difficolta' a dissociare la parola dal suo contesto "solito". 15. Variabili tipiche Mai usare 'i' per un ciclo come al solito, usate qualsiasi altra variabile ma non 'i'. 16. Ignorare le convenzioni implicite Se il vostro linguaggio (tipo Java) ha delle convenzioni implicite per i nomi (tipo le classi iniziano con la maiuscola, le variabili no...) IGNORATELE! In alternativa fatevi la VOSTRA serie di convenzioni assolutamente bizzarre e lamentatevi del fatto che nessuno le usa. 17. La 'l' (elle) somiglia molto ad '1' (uno) Due nomi come def1ab e deflab sono molto simili ma sono diversi. 18. Essere creativi con i parametri delle funzioni Se avete una funzione F che richiama G passandogli un parametro che in F e' chiamato A, in G usate come identificativo un altro nome che e' presente in F ma non in G. Questo rendera' molto piu' complesso il capire cosa fa' esattamente la funzione 'G' e come viene usato il suo valore di ritorno. Altro esempio: se avete una funzione CalcWidth( height, size ), usate "height" per contenere il valore che verra' usato come "size" nel calcolo e viceversa... 19. Utlzo dle abbrvzni (utilizzo delle abbreviazioni) Non c'e' un solo modo di abbreviare una parola... siate creativi. 20. Sottostimare le funzioni Utilizzate per le funzioni dei nomi che non diano l'idea (o non precisamente) di cosa effettivamente fa' la funzione. Se qualcuno domanda spiegate che la funzione e' stata migliorata e le nuove funzionalita' aggiunte in un secondo tempo, questo spiega il nome. Per esempio una funzione come isValid( x ) Dovrebbe verificare la validita' del suo parametro, ma se contemporaneamente lo converte in binario e lo memorizza in un database... 21. Notazione ungherese La Notazione Ungherese e' una vera arma nucleare nelle mani di un sapiente "offuscatore". Non c'e' sforzo di comprensione del codice che non possa essere vanificato, ne' ingegniere, programmatore o tecnico di sorta che non possa essere indotto al suicidio con un buon attacco di Notazione Ungherese. Per chi non lo sapesse, la Notazione Ungherese e' la pratica di anteporre al "nome" vero della variabile un "prefisso" che identifica il tipo e lo scopo della variabile. Cosi' abbiamo per esempio intValore, strTesto, objOggetto e cosi' via. Il trucco sta' nell'utilizzare prefissi identici ma che abbiano diversi significati in vari punti del programma, cosi' abbiamo:
intXXX = Intervallo Non Trovato... e cosi' via. 22. Notazione Ungherese 2 Seguite l'esempio Microsoft: il tipo della variabile cambia ma il nome resta lo stesso. 22. Ridurre, riusare, riciclare Se avete definito una struttura per contenere i dati di un callbacks, definite la struttura in ogni modulo del programma e dategli sempre lo stesso nome. Questo mandera' in confusione il debugger (specialemte quello di VC++), cosi' quando verra' richiesto di mostrare il contenuto della struttura nella finestra di osservazione, il debugger non avra' la minima idea di QUALE struttura prendere e ne prendera' una a caso. 23. Usare nomi che somigliano molto ad istruzioni Nomi come Null, cOnst, For o simili. 24. Usare nomi che non c'entrano niente con quello che appare a video Chi ha detto che un campo a video "Nome" deve corrispondere ad una variabile "nome" ? Un'altra grande abilita' per scrivere codice incomprensibile e' l'arte del cammuffamento, ovvero nascondere certe cose e far si' che altre cose appaiano cio' che non sono. Molto di questo dipende dal tipo di linguaggi che state usando e dagli strumenti che il "manutentore" si trovera' in mano. 1. Mascheramento del codice come commento e vice versa Questo funziona con i linguaggi in cui esistono i commenti multilina, C/C++ e Java per citarne alcuni. Per esempio: for(j=0; j<array_len; j+ =8) { total += array[j+0 ]; total += array[j+1 ]; total += array[j+2 ]; /* Main body of total += array[j+3]; * loop is unrolled total += array[j+4]; * for greater speed. total += array[j+5]; */ total += array[j+6 ]; total += array[j+7 ]; } Senza la colorazione della sintassi avreste notato che tre linee di codice sono commentate ? 2. Spazi, indentazione e linee bianche Usate gli spazi l'indentazione e le linee bianche in modo casuale e non relativo al codice stesso: for(kappa=0;kappa<=_kappa;kappa++) { if(llama+kappa<0) bzap(); if(llama+kappa>3){effe+=-l +3; data(); } } 3. Istruzioni che proseguono nelle linee successive Anche questo dipende molto dal compilatore che state usando, con molti compilatori e' possibile interrompere una linea e proseguirla sulla linea successiva aggiungendo un "\" nel punto di interruzione. In questo modo e' possibile avere una cosa del tipo: int data\ base=0; Lo scopo e' rendere impossibile una ricerca rapida della variabile "database". 4. Nascondere definizioni e dichiarazioni in mezzo ai commenti Questo funziona particolarmente bene se avete dei commenti lunghissimi, noiosissimi e scritti in qualche lingua straniera di difficile comprensione (Tedesco, Olandese, Ungherese... ). 5. Nascondere variabili globali Dato che le variabili "globali" sono di solito assolutamente proibite, definite una struttura, ficcateci dentro tutto quello che volete e chiamatela con un nome che ricordi molto quello di una classe o di una funzione. Il programmatore passera' giorni cercando nel vostro codice una classe con quel nome... 6. Usate dei sinonimi Molti programmatori coscienziosi, per verificare se una modifica influisce su piu' parti del codice effettuano delle ricerche nel codice per vedere dove una funzione o variabile e' richiamata. Se usate piu' #define per assegnare diversi "sinonimi" alla stessa funzione/variabile, il programmatore ricevera' pochi riferimenti, quindi avra' molte piu' probabilita' di ritrovarsi con un disastro quando apportera' le sue modifiche. Questo e' particolarmente effettivo se unito alle (3) e (4). 7. Sovraccarico In C++ potete usare il "sovraccarico" per ridefinire funzioni ed operatori, questo puo' dare la falsa impressione che stiate usando una semplice funzione di libreria o una semplice operazione mentre state facendo tutt'altro. 8. Usare le funzionalita' del linguaggio Questa me la segnala Maurizio Lippa, se dovete fare una cosa semplice, tipo
if (a==b) { c='pippo'; else c='pluto'; }Usate le funzionalita' del linguaggio piu' complicato che esiste: c=select decode(sign(a-b),0,"pippo","pluto"); 9. "Piccoli" errori di digitazione... Questa perla me l'ha inviata Lorenzo Paulatto. Ammette che se l'editor e' abbastanza furbo ed effettua la colorazione della sintassi si fa' presto a scovare l'errore, ma se non lo fa'...
#define TRUE 1 /* ...some comment */*0 #define FALSE 0 /* ...some other comments */ Si vede l'errore? Dato che il computer ignora i commenti e la documentazione, potete mentire a vostro piacimento e fare tutto cio' che e' in vostro potere per ridurre alla disperazione il povero programmatore. 1. Mentire nei commenti. Non e' che dovete proprio *mentire*, e' sufficiente che vi "dimentichiate" qualche piccolo particolare nella documentazione del codice. 2. Documentare l'ovvio, ignorare lo strano Documentate sempre le parti di codice OVVIO e comprensibile, ignorate sistematicamente le parti di codice piu' anomalo o dove risiedono le vere "chicche". 3. Uso dei tools di documentazione Avete presente quei "tools" che automaticamente passano le vostre funzioni e costruiscono degli "header" che riportano i vari parametri ? Copiate diligentemente questi header da una funzione all'altra, ma non riempite mai le parti relative allo scopo dei vari parametri. Se vi e' richiesto esplicitamnte assicuratevi di avere sempre gli stessi nomi dei parametri ma scopi completamente diversi. 4. Uso della documentazione di progetto. Quando state implementando un algoritmo realmente complesso usate il classico principio di avere un solido progetto prima di scrivere una linea di codice. Scrivete pertanto un dettagliatissimo documento che spiega i piu' intricati dettagli dell'algoritmo, piu' e' dettagliato (quindi lungo e noioso) il documento piu' probabilita' avete che il programmatore si perda dopo la prima pagina. Per ogni "passo" dell'alogoritmo scrivete un paragrafo che ne spieghi tutti i dettagli, usate un formato di capitolo/paragrafo/sottoparagrafo/sotto-sottoparagrafo e cosi' via. Come minimo devono essere 5 livelli. In maniera tale che si abbia alla fine una cosa come 1.2.4.6.2.13 - Visualizza il risultato dell'attivita'.... Quando scrivete il codice effettivamente, usate delle funzioni di nome Act1_2_4_6_2_13() senza commentarle. Dopotutto e' per questo che e' stata scritta la documentazione no ? Dato che la documentazione e' auto-numerata, lunga e complessa, e' estremamente difficile mantenerla in sincronia con il codice vero. Ma questo non e' un problema vostro. In effetti voi non farete assolutamente niente per mantenere la documentazione aggiornata, anzi il contrario. 5. Unita' di misura. Mai documentare le unita' di misura delle variabili di input, output ed i vari parametri (e' per questo che si usa la Notazione Ungherese no ?). 6. Bugs Mai documentare sospetti bugs nel codice. 7. Commenti alla Monty Python Se avete una funzione chiamata makesnafucatedinsert(), il solo commento accettabile e' /* make snafucated */ Mai definire cosa cavolo fa' o cosa cavolo vuol dire. Se qualcuno domanda rispondete che "e' una cosa che ho aggiunto in seguito e volevo fare dei test...". (vedere la documentazione del Java AWT per migliori idee...) La chiave per scrivere un codice facilmente comprensibile e mantenibile e' quella di definire e specificare ogni cosa in un solo posto. Se cambiate idea o volte fare delle modifiche, dovete farlo in un solo posto. Pertanto, la chiave per scrivere codice ASSOLUTAMENTE INCOMPRENSIBILE e' quella di ripetere e sparpagliare le cose in una marea di posti diversi. Questo funziona particolarmente bene con certi linguaggi, meno con altri. Per esempio, in Java/C/C++. Per esempio e' praticamente impossibile cambiare il tipo di una variabile perche' i vari cast/controlli di tipo falliscono miseramente. Mai verificare il tipo/valore dei parametri di input. Questo dimostrera' assoluta fiducia nelle scelte/intelligenza dell'utente. E si trasformera' in un incubo per il povero programmatore che avendo cambiato un int in un long otterra' un GPF o un crash del sistema senza alcuna traccia di dove andare a guardare. Per la stessa ragione mai usare Assert(). Una o due Assert() messe bene possono trasformare una settimana di lento e penoso debug in una festa di 5 minuti. Usare allegramente il copia/incolla per riprodurre parti di codice ovunque sia necessario. Questo e' anche utile se il vostro lavoro e' misurato in linee di codice scritte... Usate variabili globali ed array statici per memorizzare informazioni per tutto il programma, in questo modo non si avra' mai una chiara comprensione di COSA contengono tali variabili. Disseminate il programma di funzioni inutili e mai richiamate. Ignorate categoricamente i valori di ritorno di altre funzioni. Se state usando un linguaggio OOP gettatevi a pesce nell'ereditarieta', definite una classe base e poi derivatela fino al 20o livello aggiungendo sempre cose assolutamente inutili e ridefinendo sempre le stesse funzioni. In questo modo non si sapra' mai se state richiamando un metodo nella classe madre o in quella attuale. Sempre se state usando un linguaggio OOP, mescolate sempre variabili pubbliche con metodi pubblici. Scrivete inutili funzioni-ponte e "wrapper" per richiamare codice non scritto da voi, ed anche scritto da voi. Assicuratevi di avere un quarto livello di redirezione: la funzione A() che chiama B() che chiama C() che chiama D() che fa' il lavoro. Moltiplicate le funzioni usate e non centralizzate, invece di scrivere una sola funzione setAlignment() che accetti un parametro per indicare l'allineamento, scrivete 4 funzioni diverse setLeft, setRight etc. Abbiate cura di copiare il codice base e la logica, questo per rendere piu' difficile il mantenerle in sincronia. In Java, ogni volta che un metodo riceve un oggetto come parametro (cioe' quasi sempre), quell'oggetto e' modificabile. Usare estensivamente questo effetto collaterale per modificare lo stato interno del parametro. Le Exceptions non servono. Il codice scritto bene non fallisce mai, quindi non perdete tempo a gestire Exceptions. Lasciare qualche bug nel vostro programma fornira' al manutentore che verra' dopo di voi qualche cosa di divertente da fare. Un bug piazzato bene lasciera' al programmatore l'eccitazione di scoprire DOVE e QUANDO e' stato introdotto. Il sistema piu' semplice per ottenre quest'effetto e' semplicemente di non testare mai il vostro codice. Un altro ottimo sistema e' lasciare del codice che viene eseguito solo in fase di debug (usando #ifdef), questo lasciera' al programmatore diversi problemi che appaiono quando il programma e' in fase di debug ma spariscono quando il programma e' in esecuzione normale. Mai ricompilare. Compilate il codice una volta per ottenere un eseguibile, se funziona fate alcune modifiche al codice e non ricompilatelo piu'. Fate continui miglioramenti al vostro codice (dopotutto lo fa' anche la Microsoft no ?). Includete nel vostro codice potentissime librerie aggiuntive e non usatele mai. Accertatevi di aver lasciato qualche Warning di compilazione nel vostro codice. Usate poi l'opportuno parametro del compilatore per sopprimerne la segnalazione. In questo modo il programmatore che tentera' di ricompilare il codice si trovera' con una serie di segnalazioni anomale e perdera' giorni nel tentativo di capire cosa e' successo. Se scoprite un bug nel vostro compilatore/interprete, accertatevi di sfruttarlo al massimo, anzi, fate in modo che tale bug divenga essenziale per il vostro codice per poter funzionare correttamente. Se il vostro compilatore si lamenta di "variabili inutilizzate", non eliminatele, trovate un modo furbo di usarle, per esempio i=i; Usate array multidimensionali. E tanti. Usate particolari posizioni all'interno di lunghi array come flag. Non documentate mai ovviamente l'utilizzo. Mai usare costanti "normali", se vi serve una costante che vale 'A', usate 65 o 0x41 o 0101 per indicarla. Usare l'esadecimale o l'ottale ogni volta che e' possibile. Fate libero uso del fatto che 0x10, 010 e 10 non sono la stessa cosa... Passate tutti i dati come void* e poi effettuate un cast per ottenere il giusto tipo, anche usare il byte offset invece che un cast esplicito e' utile. Usate estensivamente switch innestati. E' il sistema piu' complicato da identificare. Mai usare costanti mnemoniche, usate sempre il valore numerico puro. Cercate di "impacchettare" il maggior numero di istruzioni su una singola linea (chi si ricorda lo "spaghetti code" ?) Mantenete tutto il codice inutile nel vostro programma, anche se non viene mai richiamato. Se necessario aggiungete funzioni inutili prendendole da altri programmi, anche se non c'entrano niente con il programma attuale. Fate le vostre funzioni le piu' grosse possibili, 1000 o piu' linee di codice non sono poche. Lasciate almeno un paio di file che non si trovano durante la compilazione. Il sistema piu' semplice e' usare dei riferimenti assoluti al vostro disco locale. Per esempio #include "D:\\myfile.h" Almeno una variabile dovrebbe essere scritta dappertutto, ma mai letta (e quindi usata). Una particolare feature del C e quindi del C++ (e anche del C# non gestito, se non ricordo male) e' quella dell'aritmetica dei puntatori. Sicuramente non c'e' bisogno che vada avanti nella spiegazione, per cui passo direttamente agli esempi: int main() { int vettore[100]; void * puntatore = vettore; // Questo lo metto qui..... vettore[20] = 50; // inizializzazione vettore[5] = 10; int elemento = vettore[5]; int elemento2 = (int)((char*)(puntatore))[5 * sizeof(int)]; // e se 5 e' cablato..... int elemento3 = (int)((char*)(puntatore))[20]; // ovviamente ti sarai anche accorto che qui sopra c'e' anche un altro // effetto malefico e' cioe' che prendendo un singolo elemento quando il // vettore e' un char * funziona solo con valori minori di 256, per cui: vettore[5] = 266; elemento = vettore[5]; elemento2 = (int)((char*)(puntatore))[5 * sizeof(int)]; elemento3 = (int)((char*)(puntatore))[20]; // A questo punto solo in elemento c'e' 266, mentre in elemento2 e elemento3 // c'e' ancora 10...bello no? // mentre che ne pensi dell'istruzione seguente? potrebbe sembrare un // bug, ma forse e' stato sbagliato giusto?!?!?! int elemento4 = vettore[5 * sizeof(int)]; return 0; // ah! dimenticavo, ovviamente va bene solo su compilatore per // cui sizeof(int) e' 4 byte: "colpa del compilatore, il codice // quando l'ho fatto era giusto" } Spero che ti piaccia, soprattutto l'ultima (elemento4) e' esagerata, perche' sembra proprio un errore logico concettuale, a meno che sia fatto a bella posta. Non penso di avere esaurito lo scibile di cio' che e' inumano mettere in un programma ma e' normale trovare, se volete aggiungere le vostre impressioni sulla cosa, siate liberi di scrivermi. |
I commenti sono aggiunti quando e soprattutto se ho il tempo di guardarli e dopo aver eliminato le cagate, spam, tentativi di phishing et similia. Quindi non trattenete il respiro.
Aggiungo ? Di Aggiungo ? postato il 18/04/2008 08:34
Alessandro Di Alessandro postato il 01/05/2008 09:33
Francesco Paolini Di Francesco Paolini postato il 22/09/2008 19:02
denis Di denis postato il 22/12/2008 15:47
In realtà questa è una tecnica di buona programmazione perchè generalizza ogni ADT rendendolo dipendente dal solo modulo client!
Tu hai uno strano concetto di "buona programmazione".
denis Di denis postato il 30/12/2008 12:30
Cosa non chiara Di lufo88 postato il 15/08/2010 22:18
Di Luk64 postato il 03/11/2010 17:12
Una cosa vorrei dire oltre all'ovvia "hai ragione da vendere" :
Se vi costringono a consumare la vostra vita professionale facendo manutenzione ad un codice in origine ben scritto, se fate questo e lavorate per una società di consulenza ( traduci associazione di ignobili b......i) allora è vostro sacro dovere applicare le linee guida gentilmente postate!!!
-- Luk64
Di Anonymous coward postato il 09/01/2011 18:53
Ne ho qui delle altre:
se hai una variabile int non scriverla in int, ma in un char di 0 byte:
char a[0] = 5;
Se volete qualcosa di ancora più cattivo scrivetelo dentro una stringa... ma in esadicimale!
sprintf(a, "%x", 0xca");
Scrivete sistematicamente le stringhe senza il tappo (se per caso C insiste a mettercelo voi toglietelo!), così il poveraccio che verrà dopo di voi metterà le printf() per capire perché sto accrocchio va in core... e otterrà un core PER la printf()!
Come corrolario di quanto sopra usate le memcpy() e mencmp() in luogo di strcpy() e strcmp().
-- Anonymous coward
Davide Bianchi, lavora come Unix/Linux System Administrator presso una societa' di Hosting in Olanda.
Il presente sito e' frutto del sudore della mia fronte (e delle mie dita), se siete interessati a ripubblicare uno degli articoli, documenti o qualunque altra cosa presente in questo sito per cortesia datemene comunicazione (o all'autore dell'articolo se non sono io), cosi' il giorno che faccio delle aggiunte potro' avvisarvi e magari mandarvi il testo aggiornato.
Questo sito era composto con VIM, ora e' composto con VIM ed il famosissimo CMS FdT.
Questo sito non e' ottimizzato per la visione con nessun browser particolare, ne' richiede l'uso di font particolari o risoluzioni speciali. Siete liberi di vederlo come vi pare e piace, o come disse qualcuno: "Finalmente uno dei POCHI siti che ancora funzionano con IE5 dentro Windows 3.1".