comment attribuer plusieurs valeurs dans une structure à la fois?
Je peux le faire lors de l'initialisation d'un struct Foo:
Foo foo = {bunch, of, things, initialized};
mais, je ne peux pas faire ça:
Foo foo;
foo = {bunch, of, things, initialized};
Alors, deux questions:
- Pourquoi je ne peux pas faire le dernier, est l'ancien spéciale constructeur pour l'initialisation seulement?
-
Comment puis-je faire la même chose pour le deuxième exemple, c'est à dire déclarer un tas de variables pour une structure dans une seule ligne de code après qu'il a déjà été initialisé? J'essaie d'éviter d'avoir à le faire pour les grandes structures avec de nombreuses variables:
Foo foo; foo.a = 1; foo.b = 2; foo.c = 3; //... ad infinitum
- "c'est l'ancienne spéciale du constructeur pour l'initialisation seulement?" Oui, justement, qui s'appelle globale de l'initialisation.
- C ou C++? Choisissez-en un.
- C(++) reste très primitif dans certains domaines.
- C'est juste de niveau inférieur. Qu'il semble que le "primitif dans certains domaines" est en fait juste que c'est les blocs de construction de base de la programmation procédurale. Quelque chose doit être. "Ces briques rouges sont moches. Nous devons nous débarrasser de nos briques et de venir avec un nouveau type de brique qui est recouverte de plâtre blanc." "Donc ce qui se passe sous le plâtre si non.. le rouge des briques?" Briques rouges doivent existent toujours, et les gens qui font du plâtre blanc recouvert de briques ont encore de voir et de travailler avec les briques rouges.
- Justement, je vous remercie pour les précisions.
- avez-vous une autre solution?
- Elles sont différentes langues et, par conséquent, garantit des questions différentes. Pour cette question, choisissez une seule langue s'il vous plaît.
- Je suis intéressé à ce que les solutions pourrait ressembler soit. Pouvez-vous m'indiquer où il y a une SORTE de règle qu'une question ne peut que refléter une seule langue? Je comprends bien le raisonnement, si je faisait référence C++/OCAML, mais, il me semble, un lecteur peut calculer la valeur d'une solution en C/C++.
- Si oui ou non c'est une SORTE de règle, beaucoup de gens (moi y compris) ne pourront pas répondre à une question tagged plusieurs langues, car elle implique une obligation de donner une réponse pour chaque langue. Si vous voulez moins de réponses à votre question, c'est certainement votre prérogative. ;-]
- En demandant des solutions dans C et C++ en fait deux questions différentes, mais avec des thèmes communs. Vous ne sont là que pour poser une question à la fois. J'ai donné une réponse pour le C, mais lorsque j'ai réalisé que la question avait deux balises je l'ai supprimé.
- Ok, eh bien, c'est malheureux, parce que je suis vraiment intéressé par un ou l'autre, PAS les deux (pas de pression). Dans mon code, j'ai tendance à mélanger les deux, en fonction de ce que je ressens est le plus approprié pour la situation par rapport à une approche du tout ou rien, mais je comprends votre point de vue.
- ce n'est pas mon nom, et, comme tel, "@LRiO" ne donne pas lieu à une réponse de notification.
- Les deux absolument ne devrait pas être "mixte" comme ça. Le C et le C++ sont des langues distinctes et doivent être traités comme tels! OK, donc certaines solutions peuvent se chevaucher; beaucoup ne le font pas.
- Des excuses pour ne pas l'orthographe de votre nom (c'est assez long), je ne savais pas que les notifications ont été déclenchés comme ça. Comme pour votre commentaire que les deux ne doivent pas être mélangés comme "ça", je ne suis pas sûr de ce que vous faites allusion, j'ai donné aucun exemple quand j'ai fait cette déclaration. Si vous faites allusion à ma question, je ne peux pas commenter, car je ne sais pas quelles sont les différentes solutions sont et d'où l'absence de chevauchement peut être, d'où le séparer les tags dans ma question.
- mon propre code, j'ai tendance à mélanger les deux"
- Ah, je vois, vous avez été universelle. Eh bien, bon pour vous dans votre strict respect des limites du langage, de respect.
Vous devez vous connecter pour publier un commentaire.
Le premier est un agrégat d'initialiseur - vous pouvez lire et ceux marqués d'initialiseurs à cette solution:
Ce qui est étiqueté structure de la syntaxe d'initialisation?
C'est un spécial syntaxe d'initialisation, et vous ne pouvez pas faire quelque chose de similaire après l'initialisation de votre structure. Ce que vous pouvez faire est de fournir à un membre (ou un non-membre) fonction de prendre votre série de valeurs de paramètres qui vous affectez ensuite à l'intérieur de la fonction de membre - qui vous permettra d'accomplir ce après l'initialisation de la structure d'une manière qui est tout aussi concis (après que vous avez écrit la fonction de la première heure de cours!)
Essayez ceci:
Cela fonctionne si vous avez un bon compilateur (par exemple GCC). Vous devrez peut-être tourner sur C99 mode avec
--std=gnu99
, je ne suis pas sûr.gcc
vous devez spécifier--std=c99
ou plus tard, pour qu'il soit reconnu). Malheureusement, Microsoft a décidé de ne pas soutenir C99 dans le VS suite. Il sera intéressant de voir si ils décident de soutenir C11.En C++11, vous pouvez effectuer l'affectation multiple avec "la cravate" (déclaré dans le tuple en-tête)
Si votre main droite expression est de taille fixe et vous avez seulement besoin d'obtenir certains éléments, vous pouvez utiliser l'ignorer espace réservé avec une cravate
Si vous trouvez la syntaxe std::cravate(f.a, f.b, f.c) code de l'encombrer, vous pourriez avoir un membre de la fonction de renvoi de ce n-uplet de références
Tout cela bien sûr en supposant que la surcharge de l'opérateur d'affectation n'est pas une option parce que votre structure n'est pas constructible par une telle séquence de valeurs, auquel cas on pourrait dire
Si vous ne vous inquiétez pas trop à propos de l'efficacité, vous pouvez doubler attribuer: c'est à dire créer une nouvelle instance de la structure globale de l'initialisation, puis de la copier:
Assurez-vous de garder la partie enveloppée dans {}s afin de jeter l'inutile variable temporaire, dès qu'il n'est plus nécessaire.
Noter que ce n'est pas aussi efficace que la fabrication, par exemple, un " set " de la fonction dans la structure (si c++) ou à l'extérieur de la structure, l'acceptation d'une struct pointeur (si C). Mais si vous avez besoin d'un rapide, de préférence temporaire, alternative à l'écriture de l'élément par élément d'assignation, cela peut faire.
struct Foo foo_new(int bunch, int of, int things, int initialized) { struct Foo tmp = {bunch, of, things, initialized}; return tmp; }; struct Foo foo; foo = foo_new(1, 2, 3, 4);
Le coller dans un fichier d'en-tête commeinline
et l'impact sur les performances devraient être minimes avec l'optimisation. Le seul inconvénient est que vous ne pouvez pas laisser de côté toutes les choses à être remis à zéro à la fin (même si certains ne peut pas considérer que la baisse compte tenu de l'existence de lamissing-field-initializers
avertissement). Bien sûr, la(Foo){...}
style est probablement le plus simple quand il est disponible.Empreinte mémoire - Voici un intéressant i386 plus.
Après beaucoup de tracas, à l'aide de optimisation et memcpy semble générer une plus petite empreinte de l'aide i386 avec GCC et C99. Je suis aide -O3 ici. stdlib semble avoir toutes sortes de plaisir les optimisations du compilateur à la main, et cet exemple fait usage de cette (memcpy est effectivement compilé ici).
Ce faire:
Résultat:
Exemple:
Dire Foo était de 48 champ de structure de u_int8_t valeurs. Il est aligné dans la mémoire.
(IDÉAL) Sur une machine 32 bits, ce POURRAIT être aussi rapide que 12 MOVL instructions immédiates pour foo adresse de l'espace. Pour moi, c'est 12*10 == 120bytes de .texte de taille.
(RÉELLE) Cependant, l'utilisation de la réponse par l'AUTO sera susceptible de générer 48 MOVB instructions .texte. Pour moi, c'est de 48*7 == 336bytes de .le texte!!
(Plus PETIT*) Utiliser le memcpy version ci-dessus. SI l'alignement est pris en charge,
Donc, pour moi, au moins avec mon i386 code,
*Du plus petit signifie ici " plus petite empreinte que je sais du. Il exécute aussi plus rapide que les méthodes ci-dessus (24 instructions vs 48). Bien sûr, l'IDÉAL version est plus rapide & plus petit, mais je n'arrive toujours pas à comprendre cela.
-Justin
*Est-ce que quelqu'un sait comment obtenir la mise en œuvre de la "IDÉAL " ci-dessus? Il est gênant, l'enfer hors de moi!!
Si vous vous souciez de l'efficacité, vous pouvez définir une union de la même longueur que votre structure, avec un type que vous pouvez affecter à la fois.
Pour affecter des valeurs par des éléments d'utiliser la structure de votre union, à céder l'ensemble de données, utilisez l'autre type de votre union.
Être prudent au sujet de votre organisation de la mémoire ("le" le MSB ou LSB de "tout"?).