Inizializzazione dell'unione nella programmazione C e nell'odore del codice

Inizializzazione dell'unione nella programmazione C e nell'odore del codice

In questo post del blog imparerai tutti i concetti importanti relativi all'inizializzazione dell'unione nella programmazione C. Qui non spiegheremo il concetto di sindacato in C. Spieghiamo solo il modo e le questioni relative al sindacato C.

I post del blog trattano i seguenti argomenti:

  • Come si inizializza un'unione in C o l'inizializzazione dell'unione in C?
  • Quanti membri del sindacato possono essere inizializzati?
  • Inizializzatori designati di un'unione in C?
  • Il bug che può essere sollevato con gli inizializzatori di unione.

Come si inizializza l'unione in C:

Prima di capire come inizializzare un'unione, comprendiamo il significato di inizializzazione.

Nella programmazione C, l'inizializzazione è l'assegnazione di un valore iniziale per una variabile (oggetto). Il modo per inizializzare un oggetto dipende dal linguaggio di programmazione, nonché dal suo tipo, classe di archiviazione, ecc. In genere l'inizializzazione viene eseguita tramite inizializzatori ed elenchi di inizializzatori.

Considera l'esempio seguente,

static int data1;   // initializes data1 to 0

int data2 = 1;      // initializes data2 to 1

// initializes int arr[4] to 1,3,5,25
int arr[] = { 1, 3, 5, 25 };

Ora credo che tu abbia una conoscenza di base dell'inizializzazione, quindi veniamo al nostro argomento Inizializzazione dell'unione.

Come altri inizializzatori, un inizializzatore di unione specifica il valore iniziale archiviato in un oggetto di unione. Quando si inizializza un oggetto di tipo unione, l'inizializzatore deve essere un elenco di inizializzatori non vuoto (fino a C23) racchiuso tra parentesi e separati da virgole per i membri.

I seguenti sono gli inizializzatori per l'unione.

1.)  = { expression , ... }

2.) = { designator expression , ... } (dal C99)

3.) = { } (da C23)

Discutiamo di ogni inizializzatore di unione uno per uno con un codice di esempio.

1. lista-inizializzatori:

Quando si inizializza un'unione, l'elenco di inizializzatori deve avere un solo membro (fino a C23), che inizializza il primo membro dell'unione.

Facciamo un esempio per una migliore comprensione.

#include <stdio.h>
union Test
{
    int x;
    char c;
};


int main()
{
    union Test obj = {1};

    printf("%d\n", obj.x);

    return 0;
}

Output: 1

2. Inizializzatori designati (da C99):

Usando il designatore possiamo inizializzare il membro specifico di un sindacato. Il designatore ha la forma .identifier . Qui identificatore è il nome di un membro del tipo di unione specificato.

La seguente sintassi può inizializzare qualsiasi membro di un'unione:

union Test
{
    /*
      List of union members

    */
};


//union object
union Test obj = {.any_member = 42 };

Puoi anche utilizzare il designatore con un'unione senza tag union(con nome, ma non con tag).

union
{
    /* 
      List of union members 
    
    */
} obj = {.any_member = 42 };

Considera l'esempio seguente,

#include <stdio.h>


union Test
{
    int i;
    double d;
};

int main()
{
    //Initialization
    union Test temp = { .d = 4 };

    printf("%f\n", temp.d);

    return 0;
}

Output: 4.000000

3. inizializzatore vuoto (C23):

Una coppia di parentesi graffe vuota ({} ) viene chiamato inizializzatore vuoto e viene indicato come inizializzazione vuota. Viene introdotto in C23.

Considera l'esempio seguente,

#include <stdio.h>

union Test
{
    int i;
    double d;
};

int main()
{
    //empty Initialization C23
    union Test temp = {};

    printf("%d\n", temp.i);

    return 0;
}

Output: 0

Ti viene in mente una domanda quale sarà il valore di un oggetto che viene inizializzato con un inizializzatore vuoto.

Non preoccuparti C23 ha già dato la risposta a questa domanda.

