http://www.cplusplus.com/reference/
2 - FUNZIONI
versione 19/12/2012
 
ESERCIZIO
 
Costruire un programma che generi una sequenza di numeri casuali (da 2 a 100) ed evidenzi tra questi quelli che sono primi. Il test sui numeri deve essere svolto da una funzione.

 
SOLUZIONE:
/**************************************************************************
 * Nome: lab1-primi.c                                                     *
 * Autore: Alessandro Saetti                                              *
 * Data: 30/3/11                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#define DIM 10
/* FUNZIONE
 * Nome: primo
 * Scopo: Determina se un dato intero e' primo
 * Input: int n: l'intero che di intende esaminare
 * Output: true se n e' primo, false altrimenti
 */
bool primo(int n) 
{
    for (int i=2 ; i < n ; i++ ) 
       if (n%i==0) return false;    
    return true;
}
/*
 * Nome: main
 * Scopo: Inizializza un vettore di DIM variabili intere con dati interi
 *        pseudo-casuali compresi tra 2 e 100. Visualizza i dati interi primi
 *        contenuti nel vettore in ordine contrario.
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    int x, primi[DIM]={0}, n = 0, i;
    // INIZIALIZZAZIONE + ALGORITMO
    printf("Numeri generati:\n");
    for ( i=0; i < DIM; i++ ) 
    {
        x = rand() % 99 + 2;
        printf("%5d", x);
        if (primo(x))
           primi[n++] = x;
    }
    // OUTPUT
    printf("\nI numeri primi sono:\n");
    for (i = n - 1; i >= 0; i--) 
        printf("%5d", primi[i]); 
    printf("\n\n");
    
    // metto in stop il programma prima della sua chiusura
    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire un programma che legge la sequenza di numeri interi posti sulla linea di comando e mostri a video, per ogni numero pari della sequenza, due numeri primi la cui somma coincide con il numero analizzato.
PS: L'esercizio prende spunto dalla congettura di Goldbach che è uno dei più vecchi problemi irrisolti nella teoria dei numeri. Essa afferma che ogni numero pari >= 2 può essere scritto come somma di due numeri primi (che possono essere anche uguali).

 
SOLUZIONE:
NOTE:

I parametri di linea possono essere passati utilizzando l'apposito menu




int atoi ( const char * str ); => Analizza il parametro str, che è di tipo stringa, e lo interpreta come numero intero. Tale valore viene poi restituito come int dalla funzione stessa. Se non è possibile effettuare una conversione allora la funzione restituisce 0. Non ci sono specifiche standard sul comportamento della funzione quando il valore intero convertito non rientra nel range del tipo int. La funzione strtol rappresenta una più valida cross-platform alternativa quando questo è possibile. Richiede <stdlib.h>.
/**************************************************************************
 * Nome: lab2-goldbach.c                                                  *
 * Autore: Alessandro Saetti                                              *
 * Data: 30/3/11                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#define DIM 10
/* FUNZIONE
 * Nome: primo
 * Scopo: Determina se un dato intero e' primo
 * Input: int n: l'intero che di intende esaminare
 * Output: true se n e' primo, false altrimenti
 */
bool primo(int n) 
{
    for (int i=2 ; i < n ; i++ ) 
       if (n%i==0)
          return false;    
    return true;
}
/* FUNZIONE
 * Nome: primi
 * Scopo: Calcola una coppia di numeri primi la cui somma e' pari ad un dato intero n
 * Input: int n: l'intero che di intende esaminare
 *        int *p1: un puntatore al primo numero primo calcolato
 *        int *p2: un puntatore al secondo numero primo calcolato
 * Output: -- poichè si ritiene vera la congettura di Goldbach non occorre restituire TRUE o FALSE.
 */
void ScomponiSommaPrimi(int n, int *p1, int *p2) 
{
    int i;
    for (i = 2; i < n; i++) 
    {
        if ( primo(i) && primo(n-i) ) 
        {
           *p1 = i;
           *p2 = n - i;
           return;     
        }
    }
}
/*
 * Nome: main
 * Scopo: Inizializza una matrice di DIM righe e 2 colonne con i numeri primi
 *        la cui somma e' pari ai numeri pari specificati tramite la linea di
 *        comando
 * Input: int argc: il numero di argomenti presenti sulla linea di comando + 1
 *        char *argv: le stringhe corrispondenti agli argomenti specificati
 * Uso:   comando n1 n2 ... ni   
 * Output: 0 se il programma termina correttamente
 */
int main(int argc, char *argv[]) 
{
  int i, x, m[DIM][2], n = 0;
  
  // Scorro gli argomenti sulla linea di comando
  for (i = 1; i < argc; i++) 
  {
      x=atoi(argv[i]);
      // Se x è pari ricerco i due numeri primi la cui somma 
      // restituisce x.
      if (x % 2 == 0) 
      {
         ScomponiSommaPrimi(x, &m[n][0], &m[n][1]);
         n++;
      }   
  } 
  for (i = 0; i < n; i++) 
      printf("%d=%d+%d\n", m[i][0]+m[i][1], m[i][0], m[i][1]);
  
  system("pause");
  return 0;
}

ESERCIZIO
 
