Strumenti Utente

Strumenti Sito


informatica:sol:laboratorio15:esercitazionia:esercitazione1

Questa è una vecchia versione del documento!


Esercitazione 1

Esercizi proposti su: puntatori, stringhe, puntatori a funzione, argc-argv, allocazione/deallocazione dinamica, …. Cercare di completare tutti gli esercizi durante le ore di laboratorio e nel caso come homework.

In caso di difficoltà su aspetti del C, discuterne con il docente.

Esercizio 1 (sul debugging con gdb)

Usare il debugger gdb per trovare gli errori in questo programma C (ce ne sono almeno 2):

#include <stdlib.h>
#include <stdio.h>
#define N 32
 
int main() {
    int *A = malloc(N);
    int i=0;
    while(++i<N) {
	A[i] = !(i%2);
    } 
    printf("stampa ...\n"); 
    for(int i=0;i<N;++i) 
	printf("%d ", A[i]);
    printf("\n");
    printf("exiting ...\n");
    free(A);
    return 0; 
}

Copiare il codice precedente in 'debugging.c'. Compilare il codice con l'opzione “-g”, ad esempio:

gcc -std=c99 -Wall -Werror -g debugging.c -o debugging

quindi lanciare l'eseguibile e verificare quali errori produce, poi usando il debugger:

$ gdb ./debugging

