Partilhar via


Inicializando tipos agregados

Um tipo de agregação é um tipo de estrutura, união ou matriz. Se um tipo de agregação contém membros de tipos de agregação, as regras de inicialização são aplicadas recursivamente.

Sintaxe

initializer:
{ initializer-list } /* Para inicialização de agregação */
{ initializer-list , }

initializer-list:
initializer
initializer-list , initializer

A initializer-list é uma lista de inicializadores separados por vírgulas. Cada inicializador na lista é uma expressão constante ou uma lista de inicializadores. Em virtude disso, as listas de inicializadores podem ser aninhadas. Esse formato é útil para inicializar membros de agregações de um tipo de agregação, como mostrado nos exemplos desta seção. No entanto, se o inicializador de um identificador automático for uma expressão única, ele não precisa ser uma expressão constante, apenas ter o tipo apropriado para a atribuição ao identificador.

Para cada lista de inicializadores, os valores das expressões constantes são atribuídos, em ordem, aos membros correspondentes da variável de agregação.

Se initializer-list tiver menos valores do que um tipo de agregação, os membros ou os elementos restantes do tipo de agregação serão inicializados como 0. O valor inicial de um identificador automático não inicializado explicitamente será indefinido. Se initializer-list tiver mais valores do que um tipo de agregação, ocorrerá um erro. Essas regras se aplicam a cada lista de inicializadores inseridos e à agregação como um todo.

O inicializador de uma estrutura é uma expressão do mesmo tipo ou uma lista de inicializadores para seus membros incluídos entre chaves ({ }). Membros de campo de bit sem nome não são inicializados.

Quando uma união é inicializada, initializer-list deve ser uma expressão constante única. O valor da expressão constante é atribuído ao primeiro membro de união.

Se o tamanho de uma matriz for desconhecido, o número de inicializadores determina o tamanho da matriz, e seu tipo se torna completo. Não há como especificar a repetição de um inicializador em C ou inicializar um elemento no meio de uma matriz sem fornecer todos os valores anteriores também. Se você precisar dessa operação em seu programa, escreva a rotina na linguagem Assembly.

O número de inicializadores pode definir o tamanho da matriz:

int x[ ] = { 0, 1, 2 }

No entanto, se você especificar o tamanho e fornecer o número incorreto de inicializadores, o compilador gerará um erro.

Seção específica da Microsoft

O tamanho máximo para uma matriz é definido por size_t.

Fim da seção específica da Microsoft

Exemplos

Este exemplo mostra inicializadores para uma matriz.

int P[4][3] =
{
    { 1, 1, 1 },
    { 2, 2, 2 },
    { 3, 3, 3,},
    { 4, 4, 4,},
};

Essa instrução declara P como uma matriz de quatro por três e inicializa os elementos da primeira linha como 1, os elementos da segunda linha como 2 e, assim por diante, até a quarta linha. A lista de inicializadores da terceira e da quarta linha contém vírgulas após a última expressão de constante. A última lista de inicializadores ({4, 4, 4,},) também é seguida por uma vírgula. Essas vírgulas extras são permitidas, mas não são necessárias. Somente vírgulas que separam expressões constantes umas das outras e vírgulas que separam uma lista de inicializadores de outra são necessárias.

Se um membro agregado não tiver uma lista de inicializadores inseridos, os valores serão atribuídos, em ordem, a cada membro do subagregado. Portanto, a inicialização no exemplo anterior é equivalente ao seguinte exemplo:

int P[4][3] =
{
   1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4
};

Os inicializadores individuais também podem estar entre chaves na lista, ajudando a esclarecer o exemplo.

Quando você inicializar uma variável de agregação, deve ter cuidado para usar corretamente as chaves e as listas de inicializadores. O exemplo a seguir ilustra com mais detalhes a interpretação das chaves pelo compilador:

typedef struct
{
    int n1, n2, n3;
} triplet;

triplet nlist[2][3] =
{
    { {  1, 2, 3 }, {  4, 5, 6 }, {  7, 8, 9 } },  /* Row 1 */
    { { 10,11,12 }, { 13,14,15 }, { 16,17,18 } }   /* Row 2 */
};

Neste exemplo, nlist é declarado como uma matriz de estruturas 2-por-3, cada estrutura com três membros. A linha 1 da inicialização atribui valores à primeira linha de nlist, como segue:

  1. A primeira chave à esquerda na linha 1 sinaliza ao compilador que a inicialização do primeiro membro da agregação de nlist (isto é, nlist[0]) foi iniciada.

  2. A segunda chave à esquerda indica a inicialização do primeiro membro da agregação de nlist[0] (isto é, a estrutura em nlist[0][0]) foi iniciada.

  3. A primeira chave à direita termina a inicialização da estrutura nlist[0][0]; a chave à esquerda a seguir inicia a inicialização de nlist[0][1].

  4. O processo continua até o final da linha, onde a chave de fechamento à direita encerra a inicialização de nlist[0].

A linha 2 atribui valores à segunda linha de nlist de forma semelhante. Os conjuntos externos de chaves que incluem os inicializadores nas linhas 1 e 2 são necessários. A construção a seguir, que omite as chaves externas, provocará um erro:

triplet nlist[2][3] =  /* THIS CAUSES AN ERROR */
{
     {  1, 2, 3 },{  4, 5, 6 },{  7, 8, 9 },   /* Line 1 */
     { 10,11,12 },{ 13,14,15 },{ 16,17,18 }    /* Line 2 */
};

Nessa construção, a primeira chave deixada na linha 1 inicia a inicialização de nlist[0], que é uma matriz de três estruturas. Os valores 1, 2 e 3, são atribuídos aos três membros da primeira estrutura. Quando a chave à direita seguinte é encontrada (após o valor 3), a inicialização de nlist[0] está concluída, e as duas estruturas restantes na matriz de três estruturas são iniciadas automaticamente como 0. Da mesma forma, { 4,5,6 } inicializa a primeira estrutura na segunda linha de nlist. As duas estruturas de nlist[1] restantes são definidas como 0. Quando o compilador localizar a lista de inicializadores seguinte ( { 7,8,9 } ), ele tentará inicializar nlist[2]. Como a nlist tem apenas duas linhas, essa tentativa causará um erro.

Neste exemplo, os três membros de int de x são inicializados como 1, 2, e 3, respectivamente.

struct list
{
    int i, j, k;
    float m[2][3];
} x = {
        1,
        2,
        3,
       {4.0, 4.0, 4.0}
      };

Na estrutura list, os três elementos na primeira linha de m são inicializados para 4.0. Os elementos da linha restante de m são inicializados para 0.0 por padrão.

union
{
    char x[2][3];
    int i, j, k;
} y = { {
            {'1'},
            {'4'}
        }
      };

A variável de união y, neste exemplo, é inicializada. O primeiro elemento da união é uma matriz, assim, o inicializador é um inicializador de agregação. A lista de inicializadores {'1'} atribui valores para a primeira linha da matriz. Como apenas um valor aparece na lista, o elemento na primeira coluna é inicializado com o caractere 1, e os dois elementos restantes na linha são inicializados com o valor 0 por padrão. Da mesma forma, o primeiro elemento da segunda linha de x é inicializado com o caractere 4, e os dois elementos restantes na linha são inicializados com o valor 0.

Confira também

Inicialização