como o array [100] = {0} define o array inteiro como 0?


140

Como o compilador preenche valores char array[100] = {0};? Qual é a mágica por trás disso?

Eu queria saber como o compilador é inicializado internamente.


1
Em C ou C ++? São duas perguntas separadas.
Toby Speight

Respostas:


163

Isso não é mágico.

O comportamento desse código em C é descrito na seção 6.7.8.21 da especificação C ( rascunho online da especificação C ): para os elementos que não têm um valor especificado, o compilador inicializa os ponteiros para NULL e os tipos aritméticos para zero ( e recursivamente aplica isso a agregados).

O comportamento desse código em C ++ é descrito na seção 8.5.1.7 da especificação C ++ ( rascunho online da especificação C ++ ): o compilador inicializa os elementos que não têm um valor especificado.

Além disso, observe que no C ++ (mas não no C), você pode usar uma lista vazia de inicializadores, fazendo com que o compilador inicialize agregado todos os elementos da matriz:

char array[100] = {};

Quanto ao tipo de código que o compilador pode gerar ao fazer isso, dê uma olhada nesta pergunta: Montagem estranha da inicialização da matriz 0


Todos os compiladores C fazem isso? Fui levado a acreditar que apenas o Visual Studio faz isso.
JFA 10/10

1
rascunho on-line de c ++ specs quebrado, alguém tem novo link?
Behrooz Karjoo

35

A implementação depende dos desenvolvedores do compilador.

Se sua pergunta for "o que acontecerá com essa declaração" - o compilador definirá o primeiro elemento da matriz com o valor que você forneceu (0) e todas as outras serão definidas como zero porque é um valor padrão para os elementos da matriz omitidos.


Não tenho uma fonte, mas tenho certeza de que li em algum lugar que não há valor padrão para declarações de matriz; você pega o lixo que já estava lá. Não faz sentido perder tempo definindo esses valores quando é provável que você os substitua de qualquer maneira.
Ryan Fox

10
Ryan, se você não definir um valor para o primeiro elemento, que toda a matriz não seja inicializada e realmente contenha lixo, mas se você definir um valor para pelo menos um elemento, toda a matriz será inicializada, para que elementos não especificados sejam inicializados implicitamente em 0
qrdl 10/03/09

1
Para C ++, uma lista de inicializadores vazia para uma matriz limitada inicializa todos os elementos por padrão.
dalle

2
@NatanYellin Onde eu disse que isso é indefinido? Leia a resposta completa antes de comentar e fazer voto negativo.
qrdl

1
@qrdl Você está certo. Entendi mal o seu comentário sobre a implementação. Infelizmente, não posso mudar meu voto agora.
Natan Yellin

27

Se o seu compilador for o GCC, você também poderá usar a seguinte sintaxe:

int array[256] = {[0 ... 255] = 0};

Consulte http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits e observe que esse é um recurso específico do compilador .


Bem-vinda! desde que você pediu Olhando mais esses tipos de truques, eu tinha fornecido
lakshmanaraj

1
Você certamente pode fazer isso se quiser, mas há desvantagens óbvias em depender de extensões específicas do compilador como esta.
1111 Dan Danson

@ Dan Olson, sua pergunta está perguntando sobre compiladores específicos e, portanto, postou isso. Se você acha que é inútil, vou excluir.
10139 lakshmanaraj # 039

5
Não é inútil, é interessante. A ressalva apenas merece ser notada.
1111 Dan Danson

2
É de coisas como esta que me mantém voltando para SO e lendo mais do que os principais poucas respostas ...
timday

19

Depende de onde você coloca essa inicialização.

Se a matriz for estática como em

char array[100] = {0};

int main(void)
{
...
}

então é o compilador que reserva os 100 0 bytes no segmento de dados do programa. Nesse caso, você poderia ter omitido o inicializador.

Se sua matriz é automática, é outra história.

int foo(void)
{
char array[100] = {0};
...
}

Nesse caso, a cada chamada da função foo, você terá um memset oculto.

O código acima é equivalente a

int foo(void)
{ 
char array[100];

memset(array, 0, sizeof(array));
....
}

e se você omitir o inicializador, sua matriz conterá dados aleatórios (os dados da pilha).

Se sua matriz local for declarada estática como em

int foo(void)
{ 
static char array[100] = {0};
...
}

então é tecnicamente o mesmo caso que o primeiro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.