Meilleure utilisation d'un struct global variable en C
J'ai un mondial var struct:
typedef struct {
int myvar1;
int myvar2;
int myvar3;
...
int myvar10;
} t_myStruct myGlobalData;
Je ne peux pas éviter ce mondial structures, donc je dois l'utiliser.
J'ai trois options pour l'utiliser:
- Utiliser le mondial var "comme est" dans n'importe quelle fonction. I. e.:
int myFunc(void) { myGlobalData.myvar1 = ... myGlobalData.myvar10 = myGlobalData.myvar5 + ... }
- Déclarer un pointeur local et de l'utiliser:
int myFunc(void) { t_myStruct * p; p = &myGlobalData; p->myvar1 = ... ... p->myvar10 = p->myvar5 + ... }
- Utilisation locale de la var et de la copie pour struct global:
int myFunc(void) { t_myStruct localStruct; localStruct.myvar1 = ... localStruct.myvar10 = localStruct.myvar5 + ... myGlobalData = localStruct ; }
Pourrait m'expliquer quel est le meilleur moyen, en général, et pourquoi?
Ils devraient vraiment faire plus facile de mettre le code-blocs entre les puces. Maintenant, je comprends pourquoi l'utilisation de la quote-blocs au lieu de code-blocks.
Merci pour les conseils et le modifier.
vous pouvez également "double tiret" les blocs de code à se joindre à eux pour les éléments de la liste
La troisième option est particulièrement risqué. Avoir deux versions des mêmes données qui datent un peu l'un de l'autre est une recette pour le méchant conditions de course lorsque vous ajouter de la complexité et de plusieurs morceaux de code d'exploitation sur les différentes versions des données.
Votre memcpy copies
Merci pour les conseils et le modifier.
vous pouvez également "double tiret" les blocs de code à se joindre à eux pour les éléments de la liste
La troisième option est particulièrement risqué. Avoir deux versions des mêmes données qui datent un peu l'un de l'autre est une recette pour le méchant conditions de course lorsque vous ajouter de la complexité et de plusieurs morceaux de code d'exploitation sur les différentes versions des données.
Votre memcpy copies
myGlobalData
à localStruct
- est-ce intentionnel!? BTW myGlobalData = localStruct ;
copie d'une struct.OriginalL'auteur Kyrol | 2012-09-18
Vous devez vous connecter pour publier un commentaire.
Choisir plus d'abstraction. Si vous pouvez en modifier les arguments de
myFunc
, puis faire sa signature:Maintenant la fonction elle-même ne dépend pas de l'existence d'une variable globale à tous. Et la même pour toutes les autres fonctions qui en ont besoin pour fonctionner sur un
struct
de ce type. Si vous devez utiliser une variable globale puis isoler l'utilisation de autant que possible, c'est à dire utiliser le mondial en quelques endroits que possible.Si vous ne pouvez pas changer la signature de la fonction, je choisirais l'option de votre question qui est la plus directe: la première. Juste fonctionner directement sur la variable globale.
oui c'est vrai, et lorsque vous utilisez une échelle mondiale, la limite de son utilisation autant que possible
Ok! Message reçu! =)
comme le montre cet exemple, les variables globales peuvent rendre le code difficile à ré-utiliser (si
myFunc
se réfère àglobalData
directement, alors il ne peut pas être utilisé dans le cadre d'un autre programme qui ne définit pasglobalData
). Idéalement, les fonctions et leurs appelants doivent communiquer exclusivement par le biais d'arguments, les valeurs de retour, et les exceptions (le cas échéant); ils ne doivent pas partager l'état par le biais de variables globales. Cela rend plus facile à utiliser de nouveau la fonction dans un autre programme.OriginalL'auteur pb2q
Des trois options que vous avez énumérés, l'OMI, le premier est le meilleur. Juste utiliser avec soin la structure globale.
La première et la deuxième options sont presque identiques, mais à chaque fois que vous commencez à utiliser des pointeurs inutilement les choses deviennent brouillées et les gens ont tendance à faire plus d'erreurs.
La troisième option est une mauvaise idée. Maintenant, vous vous attendez à chaque fonction pour être sûr d'écrire des données lorsqu'ils sont cuits? Que faire si la fonction
A()
et de la fonctionB()
sont à la fois les modifications apportées à la structure globale?A()
remet les données quand c'est fait, alorsB()
termine deuxième et remplaceA()
de données de l'? Maintenant, vous avez besoin d'autres mécanismes de protection en place... juste une mauvaise idée.OriginalL'auteur Mike
Tout d'abord pourquoi est-il si inévitable? Deuxièmement, pourquoi les votre seulement trois options?
Si vous devez accéder à un mondial, de votre première option n'est pas déraisonnable - son déjà mondial, combien pire peut-il obtenir?
Votre deuxième option est inutile.
Votre troisième option a peu de mérite, et le memcpy est inutile, vous pouvez attribuer un struct directement:
Aucune des solutions sont souhaitables dans une application multi-thread.
Si la réponse n'est ni de la ci-dessus. Au lieu de cela, si il n'y a pas vraiment de raison de ne pas le faire, qualifiez-la mondiale,
static
de sorte qu'il est invisible à l'extérieur du module dans lequel elle est définie, puis dans ce même module, le cas échéant, des fonctions d'accès.Même sans la statique de la déclaration, les fonctions d'accès sont une bonne approche, car vous pouvez valider des arguments, de s'assurer de la cohérence des données, appliquer mutuelle-exclusion, si nécessaire, et au cours de débogage, vous pouvez vérifier tous les accès par la mise en pause-points seulement dans l'accès à des fonctions plutôt le partout, l'accès peut se produire autrement.
Vous devriez peut-être lire Une Vérole sur Globals - il se réfère à des systèmes embarqués, mais n'en est pas moins applicable à des applications de bureau.
Merci pour la bonne réponse!
Eh bien, si il a une liaison statique, il n'est pas véritablement mondiale - tant que les seules fonctions déclarées dans la même unité de traduction sont des fonctions d'accès et de toutes les autres fonctions sont situés dans des unités de traduction pour le mondial. Le point est d'utiliser la compilation séparée pour encapsuler et de limiter la visibilité de la variable.
OriginalL'auteur Clifford