Strumenti Utente

Strumenti Sito


informatica:sol:laboratorio17:esercitazionib:esercitazione1

Esercitazione 1

Illustrazione dei principali comandi emacs. Cenni a vi. Illustrazione dell'uso del debugger gdb su un semplice programma. Esercizio sul debugger gdb.

Illustrazione uso gdb

Vediamo come si usa il debugger gdb usando il codice usodebug.c contenuto in questo tarball. I comandi principali di gdb da ricordare sono:
- run ( r ), break <file:linea> ( b ), step ( s ), next ( n ), print <variabile> ( p ), set args <argomenti>, backtrace ( bt ), finish, continue ( c ), quit ( q ).

Esercizio 1

Usare il debugger gdb (o per chi vuole la sua interfaccia grafica ddd ) per trovare gli errori in findbug.c (nello stesso tarball precedente) e correggerli.

Compilare il codice nel seguente modo (ATTENZIONE all'opzione-g che abilita le informazioni di debugging):

gcc -std=c99 -g findbug.c -o findbug

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

$ gdb ./findbug

inserire un breakpoint nel main (b main) ed eseguire il programma (r) step-by-step (n o s). Identificato l'errore e modificare il programma opportunamente.

Trovare il bug nel file findbug2.c (nello stesso tarball)

Esercizio 2

Scrivere un programma C che prende in ingresso 2 interi e 2 stringhe. Stampare a video tutta la lista degli argomenti (argv) e tutte le variabili d'ambiente del programma (envp). Ricordare che una possibile segnatura della funzione main e':

int main(int argc, char *argv[], char *envp[]);

Esercizio 3

Scrivere una funzione 'mystrcat' con la seguente segnatura:

const char *mystrcat(char* buffer, int buffer_size, char *prima, ...);

La funzione prende un buffer, la lunghezza del buffer ed almeno uno stringa. Le stringhe possono essere un numero variabile (>1). La funzione concatena tutte le stringhe nel 'buffer' e ritorna il buffer stesso. ATTENZIONE alla gestione della memoria!

Utilizzare il seguente main:

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
#define RIALLOCA(buf, newsize) \
    <inserire il codice per riallocare buf> 
 
char* mystrcat(char *buf, size_t sz, char *first, ...) {
  <implementare il codice>
}  
 
int main() {
  char *buffer=NULL;
  RIALLOCA(buffer, 16);  // macro che effettua l'allocazione
  buffer[0]='\0';
  buffer = mystrcat(buffer, 16, "prima stringa", "seconda", "terza molto molto molto lunga", "quarta", "quinta lunga", "ultima!",NULL);
  printf("%s\n", buffer);     
  free(buffer);
  return 0;
}

NOTA: Che cosa puo' succedere al programma se invece di

 printf("%s\n", buffer);

si fosse scritto:

 
 printf("%s\n", mystrcat(buffer, 16, "prima stringa", "seconda", "terza molto molto molto lunga", "quarta", "quinta lunga", "ultima!",NULL));

Per chi ha bisogno di prendere dimestichezza con il C (homeworks)

Esercizio 4

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 5

Non utilizzando la funzioni di libreria 'getopt' (man 3 getopt), scrivere un programma che effettua il parsing della linea di comando e che riconosce 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”. Per convertire le stringhe in interi usare la funzione di libreria atoi (vedere man 3 atoi) o meglio ancora la funzione strtol (vedere man strtol). 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 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/laboratorio17/esercitazionib/esercitazione1.txt · Ultima modifica: 22/02/2017 alle 11:16 (7 anni fa) da Massimo Torquati