Il concetto di Union e' tipico del genere "godereccio" del linguaggio C, dove tutto e' possibile. Diciamo pure che e' utile sapere della loro esistenza, ma le Union vengono comode solo agli hacker piu' incalliti.
Structure e Union sono due concetti completamente diversi, l'unica cosa in comune e' la loro sintassi. Ma a differenza della Structure, dove ogni membro ha il suo posto in memoria, TUTTI i membri della Union usano la stessa memoria, che e' quindi la piu' grande tra quelle dei membri.
Vengono usate per diversi motivi, ma non molti. Per esempio, si vuole ottimizzare lo spazio di memoria allocato, e si sa gia' che quei valori NON saranno mai usati allo stesso tempo. Oppure si vuole accedere alla stessa posizione di memoria SENZA fare un casting. Utile per esempio per convertire un numero a virgola mobile nella sua rappresentazione binaria. Ma piu' comunemente viene usata per retro-compatibilita'. Per esempio, supponiamo che si ha scritto un file binario dove un valore fu scritto in decimale. Con il tempo lo si vuole cambiare in virgola mobile. Il trucco e' di leggere il valore in una Union con un decimale e un double, e poi accedere al suo valore a seconda della versione.
--- i due messaggi sono stati uniti ---
La ENUM funzione in pratica come la definizioni di costanti (numeriche). Si puo' assegnare valori alle dichiarazioni, oppure lasciare che il compilatore le assegni automaticamente (in valore incrementale).
E' utile quando NON si vuole usare delle costanti numeriche all'interno del proprio codice. Per esempio, l'istruzione
if (posizione == 34) e' ambigua, nel senso che chi la legge non ha idea cosa rappresenti il numero 34
Invece l'espressione if (posizione == SonoAlCesso) , dove SonoAlCesso e' definita all'interno di una enum, fa subito capire dove io sia in quel momento.
In altre parole, le ENUM rendono il codice piu' leggibile e compatto (proprio come i #define per esempio)
Circa il discorso delle unioni e strutture sei stato molto chiaro, mi hai tolto quasi ogni dubbio. Il "pallino" che mi è rimasto in testa è il seguente:
È legittimo manipolare i puntatori per accedere ai membri di una variabile di tipo struttura, ho fatto delle prove con il seguente codice, e non ho riscontrato problemi di compilazione ne esecuzione (quindi SUPPONGO di si) . Ma la mia domanda resta sempre la stessa: È legittimo ?
C:
#include <stdio.h>
typedef struct prova{
int a;
char b;
}nuovoTipo;
int main (int argc, char *argv[]){
nuovoTipo a = {25, 'A'};
void *p = &a;
char *ptr = p+4;
int *ptr1 = p;
printf("%c\n",*ptr);
printf("%d\n",*ptr1);
return 0;
}
--- i due messaggi sono stati uniti ---
Un'altra domanda che mi sono dimenticato di porti riguarda i campi di bit: Se scrivo una cosa del genere:
C:
#include <stdio.h>
typedef struct var_booleane{
unsigned int val: 1;
}Boolean;
int main (int argc, char *argv[]){
Boolean prova1;
printf("%d\n",sizeof(Boolean));
/* Output: 4 */
printf("%d\n",sizeof(int));
/* Output: 4 */
return 0;
}
se non ho capito male la variabile
val della struttura utilizzerà 1 solo bit di spazio in memoria, però:
1) eseguendo il codice (come scritto anche sotto forma di commenti) l'output della
sizeof( Boolean ) è 4 Byte, quindi la dimensione di un intero, suppongo quindi che in realtà la variabile
Boolean prova1 occupi 4 Byte ma ne siano accessibili soltanto 1 bit. È corretto questo ragionamento, o mi sto perdendo ??
2) In caso il ragionamento appena fatto fosse corretto, quale potrebbe essere una reale utilità dell'utilizzare questi campi di bit ? o sono solo una sorta di "presa per i fondelli" ? (dubito)
--- i due messaggi sono stati uniti ---
Il concetto di Union e' tipico del genere "godereccio" del linguaggio C, dove tutto e' possibile. Diciamo pure che e' utile sapere della loro esistenza, ma le Union vengono comode solo agli hacker piu' incalliti.
Structure e Union sono due concetti completamente diversi, l'unica cosa in comune e' la loro sintassi. Ma a differenza della Structure, dove ogni membro ha il suo posto in memoria, TUTTI i membri della Union usano la stessa memoria, che e' quindi la piu' grande tra quelle dei membri.
Vengono usate per diversi motivi, ma non molti. Per esempio, si vuole ottimizzare lo spazio di memoria allocato, e si sa gia' che quei valori NON saranno mai usati allo stesso tempo. Oppure si vuole accedere alla stessa posizione di memoria SENZA fare un casting. Utile per esempio per convertire un numero a virgola mobile nella sua rappresentazione binaria. Ma piu' comunemente viene usata per retro-compatibilita'. Per esempio, supponiamo che si ha scritto un file binario dove un valore fu scritto in decimale. Con il tempo lo si vuole cambiare in virgola mobile. Il trucco e' di leggere il valore in una Union con un decimale e un double, e poi accedere al suo valore a seconda della versione.
--- i due messaggi sono stati uniti ---
La ENUM funzione in pratica come la definizioni di costanti (numeriche). Si puo' assegnare valori alle dichiarazioni, oppure lasciare che il compilatore le assegni automaticamente (in valore incrementale).
E' utile quando NON si vuole usare delle costanti numeriche all'interno del proprio codice. Per esempio, l'istruzione
if (posizione == 34) e' ambigua, nel senso che chi la legge non ha idea cosa rappresenti il numero 34
Invece l'espressione if (posizione == SonoAlCesso) , dove SonoAlCesso e' definita all'interno di una enum, fa subito capire dove io sia in quel momento.
In altre parole, le ENUM rendono il codice piu' leggibile e compatto (proprio come i #define per esempio)
Per quanto riguarda le enumerazioni,finalmente ho capito cosa sono e come poterle utilizzare. Una cosa mi preme, il discorso memoria. Ovvero le costanti definite quando dichiaro un enumerazione quanto spazio occupano in memoria ? di che tipo sono (int, short, long, float ...) ?