Difference between revisions of "Esercizi di lettura di codice C"

From Sistemi Operativi
Jump to navigation Jump to search
Line 68: Line 68:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
Output del programma:
 +
 +
test test
 +
 +
test tent
 +
 +
text text
 +
 +
([[User:S.G|S.G]])
  
 
== programma 3 ==
 
== programma 3 ==

Revision as of 14:59, 15 October 2015

Questi programmi non sono necessariamente stilisticamente belli (non sono "esempi da copiare") ma presentano dei passaggi di non semplice lettura.

Il consiglio e' di compilarli, provarli e capirne passo-passo il funzionamento. (o spiegare perche' non funzionino).

Ovviamente potete proporre ulteriori esempi. Renzo (talk) 15:42, 10 October 2015 (CEST)

programma 0

#include <stdio.h>

int main(int argc, char *argv[]) {
        int c;
        while ((c=getchar())!=EOF)
                putchar(c);
        return 0;
}

In questo esempio tutto ciò che viene preso in input viene messo in output, fino a quando non viene digitato il carattere di End of File (EOF). Solitamente nei sistemi DOS il carattere EOF viene definito come la combinazione di tasti CTRL+Z, mentre nei sistemi basati su Unix si utilizzano i tasti CTRL+D. (S.G)

programma 1

#include <stdio.h>

char s1[]="hello world";
char *s2="hello world";

void foo(char *s) {
        printf("%s\n",s);
        s[4]=',';
        printf("%s\n",s);
}

int main(int argc, char *argv[]) {
        foo(s1);
        foo(s2);
        return 0;
}

In questo esempio viene mostrata la differenza tra stringa variabile (s1) e stringa costante (s2). Nel primo caso a tempo di compilazione la stringa costante "hello world" viene copiata passo nella stringa variabile s1 consentendo le normali operazioni di modifica della stringa stessa. Mentre nel secondo caso a tempo di compilazione viene creata la stringa costante "hello world" e memorizzato il suo indirizzo nella variabile s2 NON consentendo le normali operazioni di modifica delle stringa stessa in quanto appunto un costante. (S.G)

programma 2

#include <stdio.h>

char t[]="test";
struct st {
        char s[5];
        char *t;
} st0={"test",t};

void foo (struct st i) {
        i.s[2]='n';
        i.t[2]='n';
}

void bar (struct st *i) {
        i->s[2]='x';
        i->t[2]='x';
}

int main(int argc, char *argv[]) {
        printf("%s %s\n",st0.s,st0.t);
        foo(st0); /* Vengono copiati i valori della struttura st0 in i, le uniche modifiche saranno sul campo i.t in quanto puntatore. */
        printf("%s %s\n",st0.s,st0.t); 
        bar(&st0); /* Viene copiato l'indirizzo della struttura st0 in i, le modifiche vengono apportate su tutti i campi delle struttura. */
        printf("%s %s\n",st0.s,st0.t);
        return 0;
}

Output del programma:

test test

test tent

text text

(S.G)

programma 3

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
        while (argc > 1) {
                int i,j;
                char *s=argv[1];
                for (i=0, j=strlen(s)-1; i < j; i++, j--)
                        s[i] ^= s[j], s[j] ^= s[i], s[i] ^= s[j];
                printf("%s ",s);
                argc--;
                argv++;
        }
        printf("\n");
        return 0;
}

In questo esempio il programma effettua un reverse di tutte le parole che gli vengo date in input ad esclusione di argv[0] che sarebbe il nome del programma, esempio:

INPUT: ./programma3 ciao sistemi operativi

OUTPUT: oaic imetsis ivitarepo

Il punto importante di questo codice è che lo scambio delle singole lettere viene effettuato con l'operatore logico XOR senza cosi avere bisogno di una "variabile di scambio". Qui viene spiegato nel dettaglio il funzionamento dell'operatore logico

(S.G)

programma 4

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct elem {
        char *s;
        struct elem *next;
};
struct elem *root=NULL;

void insert(char *s, struct elem **elp) { /* Inserimento in ordine alfabetico */
        if (*elp && strcmp((*elp)->s, s) < 0) /* se la lista elp non è vuota e se (*elp)->s è alfabeticamente minore di s, inserisce in coda s */
                insert(s,&((*elp)->next));
        else { /* nel caso in cui la lista è vuota o se (*elp)->s è alfabeticamente maggiore di s, inserisce in testa s */
                struct elem tmp={s,*elp};
                struct elem *new=malloc(sizeof(struct elem));
                *new=tmp;
                *elp=new;
        }
}

struct elem *print(struct elem *root) { /* stampa l'intera lista, alla fine dealloca root e restituisce NULL */
        if (root) {
                printf("%s ",root->s);
                root->next=print(root->next);
                free(root);
                return NULL;
        }
}

int main(int argc, char *argv[]) {
        for (;argc>1;argc--,argv++) /* Scorre tutti gli elementi in input del programma (tranne il nome stesso del programma), aggiungendoli in una lista */
                insert(argv[1],&root);
        root=print(root);
        printf("\n");
        return 0;
}

Il programma ordina alfabeticamente gli elementi presi input, esempio:

INPUT: ./programma4 ciao sistemi operativi e macchine virtuali

OUTPUT: ciao e macchine operativi sistemi virtuali

(S.G)