"Decadimento" si riferisce alla conversione implicita di un'espressione da un tipo di array a un tipo di puntatore. Nella maggior parte dei contesti, quando il compilatore vede un'espressione di array converte il tipo di espressione da "array di elementi N di T" a "puntatore a T" e imposta il valore dell'espressione sull'indirizzo del primo elemento dell'array . Le eccezioni a questa regola sono quando una matrice è un operando dell'operatore sizeof
o &
, oppure la matrice è una stringa letterale utilizzata come inizializzatore in una dichiarazione.
Assumi il seguente codice:
char a[80];
strcpy(a, "This is a test");
L'espressione a
è di tipo "array di caratteri a 80 elementi" e l'espressione "Questo è un test" è di tipo "array di caratteri a 16 elementi" (in C; in C ++ i valori letterali di stringa sono array di caratteri costanti). Tuttavia, nella chiamata a strcpy()
, nessuna delle due espressioni è un operando di sizeof
o &
, quindi i loro tipi vengono implicitamente convertiti in "puntatore a carattere" e i loro valori sono impostati sull'indirizzo del primo elemento in ciascuno. Ciò che strcpy()
riceve non sono matrici, ma puntatori, come si vede nel suo prototipo:
char *strcpy(char *dest, const char *src);
Questa non è la stessa cosa di un puntatore ad array. Per esempio:
char a[80];
char *ptr_to_first_element = a;
char (*ptr_to_array)[80] = &a;
Entrambi ptr_to_first_element
e ptr_to_array
hanno lo stesso valore ; l'indirizzo di base di a. Tuttavia, sono tipi diversi e vengono trattati in modo diverso, come mostrato di seguito:
a[i] == ptr_to_first_element[i] == (*ptr_to_array)[i] != *ptr_to_array[i] != ptr_to_array[i]
Ricordare che l'espressione a[i]
viene interpretata come *(a+i)
(che funziona solo se il tipo di matrice viene convertito in un tipo di puntatore), in modo da entrambi a[i]
e ptr_to_first_element[i]
di lavoro stesso. L'espressione (*ptr_to_array)[i]
viene interpretata come *(*a+i)
. Le espressioni *ptr_to_array[i]
e ptr_to_array[i]
possono portare a avvisi o errori del compilatore a seconda del contesto; faranno sicuramente la cosa sbagliata se ti aspetti che valutino a[i]
.
sizeof a == sizeof *ptr_to_array == 80
Ancora una volta, quando un array è un operando di sizeof
, non viene convertito in un tipo di puntatore.
sizeof *ptr_to_first_element == sizeof (char) == 1
sizeof ptr_to_first_element == sizeof (char *) == whatever the pointer size
is on your platform
ptr_to_first_element
è un semplice puntatore a char.
int a[10]; int b(void);
, quindi+a
è un puntatore int ed+b
è un puntatore a funzione. Utile se si desidera passarlo a un modello che accetta un riferimento.