Costruire un programma che genera una sequenza di frazioni (memorizzate in una array bidimensionale dove gli elementi sulla colonna 0 rappresentano il numeratore mentre quelli sulla colonna 1 il denominatore delle frazioni) e visualizza e stampa a video le frazioni ridotte ai minimi termini.

 
SOLUZIONE:
NOTE:
int rand() => Restituisce un numero intero casuale tra 0 e RAND_MAX. Il valore RAND_MAX dipende dalla libreria. Vale almeno 32767. Richiede <stdlib.h>.

void srand ( unsigned int seed ); => Inizializza il generatore di numeri casuali. Richiede <stdlib.h>. Usando come argomento time(NULL) facciamo variare il seme (seed) in funzione del tempo e di conseguenza anche le sequenze generate.

time_t time ( time_t * timer ); => Restituisce l'orario corrente come oggetto time_t e lo registra anche nel parametro *timer (se questo non è posto a NULL!). Il tipo time_t restituito dalla funzione time() è un numero intero che contiene il numero di secondi trascorsi dalle 00:00 del 1 gennaio 1970 (corrisponde al timestamp di unix). In questo modo la rappresentazione del tempo consente di effettuare delle operazioni aritmentiche. Richiede <time.h>.
/**************************************************************************
 * Nome: lab3-mcd.c                                                       *
 * Autore: Alessandro Saetti                                              *
 * Data: 30/3/11                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h>   // Richiesta da time(NULL);
#define DIM 10
/* FUNZIONE
 * Nome: MCD
 * Scopo: Calcola il massimo comune divisore di 2 dati interi
 * Input: int n1, n2: i due interi di cui si intende calcolare il MCD
 * Output: il MCD calcolato
 */
int MCD(int n1, int n2) 
{
    int i, min, MCD;
    min=(n1 < n2 ? n1 : n2);
    for (MCD=min ; ((n1%MCD)+(n2%MCD))>0 ; MCD--);
    return MCD;
}
/*
 * Nome: main
 *        Supponendo che le colonne della matrice rappresentino il numeratore
 *        ed il denominatore di frazioni, stampa a video le frazioni ridotte
 *        ai minimi termini
 * Input: -   
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    int m[DIM][2], i, d;
    // INIZIALIZZAZIONE - INPUT 
    //   Inizializza la prima colonna di una matrice di DIM righe con dati
    //   pseudo-casuali interi compresi tra 10 e 100 e la seconda colonna
    //   con dati pseudo-casuali compresi tra la prima colonna e 100.
    srand(time(NULL));
    for (i = 0; i < DIM; i++) 
    {
      m[i][0] = rand() % 91 + 10;
      m[i][1] = rand() % (100 - m[i][0] + 1) + m[i][0];
    } 
    for (i = 0; i < DIM; i++) 
    {
        d=MCD(m[i][0],m[i][1]);
        printf("%d^ Frazione ridotta di %d/%d => %d/%d\n",i+1, 
                    m[i][0], m[i][1], m[i][0]/d, m[i][1]/d);
    }
    
    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire una funzione che inizializza gli elementi di un vettore (passato come parametro) con una sequenza di numeri casuali. I valori min e max generabili devono essere parametri della nostra funzione. Ogni vettore è una riga di una matrice NxM. Costruire poi la funzione che stampa il contenuto di un vettore (la dimensione deve essere uno dei parametri). Infine costruire la funzione che, dato un vettore, restituisca la somma degli elementi pari. Sfruttando le precedenti funzioni costruire il programma che inizializza una matrice NxM, la stampa ed infine mostra per ogni riga la somma dei suo elementi pari.

 
SOLUZIONE:
NOTE:
int rand() => Restituisce un numero intero casuale tra 0 e RAND_MAX. Il valore RAND_MAX dipende dalla libreria. Vale almeno 32767. Richiede <stdlib.h>.

void srand ( unsigned int seed ); => Inizializza il generatore di numeri casuali. Richiede <stdlib.h>. Usando come argomento time(NULL) facciamo variare il seme (seed) in funzione del tempo e di conseguenza anche le sequenze generate.

time_t time ( time_t * timer ); => Restituisce l'orario corrente come oggetto time_t e lo registra anche nel parametro *timer (se questo non è posto a NULL!). Il tipo time_t restituito dalla funzione time() è un numero intero che contiene il numero di secondi trascorsi dalle 00:00 del 1 gennaio 1970 (corrisponde al timestamp di unix). In questo modo la rappresentazione del tempo consente di effettuare delle operazioni aritmentiche. Richiede <time.h>.
/**************************************************************************
 * Nome: lab1-somma_pari.c                                                 *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h>   // Richiesta da time(NULL);
#define N 10
#define M 5
/*
 * Nome: inizializza
 * Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
 * Input: int v[]: vettore dove memorizzo i valori generati
 *        int n  : dimensione del vettore
 *        int min: minimo numero pseudo-casuale generabile
 *        int max: massimo numero pseudo-casuale generabile
 * Output: -
 */
void Inizializza(int v[], int n, int min, int max) 
{
    for (int c = 0; c < n; c++) 
        v[c] = rand() % (max - min + 1) + min;
}
/*
 * Nome: stampa
 * Scopo: Stampa un vettore di n interi 
 * Input: int v[]: vettore
 *        int n: dimensione del vettore
 * Output: -
 */
