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.

Namratha Patil
fonte
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

bk1e
fonte
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.

qrdl
fonte
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 .

lakshmanaraj
fonte
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.

LPs
fonte