compilare implementare art hacking

http://it.wikibooks.org/wiki/C/Blocchi_e_funzioni/Cicli

Indice

[nascondi]

[modifica] Ciclo while

Il ciclo while ripete delle istruzioni finché l’espressione specificata è vera.

Vedi anche verità e falsità in C.

La condizione viene controllata all’inizio del ciclo, e questo vuol dire che

se l’espressione è subito falsa le istruzioni nel ciclo non verranno eseguite nemmeno una volta.

[modifica] Sintassi

 while(espressione)  istruzione;  while(espressione) {  istruzione1;  istruzione2;
http://www.freenetpages.co.uk/hp/alan.gauld/italian/tutloops.htm
http://www.dis.uniroma1.it/~liberato/informatica/while.shtml

Cicli while

I cicli while sono la forma più generica di ciclo. La struttura generale è questa:

while( condizione ) {  istruzione1;  istruzione2;  ...}

Quando questo blocco viene eseguito, si compiono i seguenti passi:

  1. si verifica se la condizione è vera;
  2. se lo è, si eseguono in sequenza le istruzioni istruzione1,
  3. istruzione2, ecc., altrimenti si esce dal ciclo
  4. si verifica di nuovo la condizione,
  5. se è verificata si eseguono di nuovo le istruzioni;
  6. ...

La frase "si esce dal ciclo" indica che si passa ad eseguire

la prima istruzione che segue il blocco, ossia la prima

istruzione che viene dopo il }. In italiano, il ciclo

while si potrebbe tradurre come: "finchè la condizione

è verificata, continua ad eseguire le istruzioni".

È facile far vedere che ogni ciclo for si può tradurre in un ciclo while:

 

for(istruz1; condiz; istruz2) {           istruz1;  A;                                -->   while(condiz) {}                                           A;                                            istruz2;                                          }

D'altra parte, i cicli in cui una variabile deve venire assegnata a valori crescenti o decrescenti in un intervallo si codificano in maniera più naturale usando cicli for: il codice risulta in questo modo più breve da scrivere e più facile da capire. D'altra parte, i cicli while sono più conveniente negli altri casi di iterazione di istruzioni ma non c'è una variabile che si incrementa o decrementa.

 

Esempio: serie di Fibonacci


I cicli - O dell'arte di ripetersi!

Contenuto del capitolo
Come usare i cicli per ridurre le parti ripetitive. I differenti tipi di cicli e come usarli.

Nell'ultimo esercizio abbiamo visualizzato una parte della tavola pitagorica del 12. Ma è stato necessario parecchio lavoro di battitura e se fosse necessario estenderla dovremmo perdere ancora altro tempo. Fortunatamente c'è un modo migliore per farlo e qui cominceremo a comprendere la vera potenza dei linguaggi di programmazione.

I cicli FOR

Adesso vedremo come utilizzare il linguaggio di programmazione

per effettuare le ripetizioni, facendo uso di una variabile

che viene incrementata ad ogni ripetizione. In Python tutto questo si può esprimere cosí:

>>>for i in range(1,13):...    print "%d x 12 = %d" % (i, i*12)...

con flash

Usare l'istruzione while. 

Un ciclo while valuta un'espressione e, se l'espressione

risulta true, esegue il codice contenuto nel corpo del ciclo.

Dopo l'esecuzione di tutte le istruzioni nel corpo,

l'espressione viene nuovamente valutata. Nell'esempio

seguente il ciclo viene eseguito quattro volte:

var i:Number = 4;while (i>0) {    myClip.duplicateMovieClip("newMC" + i, i, {_x:i*20, _y:i*20});    i--;}

È possibile utilizzare l'istruzione do..while per creare

un tipo di ciclo analogo al ciclo while. In un ciclo do...

while, l'espressione viene valutata alla fine del blocco di codice,

affinché il ciclo venga sempre eseguito almeno una volta.

http://livedocs.adobe.com/flash/9.0_it/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000709.html

http://www.001design.it/forum_italiano/thread.php?id=190

[Guida Flash]: I Cicli

Dopo aver parlato degli Array nella lezione precedente,

oggi parliamo dei cicli, di cosa sono, a che servono,

e faremo i soliti esempi (in cui vedremo come leggere gli array con un ciclo).

