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

From Sistemi Operativi
Jump to navigation Jump to search
Line 61: Line 61:
 
int main(int argc, char *argv[]) {
 
int main(int argc, char *argv[]) {
 
         printf("%s %s\n",st0.s,st0.t);
 
         printf("%s %s\n",st0.s,st0.t);
         foo(st0);
+
         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);
+
         printf("%s %s\n",st0.s,st0.t);  
         bar(&st0);
+
         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);
 
         printf("%s %s\n",st0.s,st0.t);
 
         return 0;
 
         return 0;
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 
== programma 3 ==
 
== programma 3 ==
 
<syntaxhighlight lang="C">
 
<syntaxhighlight lang="C">

Revision as of 14:02, 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. [Utente 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. [utente 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;
}

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

[Utente 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) {
        if (*elp && strcmp((*elp)->s, s) < 0) 
                insert(s,&((*elp)->next));
        else {
                struct elem tmp={s,*elp};
                struct elem *new=malloc(sizeof(struct elem));
                *new=tmp;
                *elp=new;
        }
}

struct elem *print(struct elem *root) {
        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++)
                insert(argv[1],&root);
        root=print(root);
        printf("\n");
        return 0;
}