Partilhar via


Inicializando tipos agregados

Um tipo agregado é uma estrutura, união ou tipo de matriz. Se um tipo de agregação contiver membros de tipos agregados, as regras de inicialização serão aplicadas recursivamente.

Sintaxe

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

initializer-list:
initializer
initializer-list , initializer

O initializer-list é uma lista de inicializadores separados por vírgulas. Cada inicializador na lista é uma expressão constante ou uma lista de inicializadores. Portanto, as listas de inicializadores podem ser aninhadas. Este formulário é útil para inicializar membros agregados de um tipo agregado, conforme mostrado nos exemplos desta seção. No entanto, se o inicializador de um identificador automático for uma única expressão, ela não precisará ser uma expressão constante; ele só precisa ter o tipo apropriado para 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 agregada.

Se initializer-list tiver menos valores do que um tipo agregado, os membros ou elementos restantes do tipo agregado serão inicializados como 0. O valor inicial de um identificador automático não inicializado explicitamente é indefinido. Se initializer-list tiver mais valores do que um tipo agregado, um erro resulta. Essas regras se aplicam a cada lista de inicializadores incorporada 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 entre chaves ({ }). Membros de campo de bits sem nome não são inicializados.

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

Se uma matriz tiver tamanho desconhecido, o número de inicializadores determinará o tamanho da matriz e seu tipo se tornará 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 em linguagem assembly.

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

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

Se você especificar o tamanho e fornecer o número errado de inicializadores, no entanto, o compilador gerará um erro.

Específico da Microsoft

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

END Específico 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,},
};

Esta instrução declara P como uma matriz quatro por três e inicializa os elementos de sua primeira linha para 1, os elementos de sua segunda linha para 2, e assim por diante, através da quarta linha. A lista de inicializadores para a terceira e quarta linhas contém vírgulas após a última expressão 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 obrigatórias. Apenas 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 incorporada, os valores serão atribuídos, em ordem, a cada membro da subagregação. Portanto, a inicialização no exemplo anterior é equivalente ao exemplo a seguir:

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

As chaves também podem aparecer em torno de inicializadores individuais na lista e ajudariam a esclarecer o exemplo.

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

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 2 por 3 de estruturas, cada estrutura com três membros. A linha 1 da inicialização atribui valores à primeira linha de nlist, da seguinte forma:

  1. A primeira chave esquerda na linha 1 sinaliza ao compilador que a inicialização do primeiro membro agregado de nlist (isto é, nlist[0]) está começando.

  2. A segunda chave esquerda indica que a inicialização do primeiro membro agregado de nlist[0] (isto é, a estrutura em nlist[0][0]) está começando.

  3. A primeira chave direita termina a inicialização da estrutura nlist[0][0], a próxima chave esquerda inicia a inicialização do nlist[0][1].

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

A linha 2 atribui valores à segunda linha de nlist forma semelhante. São necessários os conjuntos externos de chaves que encerram os inicializadores nas linhas 1 e 2. A seguinte construção, que omite as chaves externas, causaria 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 */
};

Nesta construção, a primeira cinta esquerda na linha 1 inicia a inicialização do 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 próxima chave direita é encontrada (após o valor 3), a inicialização de é concluída e as duas estruturas restantes na matriz de nlist[0] três estruturas são automaticamente inicializadas para 0. Da mesma forma, { 4,5,6 } inicializa a primeira estrutura na segunda linha do nlist. As duas estruturas restantes de nlist[1] são definidas como 0. Quando o compilador encontra a próxima lista de inicializadores ( { 7,8,9 } ), ele tenta inicializar nlist[2]. Como nlist tem apenas duas linhas, essa tentativa causa um erro.

Neste próximo exemplo, os três int membros do x são inicializados para 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, os list 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 yunion , neste exemplo, é inicializada. O primeiro elemento da união é uma matriz, portanto, o inicializador é um inicializador agregado. A lista {'1'} de inicializadores atribui valores à primeira linha da matriz. Como apenas um valor aparece na lista, o elemento na primeira coluna é inicializado para o caractere 1e os dois elementos restantes na linha são inicializados para o valor 0 por padrão. Da mesma forma, o primeiro elemento da segunda linha de x é inicializado para o caractere 4, e os dois elementos restantes na linha são inicializados para o valor 0.

Ver também

Inicialização