void Stampa(const int v[], int n) 
{
    for (int c = 0; c < n; c++) 
        printf("%4d", v[c]);
    printf("\n");
}
/*
 * Nome: somma_pari
 * Scopo: Somma i numeri pari presenti in un vettore v di lunghezza n
 * Input: const int v[]: vettore
 *        int n: dimensione del vettore
 * Output: somma dei numeri pari presenti in v
 */
int somma_pari(const int v[], int n) 
{
    int c, somma;
    for (somma=0, c = 0; c < n; c++)
        if (v[c] % 2 == 0) 
           somma += v[c];
    return somma;
}
/*
 * Nome: main
 * Scopo: Stampa le somme dei numeri pari sulle righe di una matrice
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    int m[N][M], s[N], r;
    // INPUT - Inizializzazione
    srand(time(NULL));
    for (r = 0; r < N ; r++) 
        Inizializza(m[r],M, 1, 9);
    // ALGORITMO
    for (r=0; r < N; r++) 
        s[r] = somma_pari(m[r],M);
    // OUTPUT
    printf("Matrice iniziale:\n\n");
    for (r = 0; r < N ; r++) 
        Stampa(m[r],M);
    printf("\nVettore Somma Pari:\n\n");
    Stampa(s,N);

    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire una funzione che, dato un vettore (riga della matrice) calcoli la somma degli elementi pari e dispari. Sfruttando questa funzione e riutilizzando le funzioni Inizializza() e Stampa() dell'esercizio 2.5 costruire il programma che inizializza una matrice NxM, la stampa ed infine mostra per ogni riga la somma dei suoi elementi pari e dispari.

 
SOLUZIONE:
/**************************************************************************
 * Nome: lab2-sommapari_dispari.c                                         *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h>   // Richiesta da time(NULL);
#define N 10
#define M 5
/*
 * Nome: inizializza
 * Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
 * Input: int v[]: vettore dove memorizzo i valori generati
 *        int n  : dimensione del vettore
 *        int min: minimo numero pseudo-casuale generabile
 *        int max: massimo numero pseudo-casuale generabile
 * Output: -
 */
void Inizializza(int v[], int n, int min, int max) 
{
    for (int c = 0; c < n; c++) 
        v[c] = rand() % (max - min + 1) + min;
}
/*
 * Nome: stampa
 * Scopo: Stampa un vettore di n interi 
 * Input: int v[]: vettore
 *        int n: dimensione del vettore
 * Output: -
 */
void Stampa(const int v[], int n) 
{
    for (int c = 0; c < n; c++) 
        printf("%4d", v[c]);
    printf("\n");
}
/*
 * Nome: somme
 * Scopo: Calcola la somma dei numeri pari e dispari presenti in un vettore v di lunghezza n
 * Input: const int v[]: vettore
 *        int n: dimensione del vettore
 *        int *somma_pari: puntatore alla variabile in cui memorizzo la somma dei numeri pari
 *        int *somma_dispari: puntatore alla variabile in cui memorizzo la somma dei numeri dispari
 * Output: -
 */
void somme(const int v[], int n, int *somma_pari, int *somma_dispari) 
{
    for (int c = 0; c < n; c++)
        if (v[c] %2 == 0) 
           *somma_pari += v[c];
        else 
           *somma_dispari += v[c];
}
/*
 * Nome: main
 * Scopo: Stampa le somme dei numeri pari e dispari sulle righe di una matrice
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    int m[N][M], p[N]={0}, d[N]={0}, r;
 
    // INPUT - Inizializzazione
    srand(time(NULL));
    for (r = 0; r < N ; r++) 
        Inizializza(m[r],M, 1, 9);
    // ALGORITMO
    for (r=0; r < N; r++) 
        somme(m[r],M, &p[r], &d[r]);
    // OUTPUT
    printf("Matrice iniziale:\n\n");
    for (r = 0; r < N ; r++) 
        Stampa(m[r],M);
    printf("\nVettore Somma Pari:\n\n");
    Stampa(p,N);
    printf("\nVettore Somma Dispari:\n\n");
    Stampa(d,N);

    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire una funzione che legge una sequenza di parole e segnala quelle palindrome. La sequenza è terminata quando l'utente scrive la stringa "0" oppure se sono state digitate NWords parole.

 
SOLUZIONE:
OSSERVAZIONI:
1) Per le prove usa il seguente elenco di parole (cut & paste).

onorarono
argento
ottetto
radar
Anna
aveva
oro
ingegni
ottavo
vivi
0
2) La maschera di formato "%-30s" nel printf permette di scrivere la stringa in uno spazio fisso di 30 caratteri allineandolo a sinistra.
3) La maschera di formato "%30s" nello scanf permette di leggere una sequenza di caratteri fino all'inserimento di un simbolo di separazione (esempio spazio, tab, newline etc. : vedi funzione isspace()) oppure quando sono arrivato al 30 carattere.
4) Quando passo ad una procedura una matrice posso omettere la 1° dimensione per cui posso scrivere: M[][100] oppure (*M)[100].
/**************************************************************************
 * Nome: lab4-palindroma.c                                                *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <string.h>   // Richiesta da strlen;
#define NWords 20
#define LStr 30
/*
 * Nome: palindroma
 * Scopo: Determina se una parola e' palindroma
 * Input: char *parola: la parola da verificare
 * Output: true se la parola e' palindroma; false altrimenti
 */
bool palindroma (char *parola) 
{
    int i, j;
    for (i = 0, j = strlen(parola) - 1; i < j ; i++, j--) 
        if (parola[i]!=parola[j]) return false;
    return true;
}
/*
 * Nome: acquisisci
 * Scopo: Acquisisce parole da tastiera finchè non digito "0" fino ad un 
 *        massimo di NWords
 * Input: char (*m)[DIM]: la matrice nella quale salvare le parole
 * Output: il numero di parole acquisite
 */
int Acquisisci (char m[][LStr]) 
{
	// Potevo anche scrivere:
	// int Acquisisci (char (*m)[LStr]) 
	// Le dimensioni successive alla prima sono obbligatorie
    int n = 0;
    do 
    {
       printf("Digita la %2d^ parola: ",n+1);
       // Specifico il nr. massimo di caratteri da òeggere
       scanf("%30s", m[n]);
       if (strcmp(m[n], "0") != 0) 
          n++;
    } while(n < NWords && strcmp(m[n], "0") != 0 );    
    return n;
}
/*
 * Nome: main
 * Scopo: Trova le parole palindrome in un gruppo di parola 
 *        acquisite da tastiera
 * Input: -
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    char Vocaboli[NWords][LStr];
    int i, n = 0;
    // INPUT
    n = Acquisisci(Vocaboli);
    // ALGORITMO+OUTPUT
    for (i = 0; i < n; i++)
       if (palindroma(Vocaboli[i])) 
          printf("%-30s: palindroma\n", Vocaboli[i]);
       else
          printf("%-30s: //\n", Vocaboli[i]);
    printf("\n");
    
    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire un programma ...

 
SOLUZIONE:
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h>   // Richiesta da time(NULL);

ESERCIZIO
 
Costruire una funzione che inizializza gli elementi di un vettore (passato come parametro) con una sequenza di numeri casuali. I valori min e max generabili devono essere parametri della nostra funzione. Ogni vettore è una riga di una matrice NxM (con M pari). Costruire poi la funzione che stampa il contenuto di un vettore (la dimensione deve essere uno dei parametri). Infine costruire la funzione che, dato un vettore, restituisca il minimo comune multiplo tra gli elementi del vettore. Sfruttando queste funzioni costruire il programma che inizializza una matrice NxM, la stampa ed infine mostra i minimi comune multipli dei numeri contenuti in ogni mezza riga (lunga quindi M/2) della matrice originale.

 
SOLUZIONE:
OSSERVAZIONI:
1) La notazione &m[r][M/2] fornisce il puntatore all'elemento a metà sulla riga r.

/**************************************************************************
 * Nome: casa1-mcm.c                                                      *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h>   // Richiesta da time(NULL);
#define N 10 // Le dimensioni devono essere pari.
#define M 10
/*
 * Nome: mcm
 * Scopo: Calcola il minimo comune multiplo tra numeri presenti in un vettore v di lunghezza n
 * Input: const int v[]: vettore
 *        int n: dimensione del vettore
 * Output: Il minimo comune multiplo
 */
int Calcola_mcm(const int v[], int n) 
{
    int i, t_mcm, prodotto, max, mcm;
    // Effettuo la produttoria di tutti gli elementi 
    // e determino il valore massimo
    for (prodotto=1, i=0 , max=v[0] ; i < n ; i++) 
    {
        prodotto *= v[i];
        if (max < v[i]) 
           max = v[i];
    }
    // Il mcm è un numero compreso tra la produttoria dei numeri 
    // e il max valore
    for (t_mcm = prodotto; t_mcm >= max; t_mcm--)
    {
        for (i = 0 ; i < n ; i++)
            if (t_mcm % v[i] != 0) break;
        // se i == n ==> che tutti gli elementi del vettore dividono il
        // t_mcm per cui è sicuramente un loro multiplo 
        if (i == n) mcm = t_mcm;  
    }
    return mcm;
}
/*
 * Nome: inizializza
 * Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
 * Input: int v[]: vettore dove memorizzo i valori generati
 *        int n  : dimensione del vettore
 *        int min: minimo numero pseudo-casuale generabile
 *        int max: massimo numero pseudo-casuale generabile
 * Output: -
 */
void Inizializza(int v[], int n, int min, int max) 
{
    for (int c = 0; c < n; c++) 
        v[c] = rand() % (max - min + 1) + min;
}
/*
 * Nome: stampa
 * Scopo: Stampa un vettore di n interi 
 * Input: int v[]: vettore
 *        int n: dimensione del vettore
 * Output: -
 */
void Stampa(const int v[], int n) 
{
    for (int c = 0; c < n; c++) 
        printf("%4d", v[c]);
    printf("\n");
}

/*
 * Nome: main
 * Scopo: Stampa i minimi comuni multipli tra i numeri nella prima e 
 *        seconda meta' di ciascuna riga
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    int m[N][M], m1[N]={0}, m2[N]={0}, r;

    // INPUT - Inizializzazione
    srand(time(NULL));
    for (r = 0; r < N ; r++) 
        Inizializza(m[r],M, 1, 9);
    // ALGORITMO
    for (r=0; r < N; r++)
    {
        m1[r] = Calcola_mcm(m[r], M/2);
        m2[r] = Calcola_mcm(&m[r][M/2], M/2);
    }

    // OUTPUT
    printf("Matrice iniziale:\n\n");
    for (r = 0; r < N ; r++) 
        Stampa(m[r],M);
    printf("\nVettore mcm 1^ meta':\n\n");
    Stampa(m1,N);
    printf("\nVettore mcm 2^ meta':\n\n");
    Stampa(m2,N);

    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire una funzione che inizializza gli elementi di un vettore (passato come parametro) con una sequenza di numeri casuali. I valori min e max generabili devono essere parametri della nostra funzione. Ogni vettore è una riga di una matrice NxM (con M pari). Costruire poi la funzione che stampa il contenuto di un vettore (la dimensione deve essere uno dei parametri). Infine costruire la funzione che, dato un vettore, restituisca il numero di valori primi in esso contenuti. Sfruttando queste funzioni costruire il programma che inizializza una matrice NxM, la stampa ed infine mostra la riga contenente il numero maggiore di numeri primi

 
SOLUZIONE:
/**************************************************************************
 * Nome: casa2-primi.c                                                    *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <time.h>   // Richiesta da time(NULL);
#define N 10
#define M 10
/*
 * Nome: Conta_I_Primi
 * Scopo: Calcola la quantita' di numeri primi in un vettore v di lunghezza n
 * Input: const int v[]: vettore
 *        int n: dimensione del vettore
 * Output: La quantita' di numeri primi nel vettore
 */
int Conta_I_Primi(const int v[], int n) 
{
    int i, j, div, n_primi = 0;
    // Scorro ogni elemento dell'array
    for (i = 0; i < n; i++) 
    {
    	for (j = 2; j < v[i]; j++) 
    	   if (v[i] % j == 0) 
              break; 
    	if (j >= v[i]) 
           n_primi++;
    }
    return n_primi;
}

/*
 * Nome: inizializza
 * Scopo: Inizializza un vettore di n interi con numeri casuali compresi tra 1 e 9
 * Input: int v[]: vettore dove memorizzo i valori generati
 *        int n  : dimensione del vettore
 *        int min: minimo numero pseudo-casuale generabile
 *        int max: massimo numero pseudo-casuale generabile
 * Output: -
 */
void Inizializza(int v[], int n, int min, int max) 
{
    for (int c = 0; c < n; c++) 
        v[c] = rand() % (max - min + 1) + min;
}
/*
 * Nome: stampa
 * Scopo: Stampa un vettore di n interi 
 * Input: int v[]: vettore
 *        int n: dimensione del vettore
 * Output: -
 */
void Stampa(const int v[], int n) 
{
    for (int c = 0; c < n; c++) 
        printf("%4d", v[c]);
    printf("\n");
}
/*
 * Nome: main
 * Scopo: Stampa la riga della matrice con piu' numeri primi
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main()
{
    int m[N][M], r, best_r, max, n_primi;
    // INPUT - Inizializzazione
    srand(time(NULL));
    for (r = 0; r < N ; r++) 
        Inizializza(m[r],M, 1,9);
    // ALGORITMO
    for (max=0, best_r=0, r=0; r < N; r++) 
    {
        n_primi = Conta_I_Primi(m[r], M);
        if (n_primi > max) 
        {
           max = n_primi;
           best_r = r;
        }
    }
    // OUTPUT
    printf("Matrice iniziale:\n\n");
    for (r = 0; r < N ; r++) 
        Stampa(m[r],M);
    printf("\nLa %d riga e' quella con piu' numeri primi (%d):\n\n",best_r+1, max);
    Stampa(m[best_r],M);

    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire una funzione che codifica una stringa utilizzando il cifrario di Cesare. Questo cifrario codifica una frase sostituendo a ciascuna lettere la lettera n posizioni in avanti nell'alfabeto.



E' uno dei più antichi algoritmi crittografici di cui si abbia traccia storica. E' un cifrario a sostituzione monoalfabetica in cui ogni lettera del testo in chiaro è sostituita nel testo cifrato dalla lettera che si trova un certo numero di posizioni dopo nell'alfabeto. Questo tipo di cifrario è detto anche cifrario a sostituzione o cifrario a scorrimento a causa del loro modo di operare.

 
SOLUZIONE:
NOTE:

I parametri di linea possono essere passati utilizzando l'apposito menu




char * strncpy ( char * Dest, const char * Orig, size_t Num ); => Il parametro Dest è un puntatore ad un array di char dove verrà copiata la stringa indicata nel parametro Orig. Num indica il massimo numero di caratteri da copiare. La copia si interrompe appena viene incontrato il carattere '0' nella stringa Orig. Num è un unsigned int. Richiede <string.h>.

int isalpha ( int c ); => Testa se il carattere cè una lettera alfabetica (minuscola o maiuscola). Restituisce un valore diverso da 0 (true) se c è una lettera alfabetica, zero (false) altrimenti. Richiede <ctype.h>.
/**************************************************************************
 * Nome: lab3-cifrare.c                                                   *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <string.h> // Richiesta da strncpy(char *d, char *o,int n)
// Se uso isalpha()
// #include <cctype>   // Richiesta da isalpha(char)
#define NChar 50
/*
 * Nome: CodificaDiCesare
 * Scopo: Cifra una frase sostituendo a ciascuna lettere la lettera n 
 *        posizioni in avanti nell'alfabeto
 * Input: char frase[]: vettore contenente la frase da cifrare
 *        int n: spostando nell'alfabeto
 * Output: -
 */
void CodificaDiCesare(char frase[], int nc, int chiave)
{
    // Al posto di if (frase[i] <= 'z' && frase[i]>='a')
    // potevo usare: if (isalpha(frase[i]))
    // In questo modo posso includere nella cifratura le maiuscole
    // Questa funzione richiede <cctype.h>
    for(int i = 0; i < nc && frase[i]!='\0'; i++)
        if (frase[i] <= 'z' && frase[i]>='a')
           frase[i]='a'+(frase[i]-'a'+chiave) % 26; 
}
/* Alternativamente:
void cifrare(char frase[], int nc, int chiave)
{
    int i;

    for(i = 0; i < nc && frase[i]!='\0'; i++) 
    {
        if (frase[i] <= 'z' && frase[i]>='a') 
        {
           if (frase[i] + chiave <= 'z' && frase[i] + chiave >= 'a')
             frase[i]=frase[i]+chiave;
           else if (frase[i] + chiave > 'z')
             frase[i]=(frase[i]+num)-'z'+'a'-1;
           else if (frase[i] + chiave < 'a')
             frase[i]=(frase[i]+chiave)-'a'+'z'+1;
        }
    }
}
*/
/*
 * Nome: main
 * Scopo: Stampa a video una frase cifrata
 * Input: una frase da cifrare e un intero 
 * Output: 0 se il programma termina correttamente
 */
int main(int argc, char *argv[]) 
{
    char vet[NChar];
    int i, chiave;
    // INPUT
    if (argc != 3) 
    {
       printf("Comando errato - Sintassi: cifra  \n");
       return(0);
    }
    else 
    {    // copia n caratteri
         strncpy (vet, argv[1], NChar);
         // strncpy(vet,"abcdefghijklmnopqrstuvwxyz",NChar);
         chiave = atoi(argv[2]);
    }
    // ALGORITMO
    CodificaDiCesare(vet, NChar, chiave);
    // OUTPUT
    printf(">> Parola in chiaro: %s\n", argv[1]);
    printf(">> Parola cifrata  : %s\n\n", vet);

    system("pause");
    return(0);
}

ESERCIZIO
 
Costruire un programma che legge una sequenza di parole e alla fine evidenzia qualla con il maggior numero di consonanti e di vocali. La sequenza è terminata quando l'utente scrive la stringa "0" oppure se sono state digitate NWords parole.

 
SOLUZIONE:
NOTE:

Per le prove usa il seguente elenco di parole (cut & paste).

Precipizio
Vocabolario
Novembre
Chiocciola
Asinara
Universiadi
Aiuola
Illustre
Caseggiato
Formaggio
0
#define identifier replacement => Si tratta di una direttiva di definizione per il precompilatore. Una direttiva per il precompilatore inizia sempre con il carattere # ed occupa una sola riga. Su tale riga possono essere messi dei commenti ( // o /* ) o il simbolo di continuazione alla riga successiva ( ). Il file sorgente contenente le direttive, viene tradotto dal pre-processore in quella che viene chiamata la translation unit (anch’essa formata solamente da codice sorgente), la quale viene poi compilata in codice binario, dando origine al corrispondente file oggetto. Tutti i file oggetto, infine, vengono collegati dal linker, generando un unico programma eseguibile.

Le direttive di inclusione sono quelle che iniziano con #include.

Le direttive di definizione sono sostanzialmente due, #define e #undef, che, come vedremo sotto, possono essere usate congiuntamente per definire o meno qualcosa in modo condizionale. La sintassi è:
#define identificatore espressione
in cui sostanzialmente il pre-processore sostituisce tutte le occorrenze di "identificatore" con l’espressione corrispondente (che può contenere anche spazi o virgolette). Quando la direttiva serve per definire una macro ha una sintassi leggermente diversa:
#define identificatore(argomenti) espressione
In questo caso, invece, si suppone che l’espressione contenga gli argomenti come variabili sulle quali operare. Il pre-processore non fa altro che sostituire il codice di espressione, modificando gli argomenti definiti nella macro con quelli attuali, ad ogni occorrenza dell’identificatore.

Ovviamente #undef serve solo per annullare il compito di ciò che abbiamo definito con l’eventuale #define. Ecco un esempio di utilizzo:
#undef NUMERO
#define NUMERO 7
Le direttive condizionali permettono di definire una serie di istruzioni che verranno compilate in determinate condizioni. Questo tipo di direttive viene usato spesso per compilare il medesimo sorgente su diversi sistemi operativi (cambiando dei parametri che in Linux funzionano ed in Windows no, e viceversa). Le direttive condizionali sono sei:
#if espressione
Se il valore dell'espressione è zero (quindi FALSO) allora l’#if non farà niente, Se il valore è diverso da zero (TRUE), allora si eseguirà il codice sotto l’if fino a che non si incontra un #elif, un #else o un #endif.
#ifdef identificatore
Riferendosi all’identificatore passato come parametro, se è già stato definito (TRUE) si eseguirà il codice sotto l’if fino a che non si incontra un #elif, un #else o un #endif.
#ifndef identificatore
Complementare al precedente. Esegue l’#if solo se l’identificatore passato non è stato definito.

#elif espressione
Corrisponde al costrutto ELSE IF, e quindi verifica la propria espressione ed agisce di conseguenza. Può essere usato per definire scelte multiple (tranne l’ultima).
#else
Nell’ultima voce delle scelte condizionali bisogna mettere l’else che copre la casistica non ricoperta dall’#if e dagli #elif precedenti. Tutto il codice che sta dopo l’else verrà eseguito fino a quando non si incontra un #endif.
#endif
Chiude la direttiva #if e, corrisponde, nel linguaggio C, alle famose parentesi graffe..
Vediamo ora un esempio completo che consente di testare il SO dove il nostro programma viene eseguito: Ci sono delle macro predefinite che sono usate dalla maggior parte dei compilatori. Ad esempio se uso il compilatore GCC (GNU Compiler Collection: è un compilatore per linguaggi di programmazione. Creato da Richard Stallman (fondatore del movimento Free Software Fondation) nel 1987 come semplice compilatore C, nel tempo e grazie al lavoro di diversi programmatori, è stato via via ampliato fino a supportare molti altri linguaggi {tra cui C++, Java, ecc.} ed è stata ampliata la compatibilità alla maggior parte dei sistemi operativi UNIX-based. Oggi è utilizzato come punto di riferimento per molti programmatori open source) posso usare questo codice
#include <stdio.h>
#ifdef _WIN64
   // per SO Windows  a 64-bit
   #define DoveSono() printf("Sono in Win 64-bit")
#elif _WIN32
   // per SO Windows  a 32-bit
   #define DoveSono() printf("Sono in Win 32-bit")
#elif _WIN16
   // per SO Windows  a 16-bit
   #define DoveSono() printf("Sono in Win 16-bit")
#elif __APPLE__
    #include "TargetConditionals.h"
    #if TARGET_OS_IPHONE    
         // device iOS
         #define DoveSono() printf("Sono in device iOS")
    #elif TARGET_IPHONE_SIMULATOR
        // Simulatore iOS
         #define DoveSono() printf("Sono in simulatore iOS")
    #elif TARGET_OS_MAC
        // Altri tipi di Mac OS
        #define DoveSono() printf("Sono in Mac OS")
    #else
        // SO Sconosciuto
        #define DoveSono() printf("Sono in OS Apple sconosciuto")
    #endif
#elif __linux
    // linux
    #define DoveSono() printf("Sono in Linux")
#elif __unix // SO unix non riconducibili a linux
    // Unix
    #define DoveSono() printf("Sono in UNIX")
#elif __posix
    // POSIX
    #define DoveSono() printf("Sono in POSIX")
#else
    // SO Sconosciuto
    #define DoveSono() printf("Sono in SO sconosciuto")
#endif

int main()
{
    DoveSono();
    
    // metto in stop il programma prima della sua chiusura
    fflush(stdin);
    getchar();
    return(0);
}


SOLUZIONE:

/**************************************************************************
 * Nome: casa3-vocali_consonanti.c                                        *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>  // richiesta da system();
#include <string.h>  // richiesta da strcmp();
#define NWords 20
#define LStr 30
/*
 * Nome: Lettera
 * Scopo: Determina se un carattere e' una lettera
 * Input: char c: il carattere da esaminare
 * Output: 1 se il carattere e' una lettera; 0 altrimenti
 */
// Potevo usare la funzione isalpha() in alternativa
// #include <ctype.h>  // richiesta da isalpha();
// #define EUnaLettera(c) isalpha(c)  
// Oppure
// #define EUnaLettera(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))  
bool EUnaLettera(char c) 
{
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
       return true;
    else 
       return false;
}
/*
 * Nome: vocale
 * Scopo: Determina se un carattere e' una vocale
 * Input: char c: il carattere da esaminare
 * Output: true se il carattere e' una vocale; false altrimenti
 */
bool EUnaVocale(char c) 
{
    bool IsVowel;
    IsVowel=(c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
    IsVowel=IsVowel || (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
    /* In alternativa
    if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' ||
        c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U') 
        return true;
    else
        return false;  
    */
    return IsVowel;  
}

/*
 * Nome: conta_vocali_consonanti
 * Scopo: Conta il numero di vocali e consonanti in una stringa
 * Input: char *vet: il vettore che contiene la stringa
 *        int n: la lunghezza della stringa
 *        int *voc: il numero di vocali ritornato
 *        int *cons: il numero di consonanti ritornato
 * Output: 1 -
 */
void Conta_Vocali_Consonanti(char *Parola, int n, int *voc, int *cons) 
{
     for (int i = 0; i < n && Parola[i] != '\0'; i++) 
     {
         if (EUnaVocale(Parola[i])) 
            (*voc)++;
         else if (EUnaLettera(Parola[i])) 
            (*cons)++;
     }
}
/*
 * Nome: acquisisci
 * Scopo: Acquisisce parole da tastiera finchè non digito "0" fino ad un 
 *        massimo di NWords
 * Input: char (*m)[DIM]: la matrice nella quale salvare le parole
 * Output: il numero di parole acquisite
 */
int Acquisisci (char m[][LStr]) 
{
	// Potevo anche scrivere:
	// int Acquisisci (char (*m)[LStr]) 
	// Le dimensioni successive alla prima sono obbligatorie
    int n = 0;
    do 
    {
       printf("Digita la %2d^ parola: ",n+1);
       // Specifico il nr. massimo di caratteri da òeggere
       scanf("%30s", m[n]);
       if (strcmp(m[n], "0") != 0) 
          n++;
    } while(n < NWords && strcmp(m[n], "0") != 0 );    
    return n;
}
/*
 * Nome: main
 * Scopo: Acquisisce un gruppo di parole da tastiera e stampa a video la parola
 *        con piu' vocali e la parola con piu' consonanti
 * Input: -
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    char Vocaboli[NWords][LStr];
    int r, n, NrVoc, NrCons;
    int max_v = 0, max_c = 0, best_v = 0, best_c = 0;
    // INPUT
    n=Acquisisci(Vocaboli);
    // ALGORITMO
    for (r = 0; r < n; r++) 
    {
        NrVoc = NrCons = 0;
        Conta_Vocali_Consonanti(Vocaboli[r], LStr, &NrVoc, &NrCons);
        if (NrVoc >= max_v) 
        {
           max_v = NrVoc;
           best_v = r;
        }
        if (NrCons >= max_c) 
        {
           max_c = NrCons;
           best_c = r;
        }
    }
    // OUTPUT
    printf("Parola con piu' vocali (%2d)    : %s\n", max_v, Vocaboli[best_v]);
    printf("Parola con piu' consonanti (%2d): %s\n", max_c, Vocaboli[best_c]);

    system("pause");
    return(0);
}

ESERCIZIO
 
Costruire una funzione che legge una sequenza di parole e stampa le coppie di anagrammi. La sequenza è terminata quando l'utente scrive la stringa "0" oppure se sono state digitate NWords parole.

 
SOLUZIONE:
NOTE:

Per le prove usa il seguente elenco di parole (cut & paste).

ROMA
BORA
BRESCIA
CALENDARIO
LOCANDIERA
ASCOLTATELI
SOLLECITATA
Orba
amor
SOLLETICATA
baro
RITAGLIERAI
roba
Artiglieria
0
int isalpha ( int c ); => Converte l'argomento c nel suo corrispondente miniuscolo se c è una lettera maiuscola. Se nessuna conversione è possibile allora la funzione restituisce c. Richiede <ctype.h>.
/**************************************************************************
 * Nome: casa4-anagramma.c                                                *
 * Autore: Alessandro Saetti                                              *
 * Data: 23/3/10                                                          *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // Richiesta da system("pause");
#include <string.h> // Richiesta da strncpy(char *d, char *o,int n)
#include <ctype.h>   // richiesta da tolower();
#define NWords 20
#define LStr 30
/*
 * Nome: Anagramma
 * Scopo: Determina se due parole sono l'una l'anagramma dell'altra
 * Input: char *p1: la prima parola
 *        char *p2: la seconda parola
 *        int n: la lunghezza massima dei vettori p1 e p2
 * Output: 1 se le due parole sono degli anagrammi; 0 altrimenti
 */
// int Anagramma (char p1[], char p2[], int n)
bool Anagramma (char *p1, char *p2, int n)
{
    int i, p, c1[26] = {0}, c2[26] = {0};
    if (strlen(p1)!=strlen(p2)) return false;
    // Conteggio le occorrenze di ogni singola lettera nella 1° parola
    for ( i=0; i < LStr && p1[i]!='\0' ; i++ )
    { 
        p=tolower(p1[i])-'a';
        c1[p]++;
    }
    // Conteggio le occorrenze di singola lettera nella 2° parola
    for ( i=0; i < LStr && p2[i]!='\0' ; i++ ) 
    { 
        p=tolower(p2[i])-'a';
        c2[p]++;
    }
    // Se il conteggio delle occorrenze è identico allora la prima parola è
    // un anagramma della seconda.
    for(i=0 ; i < 26 ; i++) 
        if ( c1[i] != c2[i] ) 
           return false;
    return true;
}
/*
 * Nome: acquisisci
 * Scopo: Acquisisce parole da tastiera finchè non digito "0" fino ad un 
 *        massimo di NWords
 * Input: char (*m)[DIM]: la matrice nella quale salvare le parole
 * Output: il numero di parole acquisite
 */
int Acquisisci (char m[][LStr]) 
{
	// Potevo anche scrivere:
	// int Acquisisci (char (*m)[LStr]) 
	// Le dimensioni successive alla prima sono obbligatorie
    int n = 0;
    do 
    {
       printf("Digita la %2d^ parola: ",n+1);
       // Specifico il nr. massimo di caratteri da leggere
       scanf("%30s", m[n]);
       if (strcmp(m[n], "0") != 0) 
          n++;
    } while(n < NWords && strcmp(m[n], "0") != 0 );    
    return n;
}
/*
 * Nome: main
 * Scopo: Acquisisce da tastiera un gruppo di parole e stampa a video le coppie di anagrammi
 * Input: -
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    char Vocaboli[NWords][LStr];
    int n, r1 , r2;
    // INPUT
    n=Acquisisci(Vocaboli);
    // ALGORITMO + OUTPUT
    printf("ANAGRAMMI TROVATI:\n ");
    for (r1 = 0; r1 < n; r1++) 
        for (r2 = r1 + 1; r2 < n; r2++) 
            if (Anagramma(Vocaboli[r1], Vocaboli[r2], LStr)) 
               printf("%30s <==> %-30s\n", Vocaboli[r1], Vocaboli[r2]);    
    // metto in stop il programma prima della sua chiusura
    system("pause");
    return 0;
}

ESERCIZIO
 
Testo esercizio
 
SOLUZIONE:
Soluzione C++
Soluzione JavaScript
Soluzione VBA
Soluzione ASP
Soluzione PHP