Newsgroup: it.comp.lang.c
Titolo: puntatori?

Vi scrivo perché avrei problemi nell'utilizzo dei puntatori.
Se si inizializza un puntatore a puntatore, lo si può usare come se fosse un
array bidimensionale per contenere, ad esempio, una matrice? Se sì, come si
può fare a riempirla, magari dopo averla allocata dinamicamente?
Io, per provare questo ho provato a fare un programma (che non ho ancora
terminato perché mi dà errore), che (per ora) si limita a chiedere il numero
di righe, di colonne di una matrice, e gli elementi, dopo averla allocata
dinamicamente.
Deve esserci qualche sbaglio, perché dopo aver chiesto il primo elemento si
blocca il programma.
Riporto sotto il programma.
Grazie,
Zeppe
#include <stdio.h>
#include <stdlib.h>
void            riempmatr(double **matr, int n, int m);
void            printmatr(double **matr, int n, int m);
int             main(void)
{
    double        **matr1;
    int             n, m;
    FILE           *fp1;
    printf("Programma per calcolare la trasposta di una matrice\ne salvarla
su file\n");
    printf("\n\nPer prima cosa le dimensioni della matrice:\n\n Numero di
righe:  ");
    scanf("%d", &n);
    printf("\n\n Numero di colonne:  ");
    scanf("%d", &m);
    printf("\n\n");
    matr1 = calloc(n * m, sizeof(double));
    if (!matr1) {
        printf("Memoria Insufficente\n");
        return 0;
    }
    riempmatr(matr1, n, m);
    printmatr(matr1, n, m);
free(*matr1);
    return 1;
}
void            riempmatr(double **matr, int n, int m)
{
    int             i, j;
for (i = 0; i <= n; i++) {
        for (j = 0; j <= n; j++) {
            printf("\n\nElemento di posizione %d, %d: ", i+1, j+1);
            scanf("%lf", &matr[i][j]);
        }
    }
}
void            printmatr(double **matr, int n, int m)
{
    int             i, j;
    for (i = 1; i < n; i++) {
        for (j = 1; j < n; j++) {
            printf("%4lf", matr[i][j]);
        }
        printf("\n\n");
    }
}

può fare a riempirla, magari dopo averla allocata dinamicamente?
Prova il seguente programma (scritto al volo e non compilato, per cui
occhio...) :
#include <stdio.h>
#include <stdlib.h>
main()
{
    int righe, colonne, **matrice, x, y ;
    printf( "quante righe ?" ) ; 
    scanf( "%d", &righe ) ;
    printf( "quante colonne ?" ) ; 
    scanf( "%d", &colonne ) ;
    /* allocazione */
    matrice = malloc( righe * sizeof ( int * ) ) ;
    for ( y = 0 ; y < righe ; y++ ) 
    {
        matrice[y] = malloc( colonne * sizeof( int ) ) ;
    }
    /* riempimento */   
    for ( y = 0 ; y < righe ; y++ )
    {
        for ( x = 0 ; x < colonne ; x++ )
        {
            printf( "introduci a[%d,%d] = " ) ;
            scanf( "%d", &matrice[y][x] ) ;
        }
    }
    /* deallocazione */
    for ( y = 0 ; y < righe ; y++ ) 
    {
        free( matrice[y] ) ;
    }
    free( matrice ) ;
}
Andrea Laforgia (andrea_...@XXXbigfoot.com)
------------------------------------------------
Il mio indirizzo di posta elettronica è inattivo 
per il momento.

Vorrei delle delucidazioni sull'uso dei puntatori. Una struttura come quella
riportata là in basso, contiene degli errori? Se no, come si fa a chiedere
il nome di una persona, caricarlo in memoria, e farlo puntare al puntatore
interno alla struct, nel modo più semplice? Come si fa ad allocare la
memoria necessaria se non si sa comunque quanto sarà lungo il nome della
persona fino a che questa non lo immette?
Di puntatori non ci capisco quasi nulla, aiuto!
#include <stdio.h>
#include <stdlib.h>
typedef struct {
    char           *nome;
    char            s;
}               pers;
int             main(void)
{
    pers           *pers1;
    pers1 = calloc(1, sizeof(pers));
    if (!*pers) {
        printf("Memoria Esaurita" \ n);
        return -1;
    }
printf("Nome?:  ");
scanf("%s",????????????);
printf("\nSesso ('m' maschio, 'f' femmina):  ");
/*Magari si potrebbe fare un ciclo while che ripeta l'operazione se il
carattere inserito non è nè m nè f, ma comunque non so come recuperare il
valore dalla stuct! Forse con pers1->s? */
scanf("%c",????????????);
Grazie
Zeppe
}

 valore dalla stuct! Forse con pers1->s? */
Esatto.
EMG

valore dalla stuct! Forse con pers1->s? */
Esatto.
Puoi semplicemente scrivere :
pers1->s = '?' ;
while ( pers1->s != 'm' && pers1->s != 'f' ) 
{
      printf( "Sesso : " ) ;
      pers1->s = getchar() ;
 
      while ( getchar() != '\n' ) ; 
      /* svuota il buffer della tastiera */
}
--
Andrea Laforgia (
andrea_...@bigfoot.com
)
---------------------------------------------

occhio...) :
Intanto complimenti per il programma che era completamente funzionante (a
parte una dimenticanza negli indici...), io non mi sogno neanche di fare un
programma tutto giusto al primo colpo!! (sono proprio un programmatore della
domenica...).
Ma avrei qualche perplessità.
Per allocare la memoria di un array bidimensionale si deve usare per forza
un ciclo for? Andava bene anche la calloc (con una virgola, al posto del *)?
Comunque ora ho capito come si alloca la memoria per una matrice, era
proprio quello che sbagliavo, infatti ora il mio programma va.
Grazie,
Zeppe

      /* svuota il buffer della tastiera */
Non ho capito bene l'operazione di svuotamento del buffer. Se non si fosse
messo il secondo while, cosa sarebbe successo? Tanto s è un char, quindi più
di un carattere non ci stà!
Grazie,
Zeppe

un ciclo for? Andava bene anche la calloc (con una virgola, al posto del *)?
Non necessariamente, ci sono diversi modi per allocare un array
bidimensionale. Potresti usare anche la calloc() pero' poi avresti il
problema di come accedere agli elementi mediante la normale notazione
[y][x]. Ricordati, in fondo, che la calloc() e' solo una estensione
della malloc(), in cui si provvede anche ad azzerare il contenuto
della memoria puntata.


di un carattere non ci stà!
Il problema e' che getchar() e' una funzione che bufferizza il suo
input. La tecnica si chiama "line-buffering", cioe' vengono conservati
in memoria i caratteri introdotti dall'utente e rilasciati ad ogni
chiamata della funzione, fino a quando non si incontra una sequenza di
escape new-line (ovvero '\n' ), introdotta nel buffer nel momento in
cui l'utente ha premuto invio e quindi terminato l'input.
In questo modo, io svuoto il buffer, cioe' leggo tutti i caratteri
introdotti dall'utente dopo il primo, compreso il new-line, in modo
che, alla prossima chiamata, getchar() sara' obbligata a chiedere
l'input all'utente, trovando il buffer vuoto. 
Scusa per la spiegazione frettolosa !!! ;))