- Cos’è un Ciclo e a cosa Serve?

Un Ciclo è un istruzione di ActionScript che permette

di eseguire un blocco di codice ripetutamente finché non si verifica una certa condizione.

- Quanti Tipi di Ciclo ci sono?

Abbiamo a disposizione 4 tipi di cicli tra cui scegliere in base alle nostre esigenze, e sono:

For (il più usato)

While

Do…While

For…In

Vediamoli uno ad uno, e spieghiamo come funzionano,e come e quando  si devono usare!

Il Ciclo For:

Il ciclo “for” è il più semplice come logica ed anche

il più usato come ho accennato prima.

Un esempio di codice per un ciclo for è il seguente:

http://www.sv-design.org/blog/guida-flash-i-cicli/

 

  • ww.webmaster-risorse.com/php/forwhiledo.asp - 16k - Copia cache - Pagine simili
  • In.F.Or. Informatica - Introduzione al Linguaggio C

    Il ciclo while viene principalmente usato nei casi dove
  • non sia preventivamente ... Il ciclo do-while si
  • differenzia dal ciclo while che abbiamo visto in ...
    www.in-f-or.it/informatica/c/cap43.html
  •  


    Funzioni

    Prepariamo una funzione (da inserire nel file di intestazione personale) per l'analisi dei caratteri.
    La funzione dovrà accettare come parametro una variabile di tipo char e stampare sul monitor tutte le informazioni che siamo in grado di estrarre dal codice ASCII della variabile stessa, ovvero:

    1. determinare se si tratti di una lettera e, nel caso, determinarne l'altezza (minuscola / maiuscola)
    2. determinare se si tratti di un carattere numerico
    3. determinare se si tratti di un segno di punteggiatura ( , . ; : ? " ' ! )
    4. determinare se si tratti di un simbolo matematico ( % + - * / < > = ( ) )
    5. determinare se si tratti di un carattere di controllo (^Z (= ctrl + Z), ^C, ^Y)
    6. determinare se si tratti di un simbolo non compreso nell'elenco precedente


    Alcune di queste funzionalità sono state implementate in precedenza;

    a queste ne andranno aggiunte altre basate sul riconoscimento

    dei codici ASCII dei singoli caratteri.

    Cominciamo con lo stabilire quale sarà il prototipo della funzione:
    il parametro sarà una variabile di tipo char
    il tipo del valore da restituire potrebbe essere un

    intero avente il seguente significato: se il confronto ha successo,

    ovvero il carattere viene identificato, la funzione restituisce un 2, altrimenti un 1.

    // inizio file di intestazione myfun.h (versione 1)

    /*
    La funzione analisi_char() serve al riconoscimento dei caratteri.

    Se il parametro rientra tra i tipi di carattere previsti,

    la funzione restituisce un 2, altrimenti la funzione restituisce 1

    (carattere non riconosciuto)
    */

    #include <stdio.h>

    http://web.unife.it/utenti/federico.spizzo/indice/fun_while.html

    si ritorna sui cicli annidati come ieri

    http://www.pluto.it/files/ildp/guide/abs/loops.html

    poi un doku wiki come quello che ho nel sito sul php

    http://www.phpbook.it/doku.php?id=prog_cicli

    e poi google libri ok ok

    http://books.google.it/books?id=R74ADG08pBEC&pg=PA89&lpg=PA89&dq=ciclo+for+ciclo+while&source=web&ots=EVwifyV0BP&sig=ekNzVKk6enS0HdNWQxIBZyHgPOQ&hl=it&sa=X&oi=book_result&resnum=10&ct=result

    [PS]

    Capitolo 5: Sintassi del linguaggio C

    Formato file: Adobe PostScript - Versione HTML
    identicatore di canale di comunicazione (di solito si
    tratta di un numero intero , che in C e. considerato
    essere un puntatore ad un tipo di variabile detta ...
    www.disi.unige.it/person/BoccacciP/dispense/cap5.ps.gz
    variabile tipo argomenti

    Programmi con argomenti

    Quando si compila un programma C viene generato un file eseguibile

    (.exe sotto dos). Questo programma può venire eseguito direttamente

    scrivendo il suo nome sulla linea di comando (finestra PromptMSDOS

    sotto Windows). Come è noto, ai programmi eseguibili è possibile

    passare degli argomenti. Per esempio, il programma copy.exe,

    che fa parte del sistema operativo, viene eseguito scrivendo

    due nomi di file dopo il nome del programma. Il programma è

    in grado di leggere questi due nomi, e comportarsi di conseguenza,

    copiando il primo file sul secondo. Il punto fondamentale è che un

    programma esguibile deve in generale essere in grado di poter usare

    i parametri con cui è stato lanciato, ossia le stringhe che seguono

    il nome del programma sulla linea di comando.

    http://www.dis.uniroma1.it/~liberato/struct/argomenti/index.shtml

    e prosegue con listati che troveremo anche nell arte dell hacking

    (vedi mio server autistici.org/sens)

    /*  Elimina da un nome di file la sua estensione.*/#include<stdlib.h>#include<stdio.h>int main(int argn, char *argv[]) {  int i;    /* controllo argomenti */  if( argn-1!=1 ) {    printf("Numero errato di argomentin");    exit(1);  }  /* ciclo di stampa */  i=0;  while( argv[1][i]!=0 && argv[1][i]!='.' ) {    printf("%c", argv[1][i]);    i++;  }  printf("n");  return 0;}
    

    In C, è possibile accedere a queste informazioni

    modificando la intestazione della funzione main.

    I programmi visti fino ad ora usavano una intestazione di questo tipo:

    http://www.dis.uniroma1.it/~liberato/struct/argomenti/progs/noext.c

    http://www.dis.uniroma1.it/~liberato/struct/argomenti/progs/commenti.c

    prpgrammi implementati

    7.1.5. Path ricerca (programmi implementanti) comandi []

    Come si è visto i comandi non built-in sono implementati attraverso

    file eseguibili localizzati in diversi possibili direttori del file

    system (/bin, /usr/bin, ecc.). Il file eseguibile potrebbe inoltre

    trovarsi non solo nei direttori di sistema, ma anche nei direttori

    dell'utente (per es. nel direttorio corrente).

    Si è anche visto che l'utente può impartire il comando citando il path

    (relativo o assoluto) del file eseguibile che lo implementa:

      $ /bin/ls *
    

    Ma più comunemente l'utente digiterà il comando come semplice

    parola senza indicare il path (per es. "ls"). In questo caso

    si pongono alcuni problemi: non avendo specificato il file eseguibile,

    quale file ed in quale direttorio la shell (Bourne o Korn o C)

    ricercherà il file da eseguire? e nel caso che nel file system

    siano presenti più file eseguibili candidati quale di questi verrà eseguito?

    Per convenzione quando si impartisce un comando (non built-in)

    specificando solo la parola che lo identifica e non il filename

    (la shell cerca se nel nome c'è o meno il carattere '/',

    non necessariamente all'inizio), il file eseguibile che

    gli corrisponde avrà lo stesso nome. Per esempio dando

    il comando mail sicuramente verrà eseguito un file

    www.dis.uniroma1.it/~liberato/struct/argomenti/index.shtml

    come faremo ............

    Vediamo come compilare i programmi in C sotto Linux, utilizzando i vari strumenti presenti in questo sistema e nei vari sistemi Unix

     

    Compilare i programmi sotto Linux

    di Lorenzo Bettini e Antonio Gallo

     

    Gli utenti diel PC, e soprattutto quelli che utilizzano Windows, sono ormai abituati al concetto di programma, pensato come eseguibile; con questo termine si intende il classico file .exe (o gli ormai sempre più rari .com). In ambiente Unix e soprattutto Linux, le cose sono leggermente differenti, e ci si trova spesso a dover “creare” tale programma. In questo articolo vedremo come utilizzare i tool di programmazione per il linguaggio C, presenti sotto Linux, e nei vari sistemi Unix, per “costruirsi” gli eseguibili. L’articolo non avrà la pretesa di insegnare a programmare in C, anche perché non basterebbe un libro per tale scopo; l’intento principale sarà quello di mettere in grado anche chi non è un programmatore di compilare i programmi che sono forniti solo in sotto formato di sorgentei (come spesso accade sotto i sistemi Unix); del resto i programmatori in ambiente Windows, abituati ad ambienti visuali, avranno la possibilità di conoscere i comandi utili per scrivere e compilare programmi sotto questi sistemi.

     

    Sorgente, binario e compilatore

    Gli eseguibili di cui si è parlato sopra sono anche detti binari; con questo si intende (estendendo il significato base del termine), che tali file contengono codice macchina, cioè scritto in linguaggio macchina, e quindi direttamente eseguibile dal processore. Il processore riconosce solo sequenze di 0 e di 1 (da qui il nome di binario), e sarebbe molto difficile, per un programmatore, scrivere un programma direttamente in linguaggio macchina. Un passo avanti sarebbe utilizzare il linguaggio assembler, in cui ogni istruzione corrisponde ad un’istruzione in linguaggio macchina. Per ovviare a questi inconvenienti sono stati creati i cosiddetti linguaggi ad alto livello, coi quali è possibile scrivere programmi utilizzando una sintassi molto più vicina al linguaggio naturale. Del resto, per quanto detto, il processore è in grado di riconoscere solo sequenze di 0 ed 1, e quindi si rende necessario un mezzo per tradurre un programma scritto con un linguaggio ad alto livello in un programma in linguaggio macchina. Per questo sono stati pensati i compilatori. La definizione classica di compilatore [Aho] è: un compilatore è un programma che traduce da un linguaggio detto sorgente in un altro linguaggio detto target. Tipicamente, e senz’altro nel nostro caso, il linguaggio sorgente è un linguaggio ad alto livello, mentre il linguaggio target è il linguaggio macchina. Il programma scritto col linguaggio ad alto livello viene detto sorgente. Ovviamente un programma complesso sarà costituito da più listati sorgente (di questo si parlerà nel corso dell’articolo). I programmi ad alto livello più utilizzati, almeno in ambiente Windows, sono Visual Basic, Delphi, e C/C++. In ambiente Unix invece prevale il C.

     

    Due filosofie a confronto

    Se adesso si andasse a cercare i sorgenti dei programmi Windows che si è utilizzato fino ad adesso, è altamente probabile che la ricerca abbia esito negativo. Questo del resto non ci impedisce di utilizzare tali programmi: una volta che si ha il programma eseguibile (scritto in linguaggio macchina) non si ha più bisogno dei sorgenti, come quando si legge un libro tradotto in Italiano non si ha bisogno della versione originale, scritta in un’altra lingua.

    L’assenza dei sorgenti nei programmi commerciali è comunque dovuta alla volontà da parte della casa produttrice di proteggere il proprio software: se gli altri potessero vedere come è realizzato un certo programma, potrebbe poi non essere più necessario acquistare gli aggiornamenti, e senz’altro si sarebbe in grado di superare le varie protezioni software che rendono necessario l’acquisto della licenza dei programmi. Questa è una filosofia commerciale.

    Linux, da parte sua, è nato come sistema operativo gratuito seguendo la filosofia del gruppo GNU [gnu], che sostiene il software OpenSource [OSS]free; con questo termine riguarda soprattutto la disponibilità dei sorgenti: a partire dal sistema operativo stesso il software della GNU, e comunque tutto il software distribution sotto che segue la licenza GPL, viene distribuito insieme ai sorgenti lasciando libera la possibilità di apportarvi modifiche. E’ un po’ come acquistare un libro tradotto, ma col testo originale a fronte. Da un lato è possibile consultare i sorgenti dei vari programmi in modo da apprendere nuove cose, ma anche, e soprattutto, apportare modifiche e correzioni (in questo modo tutti potranno usufruire del lavoro di tutti); dall’altro, avendo i sorgenti, è possibile costruire il programma (compilandolo) anche su altre macchine (teoricamente anche su altri sistemi, anche se più che altro tale software è pensato per ambienti Unix).

    A tal proposito la maggior parte del software disponibile per Unix è scritto in C (ed in minor parte in C++); è quindi necessario avere un compilatore C per costruirsi il programma eseguibile (o i programmi) vero e proprio. Fortunatamente questo non è un problema, in quanto la GNU mette a disposizione un potentissimo compilatore C/C++ e tantissimi tool di sviluppo, che si possono trovare in tutte le distribuzioni di Linux. Del resto tali tool sono disponibili, come corredo standard, anche negli altri sistemi Unix.

    Non è nostra intenzione criticare la prima filosofia rispetto a quella software libero: entrambe hanno le loro motivazioni ed il loro diritto di esistere.

     

    Il compilatore C sotto Linux

    Per chi è abituato ai vari ambienti visuali sotto Windows, l’impatto con la linea di comando dei tool per il C sotto Linux è abbastanza drammatico. Tuttavia, una volta preso un minimo di confidenza, si sentirà sempre meno la necessità di un ambiente integrato. Vediamo quindi alcuni esempi di utilizzo del compilatore C; per tale scopo utilizzeremo il classico programma Hello World, che semplicemente scrive un saluto sullo schermo (Listato 1):

    per compilare un tale programma (supponendo che sia memorizzato nel file hello.c) basterà lanciare il seguente comando:

     

    gcc hello.c

     

    gcc è il comando del compilatore C della GNU; sugli altri sistemi Unix tale compilatore può chiamarsi semplicemente cc. In ambiente Linux, per mantenere questo nome è di solito presente anche cc (un link simbolico a gcc).

    Se non ci sono errori nella compilazione, ed in questo caso non dovrebbero esserci, alla fine si avrà nella directory un file a.out, che potrà essere eseguito per vedere il programma hello in esecuzione. Nella directory sarà anche presente il file hello.o, che non è altro che la traduzione in linguaggio macchina del nostro programma (o sta per codice oggetto, mentre in ambiente Windows spesso l’estensione è obj), ma non direttamente eseguibile. Infatti l’istruzione printf è in realtà la chiamata di una funzione, che è implementata nella libreria standard del C (una sorta di repository con varie funzioni di utilità generale). Il prototipo di tale funzione (cioè il numero di parametri richiesti dalla funzione ed il tipo di ritorno) è contenuto nel file stdio.h che viene (letteralmente) incluso all’inizio del programma. Tali file sono una caratteristica del C e vengono detti file header (intestazione). In realtà la creazione di un programma è una procedura che avviene in diversi passi riassumibili principalmente in:

     

    1. compilazione: vengono creati i file oggetto (con la traduzione in linguaggio macchina dei sorgenti)

    2. linking: viene creato l’eseguibile vero e proprio, aggiungendo il codice della funzioni di libreria utilizzate.

     

    In realtà col comando lanciato i due passi vengono eseguiti automaticamente, ed alla fine i file oggetto potranno essere cancellati in quanto non necessari per eseguire il programma (si tratta solo di file intermedi).

     

    Alcune opzioni di compilazione

    In realtà il compilatore gcc ha tantissime opzioni [GCC], ed alcune di queste sono molto utili. La prima che vediamo è quella che ci permette di stabilire un nome per il file di output del compilatore, che nel nostro caso è il programma eseguibile: ad esempio se volessimo chiamare il programma hello (in Unix non è necessario che gli eseguibili abbiano una estensione, anzi di solito non ce l’hanno), il comando sarà

     

    gcc –o hello hello.c

     

    quindi l’opzione –o filename permette di definire il nome del file di output.

    E’ inoltre possibile eseguire separatamente le due fasi di creazione del programma (si vedrà più avanti che nel caso il programma sia costituito da più sorgenti questo è necessario): prima la compilazione (con l’opzione –c):

     

    gcc –c hello.c

     

    e poi la creazione dell’eseguibile, cioè la fase di linking:

     

    gcc –o hello hello.o

     

    Il comando del linker in Linux è ld, ma sarebbe necessario passare alla linea di comando esplicitamente altre opzioni, come la libreria standard del C, e questo può essere noioso. Fortunatamente però il gcc riconosce le estensioni degli argomenti, ed agisce di conseguenza: nell’ultimo comando non esegue la compilazione, ma il linking, in quanto il file passato è un file oggetto. Inoltre provvede automaticamente a collegare il nostro file oggetto con la libreria standard del C. Anche per un programma scritto in C++ non è necessario utilizzare un altro compilatore (il compilatore esplicito per il C++ si chiama g++ oppure c++): basterà specificare come estensione .cc; infatti per compilare il file hello.cc (versione scritta in C++ del precedente programma, e disponibile sul sito web dell’Infomedia), il comando di compilazione non sarà molto diverso:

     

    gcc –c hello.cc

     

    Il compilatore riconosce che si tratta di un programma C++ dall’estensione .cc. Purtroppo non è in grado di riconoscere che si tratta di un file oggetto C++, in quanto anche in questo caso viene creato hello.o; allora è necessario effettuare il linking richiamando direttamente il comando del compilatore C++ (e visto che ci siamo chiamiamo l’eseguibile in un altro modo):

     

    g++ -o hello2 hello.o

     

    Nella tabella 1 sono rappresentate alcune delle convenzioni per le estensioni dei file utilizzate dal gcc.

    Passiamo adesso a programmi più complessi.

     

    Librerie statiche e librerie dinamiche

    Tutti i programmi C fanno uso di funzioni, come ‘printf’, che fanno parte di libreriea di sistema (la libc in questo caso). Le librerie sono di due tipi: statiche e dinamiche. La differenza fondamentale tra le due tipologie è il modo in cui vengono collegate al programma eseguibile.

    Le librerie statiche (con estensione .a), sono linkate insieme ai file oggetto per formare il file eseguibile. Questo aumenta di molto le dimensioni del programma ma in alcuni casi è utile per evitare problemi che spesso si hanno con l’utilizzo delle librerie dinamiche. La presenza delle librerie statiche non è necessaria al momento dell’esecuzione del programma.

    Le librerie dinamiche (con estensione .so), non vengono linkate all’interno del file eseguibile ma restano separate. Sarà compito del sistema operativo, all’atto del caricamento del programma in memoria, di caricare tutte le librerie dinamiche richieste dall’eseguibile. In questo modo, oltre a ridurre le dimensioni di quest’ultimo, ogni libreria dinamica, è caricata in memoria una sola volta anche se sono presenti più processi che la utilizzano. Le librerie dinamiche, affinché l’eseguibile possa girare correttamente, devono essere presenti nel sistema, ma spesso ciò non accade.

    Per risolvere quest’ultimo problema, Linux ci viene incontro fornendoci il tool "ldd". Questo ci permette di determinare quali librerie vengono utilizzate da un file eseguibile. Eccone un esempio di utilizzo:

     

    # ldd /sbin/ldconfig

    statically linked (ELF)

     

    # ldd /bin/echo

    libc.so.5 => /lib/libc.so.5 (0x40009000)

     

    Nella prima riga dell’esempio viene eseguito il comando ldd sul file ‘ldconfig’, il risultato è che il file risulta linkato staticamente in formato ELF. Nel secondo esempio, invece, il comando "echo" risulta linkato dinamicamente alla libreria di sistema (libc.so.5), inoltre viene indicato il percorso dove tale libreria si trova.

     

    Risolvere alcuni problemi di compilazione

    Tra i tanti problemi di compilazione che possono insorgere, i più frequenti sono quelli dovuti al fatto che il compilatore non riesce a trovare dei file header, o delle librerie. Vediamo come esempio il programma nel Listato 2 che crea una finestra in X-Window utilizzando la libreria GTK (www.gtk.org). Provando a compilare questo programma otteniamo:

     

    # gcc gtk-hello.c

    gtk-hello.c:1: gtk.h: No such file or directory

     

    Il messaggio d’errore è stato generato perché il compilatore non ha trovato l’header "gtk.h" nei suoi percorsi di ricerca. Per risolvere questo problema dobbiamo specificare al compilatore dove cercare tale file. Se non si conosce la directory dove si trova tale file, è possibile cercarlo con il seguente comando:

     

    # find / -xdev -name gtk.h

    /usr/include/gtk/gtk.h

     

    una volta localizzatoche sappiamo dove si trova il file, utilizzando l’opzione -I, possiamo specificare al compilatore un ulteriore percorso aggiuntivo per la ricerca degli header file

     

    #gcc gtk-hello.c -I/usr/include/gtk/

    /tmp/cca006371.o: In function Main’:

    /tmp/cca006371.o(.text+0xc): undefined reference to G_print’

    /tmp/cca006371.o(.text+0x1c): undefined reference to Gtk_init’

    .

    .

    .

    collect2: ld returned 1 exit status

     

    La compilazione del programma è andata bene, ma questa volta è stato il linker ‘ld’ a segnalare che non è stato possibile ‘risolvere’ alcuni ‘simboli’. Questo perché non abbiamo specificato quali sono le librerie dinamiche da collegare al programma. CiòQuesto si ottiene utilizzando l’opzione -l (elle minuscola), come nel seguente esempio:

     

    # gcc gtk-hello.c -I/usr/include/gtk -lgtk -lgdk -lglib -lXext -lX11 -lm

    /usr/i586-pc-linux-gnulibc1/bin/ld: cannot open -lXext: No such file or directory

    collect2: ld returned 1 exit status

     

    specificare quali librerie dinamiche utilizzare non è a volte sufficiente, occorre anche dire al linker dove cercarle. Per far ciò si utilizza il parametro -L per specificare percorsi di ricerca aggiuntivi per le librerie.

     

    # gcc gtk-hello.c -I/usr/include/gtk -lgtk -lgdk -lglib -lXext -lX11 -lm -L/usr/X11R6/lib -o gtk-hello.exe

     

    Al termine del comando l’eseguibile è pronto per essere lanciato con il nome di gtk-hello.exe

     

    Compilare un programma più complesso

    Non tutti i programmi sono basati su un unico file sorgente, progetti software medio-grandi superano facilmente il centinaio. In questi casi si utilizza il tool ‘make’.

    Make è un programma scritto appositamente per automatizzare il processo di compilazione. Il funzionamento di make è controllato da un "Makefile". Questi è un programma che contiene al suo interno una serie di "macro" (comandi orientati all’elaborazione di testo) e "rules" (regole), che gli forniscono informazioni su quali sorgenti compilare e secondo quale modalità, basandosi sulla data dell’ultima modificadata dei file. Un esempio di Makefile utilizzabile per compilare il precedente programma è illustrato nel Listato 3. Partendo dall’alto notiamo una serie di variabili: CC, indica il compilatore da utilizzare; CFLAGS, i parametri da passare al compilatore; LDFLAGS, le librerie da utilizzare per linking; LDPATHS, i percorsi dove il linker deve cercare le librerie; INCLUDES, i percorsi dove il compilatore deve cercare gli header file; HEADERS, la lista degli header del progetto; OBJECTS, la lista di tutti i file oggetto che make deve creare; PROGRAM, infine, è il nome del programma eseguibile da creare.

    Dopo questo elenco di variabili incontriamo la prima regola, in cui vengono specificate le ‘dipendenze’ per il target ‘all’, questo è il target di default quando make viene eseguito senza specificare parametri.

    Nell’esempio fornito il target ‘all’ viene utilizzato per istruire make in modo tale che crei il file eseguibile e tutti i file oggetto.

    La regola successiva, invece, istruisce make su come creare il programma eseguibile (viene specificata la riga di comando per effettuare il linking dei file oggetto). Inoltre viene stabilito che l’eseguibile gtk-hello.exe "dipende" da i file specificati nelle variabile OBJECT ed HEADER.

    Come creare i file oggetto, partendo dai file sorgente, éviene specificato nella regola ‘.c.o:’. Questa regola dice a make che un file .o può essere creato elaborando il corrispondente file .c utilizzando il comando specificato nella linea successiva.

    L’ultima regola, ‘clean’ viene utilizzata per iniziare ex-novo una nuova compilazione cancellando l’eseguibile e tutti i file oggetto.

    Il programma d’esempio può essere compilato nel seguente modo:

     

    # make clean ; make

    rm -f gtk-hello.o gtk-hello.exe

    gcc -c gtk-hello.c -g -O2 -Wall -I/usr/include/gtk -o gtk-hello.o

    gcc -lgtk -lgdk -lglib -lXext -lX11 -lm -lc -L/lib -L/usr/lib -L/usr/X11R6/lib -o gtk-hello.exe gtk-hello.o

     

    L’eseguibile è stato creato e, volendo, si può controllare quali sono le librerie che utilizza.

    Make ed i Makefile oltre ad automatizzare il processo di compilazione lo velocizzano. Infatti rilanciando nuovamente make otteniamo:

     

    # make

    make: Nothing to be done for ‘all’.

     

    questo perché make non ricrea nessun file a meno che una delle ‘dipendenze’ non sia soddisfatta (sempre basandosi sulla data dell’ultima modifica). Infatti, se modifichiamo un file sorgente, solo il file oggetto (che risulterà più “vecchio”), corrispondente al sorgente modificato, verrà ricreato; il vantaggio in termini di tempo è chiaramente tangibile.

    Creare un Makefile è fuori dallo scopo di quest’articolo, chi vuole approfondire il discorso può leggere la documentazione (info make) allegata al tool.

     

    Compilare un programma GNU

    Compilare un programma GNU è un’operazione abbastanza semplice se si hanno già a disposizione tutte le librerie come prerequisitonecessarie alla compilazione del programma. Una volta ottenuto l’archivio contenente il programma in formato sorgenteda compilare è consigliabile estrarlo nel sotto il percorso /usr/local/src destinato alla compilazione di programmi per uso ‘locale’. Per estrarre un programma in formato tar.gz si può fare nel seguente modo:

     

    # cd /usr/local/src

    # tar -zxvf nome.archivio.tar.gz

     

    Prima di procedere a qualsiasi operazione successiva vale la pena spendere un pòo’ di tempo nella lettura dei file README ed INSTALL di solito forniti a corredo. La lettura di questi file è indispensabile per capire se il nostro sistema ha tutti i prerequisiti necessari all’installazione del programma.

    I programmi GNU non sono di solito forniti con Makefile, è infatti necessario lanciare lo script ‘configure’ per crearli. Questo script analizza il sistema su cui sta girando, creando un Makefile ‘ad-hoc’ da poter essere utilizzato sull’a attuale piattaforma. Questo sistema rende un programma GNU, non solo portatile attraverso i vari tipi di Unix, ma anche attraverso i vari tipi di processori.

    Prima di eseguire ‘configure’ e può valere la pena leggere le opzioni che a volte contengono informazioni non contenute nella documentazione, col seguente comando:

     

    # ./configure --help | more

     

    Se configure termina con successo il programma potrà essere compilato ed installato con i seguenti comandi:

     

    # ./configure --prefix=/usr/local/

    # make

    # make install

     

    Il parametro prefix specifica a configure di creare i Makefile in modo tale che i file eseguibili vengano installati all’interno della gerarchica /usr/local

    Per districarsi tra la miriade di messaggi generati da make & make install si puo’ usare la seguente sintassi:

     

    # make && make install && echo "Tutto OK !"

     

    cio’ garantisce che il messaggio finale vengae’ stampato solo se le due operazioni precedenti sono andate a buon fine.

     

    Conclusioni

    Come abbiamo visto la compilazione di un programma GNU risulta abbastanza facile se il sistema risulta correttamente configurato. Chi volesse approfondire l’argomento e non ha a disposizione Linux può cercare sul sito della Cygnus (www.cygnus.com) il compilatore gcc per win-32, oppure sul sito di DJ Delorie (www.delorie.com) per il compilatore gcc per DOS (djgpp), che genera comunque programmi a 32 bit.

    Approfondiremo alcuni degli argomenti trattati in articoli successivi.

     

    Bibliografia

    [Aho] A.V.Aho, R.Sethi, J.D.Ullman Compilers, Principles, Techniques, and Tools, 1987, Addison Wesley.

    [gnu] GNU Home site: www.gnu.org

    [GCC] Guida in linea del compilatore C della GNU

    [OSS] www.opensource.org

    compilare

     

    http://www.badpenguin.org/press/infomedia/compilare.html

    stessa guida del C che parla di ambedue i sistemi operativi .exe e .c

    .bath e .ssh

    per fare heh he scherzo

    http://thefirsthacking.forumcommunity.net/?t=18945983

    link parole usate

    http://www.google.it/search?hl=it&q=variabile+tipo+C+controllato+in+un+eseguibile&meta=

    siamo a pag. 11 altri concetti fondamentali di programmazione

    variabili

     

     

     

     

      /.../mail
    

     

    int main() ...
    

    Per poter usare gli argomenti con cui il programma è stato lanciato, questa linea deve diventare:

    int main(int argn, char *argv[]) ...
    
     
    

  •  

    This entry was posted in Generale. Bookmark the permalink.