Inicialização da matriz C char

Não tenho certeza do que será na matriz char após a boot das seguintes maneiras.

1. char buf[10] = "";
2. char buf[10] = " ";
3. char buf[10] = "a";

Para o caso 2, acho que o buf[0] deve ser ' ' , o buf[1] deve ser '\0' , e do buf[2] ao buf[9] será um conteúdo random. Para o caso 3, acho que o buf[0] deve ser 'a' , o buf[1] deve ser ‘\ 0’ e do buf[2] ao buf[9] será um conteúdo random.

Isso está correto?

E para o caso 1, o que será no buf ? buf[0] == '\0' e de buf[1] a buf[9] será conteúdo random?

Não é assim que você inicializa uma matriz, mas para:

  1. A primeira declaração:

     char buf[10] = ""; 

    é equivalente a

     char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
  2. A segunda declaração:

     char buf[10] = " "; 

    é equivalente a

     char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
  3. A terceira declaração:

     char buf[10] = "a"; 

    é equivalente a

     char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

Como você pode ver, nenhum conteúdo random: se houver menos inicializadores, o restante da matriz será inicializado com 0 . Este é o caso mesmo se a matriz for declarada dentro de uma function.

Edit: OP (ou um editor) alterou silenciosamente algumas das aspas simples na pergunta original para aspas duplas em algum momento depois que eu forneci esta resposta.

Seu código resultará em erros do compilador. Seu primeiro fragment de código:

 char buf[10] ; buf = '' 

é duplamente ilegal. Primeiro, em C, não existe um char vazio. Você pode usar aspas duplas para designar uma string vazia, como em:

 char* buf = ""; 

Isso lhe dará um ponteiro para uma string NUL , isto é, uma string de um único caractere com apenas o caracter NUL . Mas você não pode usar aspas simples sem nada dentro delas – isso é indefinido. Se você precisa designar o caractere NUL , você deve especificá-lo:

 char buf = '\0'; 

A barra invertida é necessária para desambiguar do caractere '0' .

 char buf = 0; 

realiza a mesma coisa, mas o primeiro é um pouco menos ambíguo para ler, eu acho.

Em segundo lugar, você não pode inicializar matrizes depois de terem sido definidas.

 char buf[10]; 

declara e define o array. O buf identificador de matriz agora é um endereço na memory e você não pode alterar onde os pontos de buf por meio de atribuição. assim

 buf = // anything on RHS 

é ilegal. Seu segundo e terceiro fragments de código são ilegais por esse motivo.

Para inicializar uma matriz, você precisa fazer isso no momento da definição:

 char buf [10] = ' '; 

lhe dará uma matriz de 10 caracteres com o primeiro caractere sendo o espaço '\040' e o restante sendo NUL , ou seja, '\0' . Quando uma matriz é declarada e definida com um inicializador, os elementos da matriz (se houver) além daqueles com valores iniciais especificados são automaticamente preenchidos com 0 . Não haverá qualquer “conteúdo random”.

Se você declarar e definir a matriz, mas não inicializá-la, como no seguinte:

 char buf [10]; 

você terá conteúdo random em todos os elementos.

  1. Estes são equivalentes

     char buf[10] = ""; char buf[10] = {0}; char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
  2. Estes são equivalentes

     char buf[10] = " "; char buf[10] = {' '}; char buf[10] = {' ', 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
  3. Estes são equivalentes

     char buf[10] = "a"; char buf[10] = {'a'}; char buf[10] = {'a', 0, 0, 0, 0, 0, 0, 0, 0, 0}; 

A parte relevante da boot do projeto padrão n1570 6.7.9 C11 diz:

14 Uma matriz de tipo de caractere pode ser inicializada por um literal de string de caractere ou uma string literal UTF-8, opcionalmente entre chaves. Bytes sucessivos da cadeia literal (incluindo o caractere nulo de terminação, se houver espaço ou se a matriz for de tamanho desconhecido) inicializam os elementos da matriz.

e

21 Se houver menos inicializadores em uma lista de chaves anexadas do que elementos ou membros de um agregado, ou menos caracteres em uma cadeia de caracteres literal usados ​​para inicializar uma matriz de tamanho conhecido que existem elementos na matriz, o restante da agregação deve ser inicializado implicitamente da mesma forma que os objects que possuem duração de armazenamento estático.

Assim, o ‘\ 0’ é anexado, se houver espaço suficiente , e os caracteres restantes são inicializados com o valor que um static char c; seria inicializado dentro de uma function.

Finalmente,

10 Se um object que possui duração de armazenamento automático não for inicializado explicitamente, seu valor será indeterminado. Se um object que tem duração estática ou de armazenamento de encadeamento não for inicializado explicitamente, então:

[-]

  • se tiver tipo aritmético, é inicializado para (positivo ou não) zero;

[-]

Assim, sendo um tipo aritmético, o restante do array também é inicializado com zeros.

Curiosamente, é possível inicializar matrizes de qualquer maneira a qualquer momento no programa, desde que sejam membros de uma struct ou union .

Exemplo de programa:

 #include  struct ccont { char array[32]; }; struct icont { int array[32]; }; int main() { int cnt; char carray[32] = { 'A', 66, 6*11+1 }; // 'A', 'B', 'C', '\0', '\0', ... int iarray[32] = { 67, 42, 25 }; struct ccont cc = { 0 }; struct icont ic = { 0 }; /* these don't work carray = { [0]=1 }; // expected expression before '{' token carray = { [0 ... 31]=1 }; // (likewise) carray = (char[32]){ [0]=3 }; // incompatible types when assigning to type 'char[32]' from type 'char *' iarray = (int[32]){ 1 }; // (likewise, but s/char/int/g) */ // but these perfectly work... cc = (struct ccont){ .array='a' }; // 'a', '\0', '\0', '\0', ... // the following is a gcc extension, cc = (struct ccont){ .array={ [0 ... 2]='a' } }; // 'a', 'a', 'a', '\0', '\0', ... ic = (struct icont){ .array={ 42,67 } }; // 42, 67, 0, 0, 0, ... // index ranges can overlap, the latter override the former // (no compiler warning with -Wall -Wextra) ic = (struct icont){ .array={ [0 ... 1]=42, [1 ... 2]=67 } }; // 42, 67, 67, 0, 0, ... for (cnt=0; cnt<5; cnt++) printf("%2d %c %2d %c\n",iarray[cnt], carray[cnt],ic.array[cnt],cc.array[cnt]); return 0; } 

Não tenho certeza, mas normalmente inicializo uma matriz “” nesse caso, não preciso me preocupar com o final nulo da string.

 main() { void something(char[]); char s[100] = ""; something(s); printf("%s", s); } void something(char s[]) { // ... do something, pass the output to s // no need to add s[i] = '\0'; because all unused slot is already set to '\0' }