Initialisation du tableau C à un moment autre que la déclaration?

Je sais en C que je peux faire ce qui suit.

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

À présent, cela n’est légal que lors de la déclaration du tableau. Cependant je me demandais pourquoi ce n’est pas légal de le faire plus tard? Mais plus tard dans le programme, il n’est pas légal de faire ce qui suit.

 test[5] = {10, 20, 30, 40, 50}; 

Ou quelque chose de similaire. Pourquoi est-ce? Je sais que ce n’est pas légal et que je ne me plains pas, mais quelqu’un pourrait-il m’expliquer plus techniquement pourquoi je ne peux pas le faire? (c.-à-d. ne dites pas simplement que la spécification C ne le permet pas ou quelque chose comme ça)

Je suppose que cela doit faire quelque chose avec le moment où la mémoire est allouée sur la stack pour le tableau, donc C peut à ce moment-là remplir automatiquement mes valeurs, mais pourquoi ne peut-il pas le faire plus tard?

Merci les gars

Ce ne sont pas que des tableaux, vous ne pouvez pas fournir d’initialiseur pour quoi que ce soit à un moment autre que dans une définition. Les gens se réfèrent parfois à la deuxième déclaration de quelque chose comme int i; i = 0; int i; i = 0; comme “initialisation i “. En fait, il s’agit d’une assignation à i , qui détient auparavant une valeur indéterminée car elle n’a pas été initialisée. Il est très rarement déroutant d’appeler cela “initialisation”, mais en ce qui concerne le langage, il n’y a pas d’initialiseur.

L’affectation et l’initialisation sont des éléments distincts de la langue, même s’ils utilisent tous deux le caractère = . Les tableaux ne sont pas assignables.

La raison pour laquelle les tableaux ne sont pas assignables est traitée ailleurs, par exemple Pourquoi C ++ prend-il en charge l’affectation de tableaux par membre au sein de la structure, mais pas en général? . La réponse courte est “des raisons historiques”. Je ne pense pas qu’il y ait une raison technique mortelle pour laquelle le langage ne pourrait pas être modifié pour permettre l’affectation de tableaux.

Un problème secondaire est que {1, 2, 3, 4, 5} est grammaticalement un initialiseur, pas un littéral de tableau, et ne peut donc pas être utilisé dans une affectation, même si les tableaux sont assignables. Je ne sais pas exactement pourquoi C89 n’a pas de littéraux de tableaux, probablement que personne n’a eu le temps de les exiger. C99 introduit une syntaxe pour les “littéraux composés” en général et les littéraux de tableaux en particulier: (int[]) {1, 2, 3, 4, 5} . Vous ne pouvez toujours pas affecter un tableau à partir de celui-ci.

Le fait est que l’utilisation de int array[]={ } déclarer et d’ initialiser l’object que vous avez créé.

Vous pouvez réellement affecter des valeurs à un tableau après sa déclaration :

 int array[5]; array[0] = 1, array[1] = 2, ... 

Ce que vous faisiez a été d’assigner plusieurs valeurs à une seule entrée de tableau:

 array[5] = {1,2,3,4,5}; // array[5] can only contain one value 

Ce serait légal à la place:

 array[5] = 6; 

J’espère que cela a du sens. Juste une question de syntaxe.

Notez que le littéral composé C99 vous permet de “passer des tableaux à des fonctions”:

 int your_func(int *test) { ...use test as an array... } void other_func(void) { int x = rand(); if (your_func((int[]){ 0, 1, 2, x, 3, 4 }) > 0 || your_func((int[]){ 9, x, 8, 7, 6, 5 }) > 0) ...whatever... } 

Ce n’est pas la même chose que de réinitialiser un tableau avec des valeurs différentes, mais cela peut être suffisamment proche pour que cela fonctionne pour vous.

Voici la solution

 //Declaration int a[5]; int a_temp[5] = {1, 2, 3, 4, 5 }; memcpy(a, a_temp, sizeof(a)); //Now array a have values 1, 2, 3, 4, 5 

La raison en est que les tableaux sont presque partout convertis en un pointeur sur le premier élément. Si vous avez deux tableaux

 double A[5]; double B[5]; 

dans une expression telle que

 A = B; 

les deux sont déjà convertis en pointeurs. Le A à gauche n’est en particulier pas une “lvalue”, vous ne pouvez donc pas l’affecter.

Cela ressemble à une excuse boiteuse, mais je suppose que, historiquement, cela s’est passé comme ça. C (et C ++ avec celui-ci) était pris au piège dans un choix de syntaxe précoce et si vous voulez restr compatible avec le code hérité, il n’ya probablement pas beaucoup de solution.