11
votes

Est-ce une pratique courante de réutiliser le même nom tampon pour diverses choses en C?

Par exemple, supposons que j'ai un tampon appelé Char Journal_Name [25] que j'utilise pour stocker le nom de la revue. Supposons maintenant quelques lignes plus tard dans le code que je souhaite stocker le nom de quelqu'un dans un tampon. Devrais-je aller char personne_name [25] ou simplement réutiliser le journal_name [25] ?

Le problème est que tout le monde qui lit le code (et moi aussi après quelques semaines) a besoin de comprendre journal_name est maintenant réellement personne_name . .

Mais le contre-argument est que deux tampons augmente l'utilisation de l'espace. Do mieux utiliser un.

Que pensez-vous de ce problème?

Merci, Boda Cydo.


3 commentaires

Idk à propos de commun, en utilisant 50 octets de pile ces jours-ci est assez inoffensif ..


Et si c'est deux fois chemin_max (2x4kb)?


Tout ce qui est sur 64 octets, j'alloque généralement de manière dynamique. Cela étant dit, 8K n'est toujours pas si grand d'une affaire. Vous avez 1 Mo de pile pour les nouveaux threads par défaut. C'est le strict minimum!


7 Réponses :


2
votes

Veuillez utiliser person_name [25] . Aucun corps n'aime fort à lire le code. Cela ne va pas faire beaucoup si quelque chose pour votre programme en termes de mémoire. S'il vous plaît, faites-le simplement la voie lisible.


0 commentaires

2
votes

Vous devriez toujours (bien sauf si vous êtes très em> serré sur la mémoire) aller pour la lisibilité et la maintenabilité lorsque vous écrivez le code pour la même raison que vous avez mentionnée dans votre question.

25 caractères (sauf si est juste un exemple) ne va pas "casser la banque", mais si la mémoire est à une prime, vous pouvez allouer de manière dynamique le stockage pour journal_name code>, puis libérer quand vous avez terminé avec elle avant Allocation de manière dynamique le stockage pour person_name code>. Bien qu'il y ait la "surcharge" du pointeur sur le tableau. P>

Une autre manière serait d'utiliser le scopage local sur les tableaux: P>

void myMethod()
{
    ... some code
    {
        char journal_name[25];
        ... some more code
    }
    ... even more code
    {
        char person_name[25];
        ... yet more code
    }
}


0 commentaires

8
votes

Certains code sont vraiment en ordre ici. Cependant, quelques points à noter:

Gardez l'identifiant découplé de vos objets. Appelez-le ScratchPad ou quoi que ce soit. De plus, par l'apparence de celui-ci, ce réseau de caractères n'est pas alloué de manière dynamique. Ce qui signifie que vous devez allouer un coussinet égratignard suffisant pour pouvoir les réutiliser.

Une approche encore meilleure est de rendre vos fonctions plus courtes: une fonction devrait idéalement faire une chose à la fois. Voyez si vous pouvez rompre et toujours faire face à la question.


5 commentaires

+1, cela aurait été ma réponse aussi. J'aimerais donner un +1 pour le faire une chose à la fois aussi, mais je suis autorisé à ajouter seulement 1 point.


@DACAV: C'est aussi pourquoi je n'ai pas mis la solution d'application de la portée: ce n'est pas une solution dans le sens où vous allociez encore deux tampons et que si vous l'êtes et que vous les mettez dans des étendues séparées, allez-y, ajoutez un couple des lignes et écrivez une fonction! Un avantage direct consiste à écrire des cas de test et des tests ultérieurs devient trivial.


Que diriez-vous de ScratchPad_256B s'il est 256 octets?


@supercat: J'essaie d'éviter toute variation de la notation hongroise. IMHO, la plupart des IDes modernes rendent ce style inutile et personnellement, je trouve que cela jarre.


Je n'utilise généralement pas de types de noms d'identifiant, sauf dans les cas où plusieurs identifiants sont susceptibles d'être distingués en grande partie par type ou dans des scénarios où rien d'autre sur l'identifiant n'indique quel type il en serait. Une variable globale appelée quelque chose comme "ScratchPad" est trop vague et ne donne aucun indice ce qu'il peut tenir.



16
votes

Le moyen de résoudre ce problème, si vous ne voulez vraiment pas gaspiller de mémoire, c'est utiliser des blocs pour mettre en place les tampons:

int main()
{
  {
    char journal_name[26];
    // use journal name
  }
  {
    char person_name[26];
    // use person name 
  }
}


10 commentaires