è possibile fermare il programma durante la sua esecuzione (ad esempio mettendo un breakpoint all'inizio del 'while' – (gdb) b 8 ), ispezionare le variabili (ad esempio '(gdb) p A[1]', '(gdb) next', etc..

Esercizio 2

Scrivere una funzione “swapPtr” che swappa due puntatori qualsiasi:

void swapPtr(void **ptr1, void **ptr2);

Testare la funzione con un semplice programma che stampi il vaore puntato prima e dopo lo swap.

Esercizio 3

Data una stringa con caratteri minuscoli e maiuscoli, trasformarla in una stringa con tutti i caratteri maiuscoli. NOTE: è possibile utilizzare le funzioni di libreria 'islower' e 'toupper' definite in ctype.h (vedere man 3 islower). Ad esempio usare la stringa:

char str[]="Questa e' una Stringa non tanto Lunga che CONtiene 123 !";

il risultato deve essere:

printf("%s\n", str);
$ QUESTA E' UNA STRINGA NON TANTO LUNGA CHE CONTIENE 123 !

Una variante di questo esercizio è quello di trasformare i caratteri maiuscoli in minuscoli e viceversa.

Esercizio 4

Scrivere un programma che dato un vettore di un certo numero di elementi esegua la somma o il prodotto di tutti gli elementi del vettore a seconda del parametro passato come input al programma. Se l'argomento è '-s' dovrà essere effettuata la somma degli elementi, se l'argomento è '-m' dovrà essere effettuato il prodotto. Scrivere il programma in modo generico utilizzando un puntatore a funzione. Usare il seguente tipo puntatore a funzione:

// tipo puntatore a funzione, prima argomento il puntatore al vettore, secondo argomento la size del vettore
typedef long (*function_t)(long *, size_t); 

Esercizio 5

Scrivere una funzione 'mystrcat' con la seguente segnatura:

const char *mystrcat(char *prima, ...);

che prenda un numero di stringhe variabili e che concateni tutte le stringhe alla 'prima' con lo stesso comportamento della funzione di libreria 'strcat' (man 3 strcat). Utilizzare il seguente main:

int main() {
  char prima[1024] = "prima";
  printf("%s\n", mystrcat(prima, "seconda", "terza lunga", "quarta", "quinta", "ultima!", NULL));
 
  return 0;
}

NOTA: A che cosa serve l'ultimo argomento 'NULL' ?

Esercizio 6

Scrivere un programma che dato un intero A a 32bit (usare i tipi int16_t, int32_t definiti in #include<stdint.h>) calcoli lo 'xor bit a bit' dei 2 byte piu' significativi (quelli di sinistra) con i 2 byte meno significativi. L'operatore di xor bit a bit è '^' (es. 0101 ^ 1100 = 1001). Dato A1 in formato network-byte-order di A (cioè formato big-endian, utilizzare htonl – vedi man 3 htonl), riordinare i byte di A1 in host-byte-order (cioè formato little-endian per sistemi Intel/AMD based). Vedere man 3 byteorder. Dato il numero in formato esadecimale 0x1234567:

  high <------------------- low
 ---------------------------------
|  0x01  |  0x23  |  0x45 |  0x67 |    little-endian  
 ---------------------------------
 ---------------------------------
|  0x67  |  0x45  |  0x23 |  0x01 |    big-endian
 ---------------------------------

Esercizio 7

Scrivere un programma che, dato un array di N elementi interi, costruisca un albero binario di ricerca (cioè per ogni nodo dell'albero, l'elemento del nodo è maggiore di tutti gli elementi del sottoalbero di sinistra e minore o uguale di tutti gli elementi del sottoalbero di destra). Implementare le seguenti funzioni:

struct node_t *buildTree(long elem, struct node_t *t); // costruisce l'albero e restituisce il nodo radice
long getMin(struct node_t *root);       // restituisce il valore minimo
long getMax(struct node_t *root);       // restituisce il valore massimo
void printInOrder(struct node_t *root); // stampa gli elementi in modo ordinato
void deleteTree(struct node_t *root);   // cancella tutti i nodi dell'albero

Definire il tipo 'struct node_t' opportunamente. Implementare tutte le funzioni usando la ricorsione.

Esercizio 8

Scrivere un programma (il cui eseguibile chiameremo 'stringsort') che prende come argumenti da linea di comando un certo numero di stringhe (un numero arbitrario) e le ordina alfanumericamente utilizzando la chiamata di libreria 'qsort' (man 3 qsort). Testare il programma come segue (vedere i manuali dei comandi 'cat' e 'xargs'):
1. preparare un file con il comando cat nel modo seguente:

$> cat << FINE > filediinput.txt
> questa è la prima riga 
> Questa è la seconda più lunga
> AAA questa è quella che deve finire per prima
> jjj questa è prima della prima riga
> zzz questa è ultima....
> FINE

2. lanciare il comando (il simbolo '|' mette in pipeline l'output del comando che precede con l'input del comando che segue) :

$> cat filediinput.txt | xargs -I {} echo \"{}\" | xargs ./stringsort

3. verificare che l'output sia correttamente ordinato.

Che cosa fa il comando 'xargs' come secondo elemento della pipeline ?

Esercizio 9

Non utilizzando la funzioni di libreria 'getopt' (man 3 getopt), scrivere un programma che effettua il parsing della linea di comando (argv) riconoscendo le seguenti opzioni:

-n <numero> -s <stringa> -m <altro-numero> -h. 

Il programma dovrà stampare le opzioni riconosciute con il relativo argomento. L'opzione -h non ha argomento e corrisponde al messaggio di help (program usage). Se e' presente l'opzione -h dovra' essere stampato solo il messaggio di usage cioè:

nome-programma -n <numero> -s <stringa> -m <numero> -h

Se ci sono opzioni non riconosciute queste dovranno essere stampate a video con il messaggio “opzione X non riconosciuta”. Testare il programma con i seguenti casi (supponiamo che l'eseguibile si chiami cmdlineparsing):

cmdlineparsing -n 10 -m 11 -s 'ciao mondo' 
cmdlineparsing -n 10 -h     // deve stampare solo il messaggio di usage 
cmdlineparsing -n 10 -k 12  // k e' una opzione non riconosciuta
cmdlineparsing ----n 10 -s-s 'ciao mondo'  // deve stampare -n: 10 e -s: -s
cmdlineparsing -n10 -m11 -s'ciao mondo'  // deve stampare gli argomenti come nel primo caso
cmdlineparsing -n -m 11   // deve stampare un messaggio di errore per -n
informatica/sol/laboratorio15/esercitazionia/esercitazione1.1424762787.txt.gz · Ultima modifica: 24/02/2015 alle 07:26 (10 anni fa) da Massimo Torquati

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki