Lezione 14: Varie, Matrici Dinamiche, Stringhe

[19/05/2011]
  • Varie: variabili locali static, variabili globali e funzioni static.
  • Preprocessore: macro, compilazione condizionata.
  • Funzioni inline.
  • Uso Puntatori: Passaggio Valori per riferimento, Vettori e Matrici Dinamiche.

Matrici Dinamiche:

Libreria: Interfaccia verso il client

// matrix.h
#ifndef MATRIX_LIB
#define MATRIX_LIB

typedef double **matrix;

// costruttore e distruttore di tipo
matrix NewMatrix(int n, int m);
void DestroyMatrix(matrix M);

// operazioni
void RangeMatrix(matrix M, int n, int m);
void RandomMatrix(matrix M, int n, int m, int top);

// output
void PrintMatrix(matrix M, int n, int m);

#endif

Libreria: Implementazione dell'interfaccia.

// matrix.c #include <stdlib.h>
#include <stdio.h>
#include "matrix.h"

matrix NewMatrix(int n, int m)
{
    double **righe = (double **) malloc(n*sizeof(double*));
    double *dati = (double *) calloc(n*m,sizeof(double));
    for (int i=0; i<n; i++)
        righe[i] = dati + i*m;
    return righe;
}

void DestroyMatrix(matrix M, int n, int m)
{
    free M[0];  // the data vector
    free M;      // the pointer vector
}

void RangeMatrix(matrix M, int n, int m)
{
    int k = 0;
    for (int i=0; i<n; i++)
        for (int j=0; j<m; j++) M[i][j] = k++;
}

void PrintMatrix(matrix M, int n, int m)
{
    int k = 0;
    for (int i=0; i<n; i++) {
        for (int j=0; j<m; j++)
            printf("%2.2f ",M[i][j]);
        printf("n");
    }
    printf("n");
}

void RandomMatrix(matrix M, int n, int m, int top)
{
    int k = 0;
    for (int i=0; i<n; i++)
        for (int j=0; j<m; j++)
            M[i][j] = rand() % top + 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "matrix.h"

int main(int argc, char *argv)
{
    matrix a = NewMatrix(10,10);
    RandomMatrix(a,10,10,100);

    PrintMatrix(a,10,10);
    DestroyMatrix(a);

    int n;
    scanf("%d",&n);

    matrix b = NewMatrix(n,n);
    RangeMatrix(b,n,n);
    PrintMatrix(b,n,n);
    DestroyMatrix(b);
    return 0;
}

Stringhe:

Esempio 1: Scorre lo standard input e trova la linea più lunga.

#include <stdio.h>

#define MAXLINE 2048

int getline(char *line, int maxline);
void copy(char *to, char *from);

int main(int argc, char *argv[])
{
    char line[MAXLINE+1];
    char linemax[MAXLINE+1];
    int max = 0;
    int len = 0;
    while ((len = getline(line,MAXLINE)) > 0)
        if (len > max)
        {
            max = len;
            copy(linemax, line);
        }
    if (max > 0)
        printf("%d: %sn",max,linemax);
    return 0;
}

/* getline,
   pre: s è preallocato di dimensione sufficiente per la lunghezza della stringa.
   post: legge una linea da stdin e la salva in s, restituisce la lunghezza
*/

int getline(char *s, int lim)
{
    int i,c;
    for (i=0; i<lim && (c=getchar()) != EOF && c != 'n'; i++)
        s[i] = c;
    if (c == 'n')
        s[i++] = c;
    s[i] = '';
    return i;
}

void copy(char *to, char *from)
{
    for (int i=0; (to[i] = from[i]) != ''; i++) ;
}

Esempio: grep.c, il programma prende in input una stringa S da linea di comando e cerca nello standard input tutte le linee che contengono la stringa S, con la stringa S circondata da asterischi per evidenziarne la posizione. Viene stampato anche il numero di linea nel file di ogni occurrenza di S e il numero totale di occorrenze.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLINE 2048

int getline(char *, int);
int strindex(const char *, const char *);
void copy(char *, const char *);

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

    if (argc > 2)
        pattern = argv[1];
    else
        pattern = "Alice";

    char line[MAXLINE+1];
    int count = 1;
    int found = 0;

    for (int count = 1; getline(line,MAXLINE) > 0; count++)
    {
        int pos = 0;
        if ((pos = strindex(line,pattern)) >= 0) {
            if (pos == 0) {
                printf("*%s*",pattern);
                printf("%s",line+strlen(pattern));
            }
            else if (strlen(line) - strlen(pattern) == pos)
            {
                line[pos] = '';
                printf("%s",line);
                printf("*%s*n",pattern);
            } else {
               char *temp = (char *)malloc(pos+1);
               strncpy(temp,line,pos);
               temp[pos] = '';
               printf("%s*%s*%sn",temp,pattern,line+pos+strlen(pattern));
               free(temp);
            }
           found++;

        }
    }
    printf("Trovate %d occorrenzen",found);
    return 0;
}

/* strindex:
   pre: source, pattern stringhe
   post: restituisce la prima posizione in source in cui compare pattern o -1 se
         pattern non compare dentro source.
*/

int strindex(const char *s, const char *pattern)
{
    int j,k;
    for (int i=0; s[i]!=''; i++) {
        for (j=i,k=0; pattern[k]!='' && s[j]==pattern[k]; j++,k++)
            ;
        if (k>0 && pattern[k]=='') return i;
    }
    return -1;
}

/* getline,
   pre: s è preallocato di dimensione sufficiente per la lunghezza della stringa.
   post: legge una linea da stdin e la salva in s, restituisce la lunghezza
*/

int getline(char *s, int lim)
{
    int i,c;
    for (i=0; i<lim && (c=getchar()) != EOF && c != 'n'; i++)
        s[i] = c;
    if (c == 'n')
        s[i++] = c;
    s[i] = '';
    return i;
}
// questa è (quasi) simile a strcpy
void copy(char *to, const char *from)
{
    for (int i=0; (to[i] = from[i]) != ''; i++) ;
}

 

3 thoughts on “Lezione 14: Varie, Matrici Dinamiche, Stringhe


  1. #include
    #include

    int main() {
    char *v;
    int dim;
    int i;

    printf("Quanti elementi? ");
    scanf("%d", &dim);

    /* alloca il vettore */
    v=malloc(dim*sizeof(int));

    for(i=0; i<=dim-1; i++) {
    printf("Dammi l'elemento v[%d]: ", i);
    scanf("%d", &(v));
    }

    for(i=0; i<=dim-1; i++)
    printf("v[%d] vale %dn", i, v[i]);

    return 0;
    }

    Questo programma dovrebbe prendere in input la dimensione dell'array e i corrispondenti valori. Conseguentemente dovrebbe stampare in output i valori dell'array ma il programma va in blocco o.O non riesco ad individuare l'errore!

    ( Ho provato anche *(v+i) al posto di v[i] )

    • E' quasi tutto corretto. Il problema sta nell'uso della scanf. Visto che non stai usando correttamente il vettore. Se devi leggere l'i-esimo elemento, allora vuoi cambiare v[i], quindi o passi a scanf &v[i], oppure visto che &v[i] = &*(v+i) = v+i, puoi passare v+i, ma &v non è un puntatore ad un elemento del vettore, è un puntatore ad un puntatore ad un vettore.

  2. Pingback: Lezione 19-20 |

Lascia un commento