web-dev-qa-db-fra.com

Pourquoi mettre des blocs de code C entre accolades?

Je regarde du code C, et j'ai remarqué qu'il est plein de ces accolades entourant des blocs de code sans aucune sorte de structure de contrôle. Jetez un œil:

//do some stuff . . .
fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC);
{
    //a block! why not?
    char *tmp_argv[3];
    tmp_argv[0] = argv[0]; tmp_argv[1] = str; tmp_argv[2] = prefix;
    t = clock();
    fprintf(stderr, "[bwa_index] Convert nucleotide PAC to color PAC... ");
    bwa_pac2cspac(3, tmp_argv);
    fprintf(stderr, "%.2f sec\n", (float)(clock() - t) / CLOCKS_PER_SEC);
}

Pourquoi voudriez-vous insérer des blocs comme celui-ci dans le code? C'est plein à craquer. Y a-t-il une sorte d'avantage de performance? Quelque chose de mystique en C? Pourquoi???

edit: Ce code provient de BWA , un programme de bioinformatique qui aligne de petites séquences à de grandes références en utilisant la transformée de Burrows-Wheeler , au cas où l'un d'entre vous se demanderait. Cet exemple de code n'est pas particulièrement pertinent pour la fonctionnalité de l'application.

61
jergason

Code hérité nécessaire {} pour faire des déclarations

En C89, vous ne pouviez pas simplement faire int i; n'importe où; les déclarations n'étaient valables qu'au début des blocs.

Alors:

a = 1;
int i; /* error */
i = 2;

... n'était pas valide, mais

a = 1
if (e) {
  int i;

... allait bien, tout comme un bloc simple.

Le style résultant a continué même après que les déclarations sont devenues valides (C99) bloc-élément (s), en partie par inertie, en partie pour la portabilité vers l'arrière, et aussi parce qu'il est logique d'établir une portée pour de nouvelles déclarations.

90
DigitalRoss

Pour délimiter des variables. Par exemple. la variable tmp_argv ne sera valide qu'entre les accolades.

38
jldupont

Un autre cas d'utilisation que j'ai découvert récemment est lorsque vous avez une sémantique d'ouverture/fermeture et que vous souhaitez marquer clairement le code `` interne '':

f = fopen('file');
{
    // do stuff
}
fclose(f);

Cela fonctionne bien pour vous rappeler de fermer/libérer des objets et rend le code quelque peu plus propre.

7
Mike Weller

Un bloc est une étendue qui détermine la durée de vie des variables, ainsi que leur visibilité pour le compilateur. Ainsi, les variables qui sont créées dans un bloc disparaissent lorsque le contrôle quitte le bloc.

Cela peut être très pratique lorsque ces variables sont des instances de classes avec des constructeurs et des destructeurs.

Cependant, dans votre exemple, il n'y a pas beaucoup d'avantages.

7
Paul Lalonde

Il crée une portée. Les objets empilés sont détruits lorsqu'ils sortent de leur portée. Il semble qu'il fasse une sorte de frappe, ce qui signifierait que chaque bloc est quelque chose qu'ils voulaient chronométrer. Cependant, je ne vois aucun objet de minuterie de portée, donc, oui, cela n'a aucun sens.

6
i_am_jorf

Les variables que vous déclarez à l'intérieur du bloc sont locales à ce bloc. De cette façon, vous pourrez peut-être redéfinir tmp_argv à un autre endroit de votre code (ci-dessous) sans entrer en conflit avec ce morceau de code.

5
pgb

J'utilise parfois des blocs dans ces cas: - Pour localiser des variables - Ou pour faciliter la lecture ...

1
ltgbau

C'est tout? Peut-être que le programmeur utilise tmp_argv ailleurs dans le code. Je ne peux penser à aucune autre raison depuis le tmp_argv entre le { et } est distinct de tout autre accolade.

1
Jacob