+1 C'est le moyen de le faire. Mais notez que même sans les scopes, le compilateur peut être suffisamment intelligent pour déterminer que journal_name n'est pas utilisé après un certain point, et il peut donc utiliser le même espace pour person_name . Même avec les étendues, un compilateur peut affecter les deux tampons de toute façon. Il suffit d'écrire un code lisible et ne vous inquiétez pas de "gaspiller" 25 octets sur la pile ici ou là, à moins que vous n'ayez écrit de code pour un système étroitement contraint.


Wow. Est-ce un modèle de programmation Conique C? C'est la première fois que je le vois!


Forcer la portée comme celle-ci est très utile et c'est une honte de nombreuses personnes ne savent pas que c'est possible.


BTW: cela fonctionne aussi dans C aussi (depuis { et } délimit étendue en C aussi)!


Une autre utilisation (très utile) pour déclarer des scopes supplémentaires est avec des relevés de commutation, si vous souhaitez créer des variables à l'intérieur.


Oui, je viens de supprimer la partie C ++, je n'ai pas remarqué que l'OP a dit C.


Le compilateur peut réutiliser les mêmes emplacements de mémoire pour les deux. Il n'est pas tenu de, et si cela ne doit pas dépendre ou non de dépendre des paramètres d'optimisation. (Si cela importe vraiment dans votre application, la façon de savoir sûrement, c'est de jeter un coup d'œil au code généré ...)


Je ne l'ache pas. Ne prenez pas ma parole pour cela, essayez-le. Utilisez 750 * 1024 et 751 * 1024 pour la taille et vérifiez si cela souffle la pile.


{Char B1 [750 * 1024]; Char B2 [751 * 1024]; Sprintf (B1, "% D", 1); Sprintf (B2, "% D", 2);} {CHAR B2 [751 * 1024]; Sprintf (B2, "% D", 2);} accidents. {char b1 [750 * 1024]; sprintf (B1, "% d", 1);} {char b2 [751 * 1024]; sprintf (B2, "% D", 2);} fonctionne bien. Ceci est sous MSVC 10, mode de sortie.


Tant que les tampons sont égaux ou que le tampon est le dernier sur la pile, cette optimisation semble vraiment triviale. Il n'y a aucune raison pour que vous ne vous attendiez pas à ne pas travailler.



1
votes

Si vous êtes inquiet pour la mémoire, et je doute que 25 octets seront un problème, mais vous ne pouvez qu'utiliser simplement MALLOC et gratuit et ensuite vous avez un supplément 4-8 octets utilisés pour le pointeur.

Mais, comme d'autres personnes mentionnées, la lisibilité est importante et que vous voudrez peut-être décomposer votre fonction afin que les deux tampons soient utilisés dans des fonctions qui donnent plus d'indications sur leurs utilisations.

mise à jour:

Maintenant, j'ai eu un tampon appelé tampon que j'utiliserais pour la lecture d'un fichier, par exemple, puis j'utiliserais un pointeur de fonction qui a été transmis, pour analyser les résultats afin que La fonction lit le fichier et le gère de manière appropriée, de sorte que le tampon ne soit pas rempli et je dois ensuite vous rappeler que cela ne devrait pas être écrasé encore.

Donc, encore une réutilisation d'un tampon peut être utile, lors de la lecture des sockets ou des fichiers, mais vous souhaitez localiser l'utilisation de ce tampon sinon vous pouvez avoir des conditions de course.


0 commentaires

3
votes

Si les deux tampons sont automatiques, pourquoi ne pas l'utiliser? La plupart des compilateurs vont gérer cela correctement avec la mémoire réutilisée. Mais vous gardez la lisibilité.

{
    char journal_name[25];
    /*
        Your code which uses journal_name..
    */
}
{
    char person_name[25];
    /*
        Your code which uses person_name...
    */
}


3 commentaires

C'est la première fois que je vois ce modèle de séparation des tampons dans une portée distincte. Où avez-vous appris cela?


ua.linkedin.com/in/romannikitchenko - a réellement joué beaucoup avec l'optimisation du code C. Voici ma présentation de formation d'adieu au bras lorsque j'ai quitté Mindspeed (regardez le profil complet, puis des fichiers i-box). J'ai inclus plusieurs techniques comme celle-ci.


Pouvez-vous partager l'URL s'il vous plaît? Je n'ai pas de compte LinkedIn. :(



4
votes

Au fur et à mesure de la précédente (bonnes) réponses, qu'en est-il de xxx

puis plus tard xxx

serait-ce correct? < / p>


1 commentaires

Je n'aime pas ça. Avoir, dans la même fonction, deux signification différemment des noms pour le même espace mémoire pourraient facilement créer une confusion. Printf ("% s a le journal nommé% s", nom_uname, journal_name); . C'est fait comme s'ils représentent différentes choses.