Quindi, se un oggetto viene inizializzato con un inizializzatore vuoto, allora:

  • Il tipo di puntatore viene inizializzato su un puntatore nullo.
  • I tipi integrali vengono inizializzati su zero senza segno.
  • I tipi decimali mobili vengono inizializzati su zero positivo e l'esponente quantistico è definito dall'implementazione.
  • Tutti gli elementi degli array, tutti i membri degli struct e i primi membri delle unioni vengono inizializzati in base alle regole precedenti, in modo ricorsivo, inoltre tutti i bit di riempimento vengono inizializzati a zero.

Inizializzazione dell'unione anonima:

Un membro senza nome il cui identificatore di tipo è un identificatore di unione senza tag viene chiamato unione anonima. I suoi membri sono anche considerati membri della struttura o dell'unione di contenimento, mantenendo la loro struttura o disposizione dell'unione. E questo vale in modo ricorsivo se anche la struttura o l'unione che li contiene è anonima.

L'esempio seguente illustra le unioni anonime:

struct Test
{
    union   // anonymous union
    {
        int var1;
        char var2;
    };
    int data;
} obj;

Poiché i membri di unioni anonime sono considerati membri della struttura contenitore
o dell'unione, struct Test nell'esempio seguente ha tre membri. Possiamo accedere a var1 e var2 usando l'oggetto di struct Test.

Qui mi interessa spiegare come è possibile inizializzare membri anonimi del sindacato di una struttura. Facciamo un esempio per una migliore comprensione.

#include <stdio.h>

struct Test
{
    union   // anonymous union
    {
        int var1;
        char var2;
    };
    int data;
};

int main()
{
    struct Test obj = {{257}, 128};

    printf("obj.var1 = %d obj.data = %d\n",obj.var1, obj.data);
    
    return 0;
}

Risultato:

obj.var1 = 257 obj.data = 128

Spiegazione: 

Puoi vedere il codice di esempio sopra in cui i membri dell'unione anonima si comportano come i membri della struttura.

Odore del codice:

Vediamo alcuni esempi di programmi C che non sono un errore del compilatore ma possono introdurre seri problemi.

Question-1:

#include <stdio.h>
union Test
{
    char a;
    int b;
};


int main()
{
    union Test obj = {127};

    printf("%d\n", obj.b);

    return 0;
}

Risultato: Comportamento non specificato

Spiegazione :

Nell'esempio precedente, stiamo inizializzando il primo membro dell'unione, il che significa inizializzare i membri dati "a '. Ma stiamo rileggendo che "b ' che ti dà un valore non specificato.

Note: Se il membro utilizzato per leggere il contenuto di un oggetto union non è lo stesso dell'ultimo membro utilizzato per memorizzare un valore nell'oggetto, la parte appropriata della rappresentazione dell'oggetto del valore viene reinterpretata come rappresentazione dell'oggetto nel nuovo tipo ( un processo a volte chiamato "tipo giochi di parole"). Se la dimensione del nuovo tipo è maggiore della dimensione dell'ultimo tipo scritto, il contenuto dei byte in eccesso non è specificato (e forse una rappresentazione trap).

Question-2:

#include <stdio.h>

struct Test
{
    int a;
    union   // anonymous union
    {
        char b;
        int c;
    };

};

int main()
{
    struct Test obj = {128, {257}};

    return 0;
}

Output: Y non otterrai l'output desiderato.

Explanation:

Un elenco di inizializzatori di unione inizializza il primo membro dell'unione a meno che non venga utilizzato un inizializzatore designato. Perché nell'esempio fornito il primo membro dell'unione è char con segno il cui intervallo è compreso tra -128 e 127 e stiamo cercando di inizializzarlo con 257; Si verificherà un overflow perché 257 è al di fuori del suo intervallo.

Post consigliato:

  • Corsi ed esercitazioni di programmazione C.
  • Corsi ed esercitazioni sulla programmazione CPP.
  • Corsi ed esercitazioni Python.
  • Impara i sindacati C con l'aiuto del codice di esempio.
  • Inizializzatori designati in C. 
  • struttura in C:dovresti conoscerla a fondo
  • imbottitura della struttura in C, dovresti saperlo.
  • Cos'è un membro di un array flessibile in c?
  • Qual ​​è l'importanza di struct hack in c?
  • Come accedere al puntatore all'interno di una struttura in c.
  • Come utilizzare la struttura del puntatore a funzione in linguaggio c?
  • Puntatore funzione nella struttura.
  • Le 10 principali domande sull'intervista sull'imbottitura della struttura.