Concetti Chiave

  • In C, gli array e i puntatori sono strettamente correlati, ma presentano anche differenze significative, specialmente nella loro manipolazione e nella semantica delle operazioni aritmetiche.
  • Non ci sono controlli sui limiti degli array in C, il che può portare a sovrascritture di memoria, mentre per i puntatori il compilatore emette avvisi in caso di problemi.
  • Il nome di un array è considerato un puntatore al primo elemento, permettendo di utilizzare l'indicizzazione come un'espressione aritmetica con puntatori.
  • L'operatore sizeof() funziona diversamente: restituisce la dimensione totale per gli array e solo la dimensione del puntatore per i puntatori.
  • Non è possibile modificare il contenuto di una stringa letterale tramite un puntatore, ma è consentito farlo se la stringa è assegnata a un array.

Relazione tra array e puntatori

In C c’è una stretta relazione tra gli array e i puntatori, ma anche notevoli differenze. È possibile utilizzare un puntatore usando la notazione array, ma non è possibile usare puntatori come array e viceversa. Le principali difficoltà nel capire le relazioni tra i due tipi di dato sono quelle che riguardano la difficoltà di capire il tipo di oggetto puntato, la semantica delle operazioni aritmetiche eseguibili su puntatori o con puntatori infatti dipende dal tipo di oggetto puntato.

Controlli e conversioni

In C non ci sono controlli sul superamento dei limiti di array, perciò può accadere di sovrascrivere la memoria. Il compilatore in questi casi non dà warning per i puntatori, ma li dà per gli array.
Puntatori a int: int A [10]; int *p = A;

Puntatori ad array di int: int A [10]; int (*p )[10] = &A;

Array di puntatori ad int: int *p [10]

Il compilatore trasforma autonomamente le espressioni con notazione array in espressioni con tipo puntatore:

A → *(A+i)

Ci sono diversi modi per esprime un variabile in un array:

p [1] = *( p +1) = *( A+1) = A [1]) e p[0] = 0 = (1-1) = (x-x)= (&p -&p);

La regola di conversione da notazione array ad espressione aritmetica di tipo puntatore è applicata anche agli array multidimensionali:

A [j] [k] → (*(A+i)) [j] [k] → (*(*(A+i)+j)) [k] → *(*(*(A+i)+j)+k)

di avere righe di diverse lunghezze.

Una dichiarazione di puntatore riserva spazio di memoria per l’oindirizzo dell’oggetto puntato, tranne nel caso in cui l’oggetto puntato sia una stringa letterale, a cui viene riservato spazio di memoria (nel text segment). Non è possibile modificare il contenuto di una stringa letterale se questa è puntata da un puntatore, possiamo però farlo se è utilizzata per inizializzare un array.

Equivalenze e differenze

Equivalenze tra puntatori e array:

- Nome di array è trattato come un puntatore al primo elemento dell’array dal compilatore

- L’indicizzazione di un elemento di un array è uguale a un’espressione aritmetica con tipo puntatore

- Il nome di un array in una dichiarazione di funzione è trattata come un puntatore al primo elemento dell’array

Differenze tra puntatori e array:

- L’operatore sizeof() agisce in modo diverso

- Non è possibile modificare una stringa letterale se assegnata a un puntatore, ma se assegnata ad un array sì

- Non si può assegnare valori ad una variabile di tipo array, ma si può farlo con variabili puntatore

- Differenze legate alla keyword extern

Domande da interrogazione

  1. Qual è la relazione fondamentale tra array e puntatori in C?
  2. In C, gli array sono trattati come puntatori al primo elemento, ma non è possibile utilizzare puntatori come array e viceversa. La comprensione di questa relazione è complicata dalla semantica delle operazioni aritmetiche sui puntatori, che dipendono dal tipo di oggetto puntato.

  3. Quali sono i rischi associati all'uso di array in C?
  4. In C, non ci sono controlli sul superamento dei limiti degli array, il che può portare a sovrascrivere la memoria. Il compilatore non fornisce avvisi per i puntatori in questi casi, ma lo fa per gli array.

  5. Come avviene la conversione tra notazione array e puntatori?
  6. Il compilatore trasforma automaticamente le espressioni in notazione array in espressioni di tipo puntatore, ad esempio, A è equivalente a *(A+i). Questa regola si applica anche agli array multidimensionali.

  7. Quali sono le principali differenze tra puntatori e array?
  8. Le differenze includono il comportamento dell'operatore sizeof(), la possibilità di modificare stringhe letterali, l'assegnazione di valori e le differenze legate alla keyword extern. Ad esempio, non si possono assegnare valori a variabili di tipo array, ma è possibile farlo con variabili puntatore.

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community