Approfondiamo un po' la parte evidenziata in blu ...
Esercizio:
1) Dichiarare ed implementare una funzione che alloca memoria sufficiente a contenere un array di variabili di tipo int; la dimensione dell'array sia posta pari a lungh. La funzione deve inizializzare ciascun elemento dell'array con un valore pari a quell dell'indice corrispondente all'elemento stesso e restituire il puntatore all'area di memoria allocata.
2)
visualizzare gli elementi dell'array che vanno dal sesto al decimo
Nota: la funzione deve restituire il puntatore ad un'area di memoria ; per poter ottenere un'area di memoria tale da non essere soggetta ai vincoli di durata cui sottostanno le variabili è necessario usare la funzione malloc(). Visto che malloc() restituisce un puntatore, il puntatore al primo elemento dell'area di memoria, gestisco tutti gli elementi facenti parte della memoria allocata da malloc() SOLO mediante tale puntatore (infatti, grazie all'aritmetica dei puntatori, noto il puntatore al primo elemento tutti gli altri sono univocamente individuati).
// inizio esercizio
#include <stdio.h>
int* init_int(int);
int* init_int(int lungh)
{int *puntatore,i;
puntatore = (int *) malloc(sizeof(int)*lungh);
for(i = 0 ; i < lungh ; i++)
{
*(puntatore + i) = i ;
}
/* la scrittura equivalente, usando la notazione degli array, è */
for(i = 0 ; i < lungh ; i++)
{
puntatore[i] = i ;
}
return puntatore;
}
/*
Quindi, usare l'operatore di dereferimento risulta essere equivalente all'uso delle []. La cosa risulta palese in questo caso:
int *p_double;
p_double = (double *) malloc(sizeof(double));
Le due istruzioni che seguono sono equivalenti (una variabile è un array di un elemento !)
*p_double = 3.4 ;
p_double[0] = 3.4 ;
*/
int main()
{int *vector;
int * origine;
int i = 0;
vector = init_int(50);
/* ora l'array di interi è stato allocato ed è gestibile mediante il valore della variabile vector, ovvero il puntatore al primo elemento dell'array */
// visualizziamo gli elementi dell'array
for(i = 5 ; i < 10 ; i++)
printf("\n %d ", * (vector + i) );
for(i = 5 ; i < 10 ; i++)
printf("\n %d ", vector [ i ] );
// inizializziamo il secondo puntatore ad intero
origine = vector + 5;
/*
vector |
|
|
|
|
origine |
|
|
|
|
|
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
*/
for(i = 0 ; i < 5 ; i++)
printf("\n %d ", * (origine + i) );
for(i = 0 ; i < 5 ; i++)
printf("\n %d ", origine [ i ] );
/*
vector |
|
|
|
|
|
|
|
|
origine |
|
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
*/
origine = vector + 9;
for(i = 4 ; i >=0 ; i--)
printf("\n %d ", * (origine - i) );
for(i = 4 ; i >=0 ; i--)
printf("\n %d ", origine [ -i ] );
free(vector);
return 0;}
// fine esercizio
In conclusione: tutto ciò che viene gestito mediante array (ovvero usando le []) può essere gestito grazie ad un puntatore. Se l'array è composto da elementi di tipo TIPO (ove TIPO, per ora, è pari a int, char, float o double) il puntatore dovrà far essere dichiarato come TIPO * .
Torniamo un istante agli array:
(1)
fino a questo momento abbiamo costruito array di char, int, float e double
(2) l'array veniva costruito anteponendo al nome dell'array il tipo degli elementi dell'array stesso ed inserendo la dimensione dell'array tra parentesi []
Possiamo usare questa ricetta per creare un array di parole, ovvero un array di stringhe ?
Le stringhe si gestiscono mediante puntatori a char, sarà quindi necessario dichiarare un array di puntatori a char.
char * vettore[30] ;
/* dichiaro un array di nome vettore composto da 30 elementi di tipo char *. */
Ora, dopo aver dichiarato l'array, è necessario inizializzare i suoi elementi; essendo composto da puntatori, per inizializzare gli elementi dell'array in modo corretto è necessario allocare delle aree di memoria e assegnare gli indirizzi di tali aree agli elementi dell'array.
for ( i = 0 ; i < 30 ; i ++ )
vettore[i] = (char *) malloc (50 * sizeof(char));

Ora che la memoria è stata allocata possiamo trattare gli elementi del vettore come delle stringhe a tutti gli effetti.
// inizio esempio
#include <stdio.h>
#include <string.h>
int main()
{char *stringhe[20];
int i = 0;
// alloco memoria per le stringhe
for( i = 0 ; i < 20 ; i ++ )
stringhe[i] = (char *) malloc (30 * sizeof (char) );
// inserisco dei caratteri in una stringa
strcpy( stringhe[0] , "prova di scrittura"
) ;
// chiedo all'utente di inserire caratteri in una stringa
printf("inserisci una stringa avente al massimo 19 caratteri");
scanf("
%s", stringhe[1] ) ;
/* inserisco un carattere all'interno di una stringa:
(a) stringhe[2] è un puntatore a char, ovvero punta al primo elemento della stringa
(b) con l'aritmetica dei puntatori avanzo di 3 posizioni e ottengo il puntatore al quarto elemento
(c) applico l'operatore di dereferimento ed inserisco il valore
*/
* (
stringhe[2] + 3) = 'g' ;
/*
(d) visto che l'aritmetica dei puntatori è equivalente alla notazione con le []
*/
stringhe[2][3] = 'g' ; // sembra tanto una tabella ...
return 0; }
// fine esempio