J'ai un grand tableau en C (pas C ++ si cela fait une différence). Je veux initialiser tous les membres de la même valeur.
Je pourrais jurer avoir déjà connu un moyen simple de le faire. Je pourrais utiliser memset()
dans mon cas, mais n'y a-t-il pas un moyen de le faire intégré à la syntaxe C?
enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … };
etstruct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … };
. Si vous supprimez les points de suspension…
, ces fragments se compilent sous C99 ou C11.memset()
discussion spécifique: stackoverflow.com/questions/7202411/… Je pense que cela ne fonctionne que pour 0.Réponses:
À moins que cette valeur ne soit 0 (auquel cas vous pouvez omettre une partie de l'initialiseur et les éléments correspondants seront initialisés à 0), il n'y a pas de moyen simple.
Cependant, ne négligez pas la solution évidente:
Les éléments avec des valeurs manquantes seront initialisés à 0:
Donc, cela initialisera tous les éléments à 0:
En C ++, une liste d'initialisation vide initialisera également chaque élément à 0. Ce n'est pas autorisé avec C:
N'oubliez pas que les objets avec une durée de stockage statique seront initialisés à 0 si aucun initialiseur n'est spécifié:
Et que "0" ne signifie pas nécessairement "tous les bits à zéro", donc l'utilisation de ce qui précède est meilleure et plus portable que memset (). (Les valeurs en virgule flottante seront initialisées à +0, les pointeurs à la valeur nulle, etc.)
la source
Si votre compilateur est GCC, vous pouvez utiliser la syntaxe suivante:
Consultez la description détaillée: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html
la source
int
s aux données statiques, ce qui correspond à 256 K - exactement l'augmentation de taille que vous avez observée.int
s, commeint foo1 = 1, foo2 = 1, ..., foo65536 =1;
vous obtiendrez la même augmentation de taille.bool array[][COLS] = { [0...ROWS-1][0...COLS-1] = true}
, bien que je ne suis pas certain que ce soit plus lisible que le formulaire complet.Pour initialiser statiquement un grand tableau avec la même valeur, sans copier-coller multiple, vous pouvez utiliser des macros:
Si vous devez modifier la valeur, vous devez effectuer le remplacement à un seul endroit.
Edit: extensions utiles possibles
(avec l'aimable autorisation de Jonathan Leffler )
Vous pouvez facilement généraliser cela avec:
Une variante peut être créée en utilisant:
qui fonctionne avec des structures ou des tableaux composés.
les noms de macro sont négociables.
la source
VAL_1X
n'est pas un entier mais une liste. Comme pour les états Amigable, c'est également la voie à suivre pour les systèmes embarqués où vous souhaitez définir les valeurs init d'une EEPROM ou d'une mémoire Flash. Dans les deux cas, vous ne pouvez pas utilisermemset()
.Si vous voulez vous assurer que chaque membre du tableau est explicitement initialisé, omettez simplement la dimension de la déclaration:
Le compilateur déduira la dimension de la liste d'initialisation. Malheureusement, pour les tableaux multidimensionnels, seule la dimension la plus externe peut être omise:
est OK, mais
n'est pas.
la source
int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
J'ai vu du code qui utilise cette syntaxe:
Là où cela devient particulièrement utile, c'est si vous créez un tableau qui utilise des énumérations comme index:
Cela maintient les choses en ordre, même s'il vous arrive d'écrire certaines des valeurs d'énumération dans le désordre.
Plus d'informations sur cette technique peuvent être trouvées ici et ici .
la source
char const *array[] = { ... };
ou mêmechar const * const array[] = { ... };
, n'est-ce pas?Je pense que c'est mieux que
incase la taille des changements de tableau.
la source
memset(myArray, VALUE, ARRAY_SIZE);
Vous pouvez faire tout l'initialisation statique comme détaillé ci-dessus, mais cela peut être un vrai problème lorsque la taille de votre tableau change (lorsque votre tableau s'embigge, si vous n'ajoutez pas les initialiseurs supplémentaires appropriés, vous obtenez des ordures).
memset vous donne un hit d'exécution pour faire le travail, mais aucun hit de taille de code bien fait n'est à l'abri des changements de taille du tableau. J'utiliserais cette solution dans presque tous les cas lorsque le tableau était plus grand que, disons, quelques dizaines d'éléments.
S'il était vraiment important que le tableau soit déclaré statiquement, j'écrirais un programme pour écrire le programme pour moi et l'intégrer au processus de construction.
la source
memset
pour initialiser le tableau?Voici une autre façon:
Voir:
Extensions C
Inits désignés
Posez ensuite la question: quand peut-on utiliser des extensions C?
L'exemple de code ci-dessus est dans un système intégré et ne verra jamais la lumière d'un autre compilateur.
la source
Pour initialiser les types de données «normaux» (comme les tableaux int), vous pouvez utiliser la notation entre crochets, mais elle remettra à zéro les valeurs après la dernière s'il reste de l'espace dans le tableau:
la source
Si le tableau se trouve être int ou quoi que ce soit avec la taille de int ou la taille de votre modèle mem correspond aux heures exactes dans un int (c'est-à-dire tous les zéros ou 0xA5A5A5A5), la meilleure façon est d'utiliser memset () .
Sinon, appelez memcpy () dans une boucle déplaçant l'index.
la source
Une réponse légèrement ironique; écrire la déclaration
dans votre langue préférée compatible avec les tableaux (le mien est Fortran, mais il y en a beaucoup d'autres), et liez-le à votre code C. Vous voudrez probablement en faire une fonction externe.
la source
Il existe un moyen rapide d'initialiser un tableau de tout type avec une valeur donnée. Cela fonctionne très bien avec de grands tableaux. L'algorithme est le suivant:
Pour le tableau d'
1 000 000
élémentsint
, il est 4 fois plus rapide que l'initialisation de boucle normale (i5, 2 cœurs, 2,3 GHz, mémoire 4GiB, 64 bits):loop runtime 0.004248 [seconds]
memfill() runtime 0.001085 [seconds]
la source
memfill()
code prend environ 1200 µs. Cependant, lors des itérations suivantes, la boucle prend environ 900-1000 µs tandis que lememfill()
code prend 1000-1300 µs. La première itération est probablement impactée par le temps de remplissage du cache. Inversez les tests etmemfill()
est lent la première fois.Personne n'a mentionné l'ordre d'index pour accéder aux éléments du tableau initialisé. Mon exemple de code lui donnera un exemple illustratif.
La sortie est:
la source
<iostream>
est pas valableC
questd::cout
,std::cin
etc. fait partie dustd::namespace
etC
ne supporte pasnamespaces
. Essayez plutôt<stdio.h>
d' utiliser forprintf(...)
.En coupant tout le bavardage, la réponse courte est que si vous activez l'optimisation au moment de la compilation, vous ne ferez pas mieux que cela:
Bonus supplémentaire: le code est en fait lisible :)
la source
exemple: int array [10]; memset (tableau, -1, 10 * sizeof (int));
la source
Il donnera le o / p 5 5 5 5 5 5 ...... jusqu'à la taille de l'ensemble
la source
Je sais que l'utilisateur a
Tarski
répondu à cette question de manière similaire, mais j'ai ajouté quelques détails supplémentaires. Pardonnez une partie de mon C car je suis un peu rouillé car je suis plus enclin à vouloir utiliser C ++, mais c'est parti.Si vous connaissez la taille du tableau à l'avance ...
Il y a quelques mises en garde ci-dessus; l'une est qui
UINT myArray[size];
n'est pas directement initialisée lors de la déclaration, mais le tout prochain bloc de code ou appel de fonction initialise chaque élément du tableau à la même valeur que vous le souhaitez. L'autre mise en garde est que vous devrez écrire uninitializing function
pour chacun quetype
vous prendrez en charge et vous devrez également modifier laprintArray()
fonction pour prendre en charge ces types.Vous pouvez essayer ce code avec un complicateur en ligne trouvé ici .
la source
Pour l'initialisation retardée (c'est-à-dire l'initialisation du constructeur du membre de classe), considérez:
la source
Je sais que la question d'origine mentionne explicitement C et non C ++, mais si vous (comme moi) êtes venu ici à la recherche d'une solution pour les tableaux C ++, voici une astuce intéressante:
Si votre compilateur prend en charge les expressions de repli , vous pouvez utiliser la magie de modèle et
std::index_sequence
générer une liste d'initialisation avec la valeur souhaitée. Et vous pouvez mêmeconstexpr
vous sentir comme un patron:Vous pouvez jeter un œil au code au travail (sur Wandbox)
la source
Je ne vois aucune exigence dans la question, donc la solution doit être générique: initialisation d'un tableau éventuellement multidimensionnel non spécifié construit à partir d'éléments de structure éventuellement non spécifiés avec une valeur de membre initiale:
Résultat:
EDIT:
start+element_size
changé en(char*)start+element_size
la source
sizeof(void)
c'est même valable.memcpy()
chevauchent l'espace de destination. Avec une implémentation naïve dememcpy()
, cela peut fonctionner mais il n'est pas nécessaire que le système le fasse fonctionner.À l'époque (et je ne dis pas que c'est une bonne idée), nous avions défini le premier élément, puis:
memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);
Pas même sûr que cela fonctionnerait plus (cela dépendrait de l'implémentation de memcpy), mais cela fonctionne en copiant à plusieurs reprises l'élément initial sur le suivant - fonctionne même pour les tableaux de structures.
la source
memcpy
mais spécifiées dans l'ordre de copie ascendant ou descendant en cas de chevauchement, mais ce n'est pas le cas.memmove()
ne le fait pas fonctionner.Si vous voulez dire en parallèle, je pense que l'opérateur virgule lorsqu'il est utilisé en conjonction avec une expression peut le faire:
ou si vous voulez dire dans une seule construction, vous pouvez le faire dans une boucle for:
// Notez que l'opérateur virgule dans une liste d'arguments n'est pas l'opérateur parallèle décrit ci-dessus;
Vous pouvez initialiser une décomposition de tableau:
Vous pouvez appeler Malloc / calloc / sbrk / alloca / etc pour allouer une région de stockage fixe à un objet:
et accéder aux membres par:
Etc.
la source