Appunti di programmazione

Appunti per il corso universitario di programmazione, riferito al linguaggio ANSI C
Redatti all'università di Venezia

ARGOMENTI

STRUTTURA COMPUTER

DEFINIZIONI

TASTIERA E TIPI

AMBIENTE E MEMORIA

COMANDI

FUNZIONI E PROCEDURE

TIPI DERIVATI

PUNTATORI

STRINGHE

ARRAY DI PUNTATORI

STRUTTURE

TYPEDEF E ENUM

PUNTATORI A PROCEDURE

ALLOCAZIONE DINAMICA

LISTE

ALGORITMI

ERRORI

PUNTATORI

riferimento = un riferimento è la costante NULL oppure l'indirizzo di una variabile del tipo T (tipo base; un qualsiasi tipo)


<tipo referente> *<identificatore>;

es.

int *p;


attento: l'operatore “*” si associa con l'identificatore non con il nome di tipo:

scrivi “int *p”, non “int* p”


int *p, *q; p e q puntatori

int *p, q; solo p puntatore, q intero

int *p, q; idem


“&” (che non potrà mai stare a sinistra di un operatore di assegnamento: es. &v = ....) applicato a un designatore mi restituisce l'indirizzo della variabile designata


“*” = operatore di deferenziazione = applicato ad una espressione di tipo T* (indirizzo di variabile di tipo T) restituisce la variabile che ha quell'indirizzo (sempre che l'espressione abbia valore diverso da NULL)


quando dichiaro un puntatore senza inizializzarlo con un indirizzo, questo punta a una cella di memoria qualsiasi (molto pericoloso)


int *p;

int q;

q = 5;

p = &q;


*p (è un designatore perchè mi restituisce una variabile quindi può stare a sinistra in un comando di assegnamento; es. *p = 4; assegna alla variabile puntata da p il valore 4)


&p mi restituisce una variabile di tipo puntatore a puntatore


es.

void scambia(int a, int b){

int temp;

temp = a;

a = b;

b = temp;

}


int main(){

int x, y;

x = 0;

y = 4;

scambia(x,y);

return 0;

}

non funziona perchè non va a toccare le variabili x e y ma solo quelle locali a e b


es. corretto:

void scambia(int *a, int *b){

int temp;

temp = *a;

*a = *b;

*b = temp;

}


int main(){

int x, y;

x = 0;

y = 4;

scambia(&x, &y);

return 0;

}


il valore restituito come funzione può essere solo uno ma posso utilizzare i puntatori per ovviare a questo problema


double somma_media(int a, int b, int c, int *k){

*k = a + b + c;

return (*k)/ (double) 3;

}


int main(){

int a,b,c,somma;

double media;

a =

b =

c =

somma = somma_media(a,b,c,&media);

}

ARITMETICA DEI PUNTATORI

l'operazione di addizione nell'aritmetica dei puntatori incrementa il puntatore in base al suo tipo base: incrementare di 1 un puntatore significa far saltare il puntatore alla prossima locazione corrispondente ad un elemento di memoria il cui tipo coincide con quello base;

se p è l'indirizzo di una variabile di tipo tabella di T (tipo base), ossia p = &Tab[0], allora p + i, dove i è una costante intera, è per definizione &Tab[i]

es.

int tab[2]=...

int *q = tab; //punta a tab[0], manca & perchè tab è un array

q++; //ora q punta a tab[1], in termini di indirizzi passo ad esempio da 8000 a 8004 (perchè 4 di differenza? perchè la memoria viene indirizzata al byte)

la scrittura:

*q++

è da evitare; chi ha la precedenza ? l'operatore ++, quindi è equivalente a:

*(q++)


se abbiamo p e q di tipo T* che puntano ad indirizzi di celle di una stessa tabella (di tipo base T):


p = &tab[h]

q = &tab[k]

q – p = (&tab[k] - &tab[h])/sizeof(T))

sizeof(T) è la dimensione del tipo

OPERAZIONI FRA PUNTATORI:

  • la somma tra due puntatori non è definita

  • la sottrazione tra due puntatori è definita e ha significato solo se entrambi puntano ad un elemento dello stesso array (se sottraggo ottengo il delta tra i due elementi nell'array)

SIZEOF

printf(“%d”, sizeof(int));

stampa il numero di bit che mi serve per rappresentare una variabile di tipo intero

la posso applicare anche a specifiche variabili:

printf(“%d”, sizeof(int s));

ARRAY MULTIDIMENSIONALI

es.

int tab[3][3];

alloca 9 celle contigue di memoria


AMBIENTE


MEMORIA


int *tab

------>

colonna 1

riga



colonna 2

1



colonna 3




colonna 4

riga



colonna 5

2



colonna 6




colonna 7

riga



colonna 8

3



colonna 9








le seguenti scritture sono tutte equivalenti a tab[1][2]:

*(&tab[1] + 2)

(*(tab + 1))[2]

*(&tab[0][0] + (3*1) + 2)


in C esistono solo tabelle monodimensionali


a[k][h] di tipo T

a[k] è di tipo T*

a è di tipo T**


Q a[k] a è di tipo Q*

T* a[k] a è di tipo T**


int *p

int a[4]

posso scrivere

p = a;

ma non

a = p

poiché a non è una variabile


l'unica maniera per ”clonare” un array è utilizzare un ciclo for


funzione che calcola la somma degli elementi di un array

int somma(int k[], int dim){

int i;

int somma = 0;

for (i = 0;i < dim; i++)

somma += k[i];

return somma;

}

ricorsiva:

int somma(int k[], int dim){

if (dim = 0) return 0;

else

return k[0] + somma(k + 1, dim – 1);

}

Ritorna sopra | Home page