Laboratorio di Programmazione. AA 2004/05.
Esercitazione n. 8

Scopo di questa esercitazione è di familiarizzarsi con i puntatori, array e stringhe.

Al solito, si suggerisce di creare una directory apposita per i files relativi a questa esercitazione.
Ricordare inoltre che i prototipi delle function di libreria per operare sulle strighe risiedono nel file di header string.h.Per utilizzare malloc invece è  necessario il file di header  stdlib.h.


     
  1. Dato il seguente programma
       #include <stdio.h>
    int main(void){
    float a[4]= { 1.30, 2.30, 3.30, 14.60}, *ip, *iq;
    ip = &a[0];
    iq = ip;
    printf("valore di a[0]: %f,indirizzo di a[0]: %p \n", a[0], &a[0]);
    return 0;
    }
    Aggiungere anche la scrittura di
     *ip, &ip, ip, a (con gli opportuni convertitori di formato)
    e interpretare i risultati. Aggiungere quindi anche la stampa di
     *ip + 3 e  *(ip+3)
    ed interpretare anche questi risultati.

  2. Scrivere un programma che dichiari un array float di 10 elementi e poi legga i valori e ne calcoli la somma delle radici quadrate (e la scriva).

  3. Scrivere un programma che legga N valori interi in input e li memorizzi in un array e li ordini in ordine crescente mediante bubblesort (si itera per un numero sufficiente di volte l' esame di tutte le coppie  consecutive di elementi  ordinandole  se necessario).  Un modo per "scambiare di posto" due elementi consecutivi dell' array e' il seguente:
    tmp    = a[i];
    a[i] = a[i+1];
    a[i+1] = tmp;



    Successivamente trasformare la parte di ordinamento in una function.

  4. Scrivere un programma che dichiari ed inizializzi due  array a due indici (matrici) di dimensione 2x2 e poi calcoli la matrice prodotto i cui elementi sono dati da

    cij = Somma_su_k_da_1_a_2     aik bkj

    per 1 <= i<= 2 e 1 <= j<= 2

    Tener conto dei diversi limiti degli indici degli arrays C. L'algoritmo da cui partire può   essere descritto come: per ogni i nell' intervallo [1,2]; per ogni j nell' intervallo [1,2]; si inizializzi c[i][j] = 0; per ogni k nell' intervallo [1,2]; si sommi al precedente valore di c[i][j] il prodotto a[i][k]*b[k][j].


  5. Cosa scriverà il seguente programma ?

    #include <stdio.h>

    int main(void){
    int i;
    char s1[] = "Immetti un numero";
    for(i=0;i< sizeof(s1); i++)
    printf("%c \n",s1[i]);
    printf("%s \n",s1);
    return 0;
    }

    Modificarlo in modo da introdurre una seconda stringa di lunghezza 40 e copiarvi sopra la stringa s1.

    E come funziona la seguente versione alternativa del programma ? Perché  l'output di questo programma è  diverso da quello del precedente ?
    #include <stdio.h>

    int main(void){

    char *p = "Immetti un numero";

    while(*p)
    printf("%c \n",*p++);

    printf("%s \n",p);
    return 0;
    }


  6. Data le  seguenti dichiarazioni delle stringhe  s1 ed s2:
      
    char s1[20]="Pippo";
    char s2[30];
    verificare ed interpretare il risultato  di
     sizeof(s1)
    sizeof(s2)
    strlen(s1)
    strlen(s2)
     
     E se le istruzioni precedenti fossero in una function ?

    Copiare quindi la stringa s1 su s2 mediante la function di libreria strcpy. (Utilizzarla come:     strcpy(s2,s1);    Occorre anche includere il file di sistema  string.h.  Per maggiori informazioni: man strcpy) Ristampare il risultato di 

     strlen(s2)
    Infine dichiarare un puntatore a caratteri, pc, allocare memoria con l' istruzione
    pc = malloc(...);
    Dove   al posto dei puntini, nella chiamata a malloc, va data la lunghezza della stringa che vogliamo utilizzare (la possiamo ricavare dai dati ottenuti fin qui). Infine copiare s1 nell' area riservata a pc e visualizzare la stringa mediante pc.

  7. (Attenzione: prima di eseguire questo esercizio dare il comando di shell (bash)     ulimit -v 100000       per mettere dei limiti ragionevoli ai propri processi ed evitare blocchi del sistema). La function malloc(size) il cui prototipo, contenuto nel file di headers  <stdlib.h> (da mettere quindi tra gli include) alloca (se possibile) size unita' di memoria di dimensione pari a  un char  (quindi size byte sul nostro sistema). Scrivere un programma che allochi un numero di bytes letto da standard input e verifichi che l' allocazione sia riuscita (se il sistema non risce ad allocare memoria, il puntatore risultante assume il valore NULL). Cercare di determinare per tentativi la massima memoria allocabile. Verificare cosa cambia se si utilizza calloc(size,1)  invece di malloc(size).



I seguenti esercizi sono suggeriti come ulteriore approfondimento degli argomenti.
  1. Modificare opportunamente il programma usato per ordinare una sequenza di numeri (esercizio n.3 ) in modo da poterlo impiegare sotto forma di function per ordinare sequenze di stringhe secondo l' ordine lessicografico (quello del dizionario).Suggerimento: per il confronto tra stringhe e per lo scambio, utilizzare le function di libreria strcmp e strcpy la cui modalita' di utilizzo e' reperibile mediante il comando man.

  2. Cosa c' è di sbagliato nel seguente programma ? Perché ?
    #include 

    int main()
    {
    char *p="questo e' un puntatore",a[]="questo e' un array";
    p[0]='Q';
    a[0]='Q';
    printf("%s \n",p);
    printf("%s \n",a);
    p=a;
    printf("%s \n",p);
    return 0;
    }