nom de variables

nom de variables - C - Programmation

Marsh Posté le 02-05-2006 à 17:32:16    

Bonjour, je voudrais un petit renseignement, je me doute que c'est juste une question de syntaxe, mais je sèche...  :pt1cable:
Je voudais créer plusieurs variables (bcp en fait) et déclarer par exemple, var1 = 1, var2 = 2, var3 = 3, etc.
mais comme il y en a bcp, je n'ai pas très envie de taper cinquante fois la déclaration.
J'aimerais donc avoir un code du genre:
for(int i = 0; i < nombre; i++)
    int var'valeur_i' = i;
sans utiliser de vecteurs.
Merci d'avance pour votre aide.

Reply

Marsh Posté le 02-05-2006 à 17:32:16   

Reply

Marsh Posté le 02-05-2006 à 17:44:54    

Tableaux.
 
Exemple, avec un tableau à taille fixe :

int values[50];
unsigned i;
 
for (i = 0; i < 50; i++)
{
   values[i] = i;
}


 
 
Exemple bis, avec un tableau de taille inconnue à la compilation :

int *values;
size_t size;
 
size = <calcul que tu veux>;
 
values = malloc(size * sizeof *values);
if ( values != NULL )
{
   unsigned i;
   for(i = 0; i < size; i++)
   {
      values[i] = i;
   }
}
else
{
   fprintf(stderr, "erreur d'allocation machin, gestion bidule\n" );
   return code_erreur;
}
 
/* quand on est sur de ne plus utiliser notre tableau, on libere la memoire */
free(values), values = NULL;

Message cité 1 fois
Message édité par Elmoricq le 02-05-2006 à 17:51:56
Reply

Marsh Posté le 03-05-2006 à 08:51:27    

Citation :

J'aimerais donc avoir un code du genre:
for(int i = 0; i < nombre; i++)
    int var'valeur_i' = i;
sans utiliser de vecteurs.


C ne permet pas ce genre de choses. Mais ce serait de toutes façons une très mauvaise habitude à prendre. Il faut utiliser des tableaux comme te l'a montré Elmoricq.


---------------
TriScale innov
Reply

Marsh Posté le 03-05-2006 à 09:27:17    

Merci pour vos réponses. A bientôt! ;-)

Reply

Marsh Posté le 03-05-2006 à 20:23:42    

Elmoricq a écrit :

int *values;
size_t size;
 
size = <calcul que tu veux>;
 
values = malloc(size * sizeof *values);
if ( values != NULL )
{
   unsigned i;
   for(i = 0; i < size; i++)
   {
      values[i] = i;
   }
}
else
{
   fprintf(stderr, "erreur d'allocation machin, gestion bidule\n" );
   return code_erreur;
}
 
/* quand on est sur de ne plus utiliser notre tableau, on libere la memoire */
free(values), values = NULL;



 
Je conseillerais tester l'erreur plutôt que la réussite

int *values;
size_t size;
unsigned i;
 
size = <calcul que tu veux>;
 
values = malloc(size * sizeof *values);
if ( values == NULL )
{
   fprintf(stderr, "erreur d'allocation machin, gestion bidule\n" );
   return code_erreur;
}
 
// Ici, on est certain que le malloc a réussi
for(i = 0; i < size; i++)
{
      values[i] = i;
}
 
/* quand on est sur de ne plus utiliser notre tableau, on libere la memoire */
free(values), values = NULL;


 
1) ça permet de gérer immédiatement le pb (si t'as une gros code à mettre après le malloc, ça permet de ne pas gérer l'erreur 800 lignes plus loin
2) ça permet de garder l'indentation minimale (ça t'évite de programmer totalement à droite de ton écran quand t'as 50 malloc à faire et à vérifier)

Message cité 1 fois
Message édité par Sve@r le 03-05-2006 à 20:24:15

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 03-05-2006 à 22:41:40    

Sve@r a écrit :

1) ça permet de gérer immédiatement le pb (si t'as une gros code à mettre après le malloc, ça permet de ne pas gérer l'erreur 800 lignes plus loin
2) ça permet de garder l'indentation minimale (ça t'évite de programmer totalement à droite de ton écran quand t'as 50 malloc à faire et à vérifier)


 
Je comprend ces arguments. Le problème, c'est que cette méthode crée des raccourcis dramatiques (goto cachés) qui font que certaines ressources pourraient très bien ne pas être libérées proprement (sockets, threads etc.)
 
Donc, je ne fais pas ça et je préfère traiter
 

Code :
  1. if (ok)
  2. {
  3. }
  4. else
  5. {
  6.    problem();
  7. }


même si il faut supporter quelques imbrications...

Code :
  1. if (ok)
  2. {
  3.    if (ok)
  4.    {
  5.    }
  6.    else
  7.    {
  8.       problem();
  9.    }
  10. }
  11. else
  12. {
  13.    problem();
  14. }


Evidemment il ne faut pas exagérer, et il faut probablement une fonction de plus si besoin est...  
 
Problème de multiplication des appels de fonctions ? Oui, ça peut arriver (surtout en embarqué, pas assez de mémoire auto...).
 
Dans ce cas, il faut chercher un compromis acceptable qui fasse que quii qu'il arrive, les ressources soient correctement libérées.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-05-2006 à 22:51:31    

Emmanuel Delahaye a écrit :

Je comprend ces arguments. Le problème, c'est que cette méthode crée des raccourcis dramatiques (goto cachés) qui font que certaines ressources pourraient très bien ne pas être libérées proprement (sockets, threads etc.)


Je comprends pas trop. Sortir d'une fonction avec "return" avant d'avoir atteint la dernière accolade peut faire que ces ressources automatiquement allouées par la fonction ne seront pas libérées ?


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 03-05-2006 à 23:11:20    

Sve@r a écrit :

Je comprends pas trop. Sortir d'une fonction avec "return" avant d'avoir atteint la dernière accolade peut faire que ces ressources automatiquement allouées par la fonction ne seront pas libérées ?


Oui, tout à fait. Disons, que par rapport à l'écriture naturelle, que génère l'imbrication des phases de 'construction', les raccourcis barbares risquent de brûler des étapes de 'déconstruction' naturelles... Exemple typique (pseudo-code):  
Voilà ce que j'appelle un algorithme 'naturel' :

Code :
  1. {
  2.    FILE *fp_in = fopen(...);
  3.    if (fp_in != NULL)
  4.    {
  5.       FILE *fp_out = fopen(...);
  6.       if (fp_out != NULL)
  7.       {
  8.          /* traitement */
  9.          fclose(fp_out);
  10.       }
  11.       else
  12.       {
  13.          perror();
  14.       }
  15.       fclose(fp_in);
  16.    }
  17.    else
  18.    {
  19.       perror();
  20.    }
  21. }


La plupart des soi-disantes simplifications de ce genre de code que j'ai vues se traduisent par un fichier non fermé, un appel à fclose() avec un NULL etc.

Message cité 1 fois
Message édité par Emmanuel Delahaye le 03-05-2006 à 23:13:17

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 03-05-2006 à 23:15:23    

comme ca par exemple
 

Code :
  1. int f()
  2. {
  3.     int * n;
  4.     FILE * f;
  5.    
  6.     n = malloc(truc());
  7.    
  8.     if( ! n )
  9.         return 1;
  10.    
  11.     f = fopen("truc", "r" );
  12.    
  13.     if( ! f )
  14.     /* erreur courante, la zone mémoire pointee par n n'est pas liberée */
  15.         return 2;
  16.    
  17.     fclose(f);
  18.     free(n);
  19.     return 0;
  20. }


 
 
pour parrer ca on peut aussi faire avec des goto, apres c'est juste une histoire de forme ?
 

Code :
  1. int f()
  2. {
  3.     int * n = NULL;
  4.     FILE * f = NULL;
  5.     int errno = 0;
  6.    
  7.     n = malloc(truc());
  8.    
  9.     if( ! n )
  10.     {
  11.         errno = 1;
  12.         goto end;
  13.     }
  14.    
  15.     f = fopen("truc", "r" );
  16.    
  17.     if( ! f )
  18.     {
  19.         errno = 2;
  20.         goto end;
  21.     }
  22.    
  23. end:
  24.     if( f )
  25.         fclose(f);
  26.     free(n);
  27.     return errno;
  28. }


Message édité par skelter le 03-05-2006 à 23:15:54
Reply

Marsh Posté le 03-05-2006 à 23:26:51    

Emmanuel Delahaye a écrit :

Oui, tout à fait. Disons, que par rapport à l'écriture naturelle, que génère l'imbrication des phases de 'construction', les raccourcis barbares risquent de brûler des étapes de 'déconstruction' naturelles... Exemple typique (pseudo-code):  
Voilà ce que j'appelle un algorithme 'naturel' :

Code :
  1. {
  2.    FILE *fp_in = fopen(...);
  3.    if (fp_in != NULL)
  4.    {
  5.       FILE *fp_out = fopen(...);
  6.       if (fp_out != NULL)
  7.       {
  8.          /* traitement */
  9.          fclose(fp_out);
  10.       }
  11.       else
  12.       {
  13.          perror();
  14.       }
  15.       fclose(fp_in);
  16.    }
  17.    else
  18.    {
  19.       perror();
  20.    }
  21. }


La plupart des soi-disantes simplifications de ce genre de code que j'ai vues se traduisent par un fichier non fermé, un appel à fclose() avec un NULL etc.


 
Délit d'intention. Ma façon d'écrire ce code est toujours ceci :

Code :
  1. {
  2.    FILE *fp_in;
  3.    FILE *fp_out;
  4.    char *buffer;
  5.    fp_in = fopen(...);
  6.    if (fp_in == NULL)
  7.    {
  8.       perror(...);
  9.       return -1;
  10.    }
  11.    
  12.     fp_out = fopen(...);
  13.     if (fp_out == NULL)
  14.     {
  15.         fclose(fp_in);
  16.         perror(...);
  17.         return -1;
  18.     }
  19.      buffer=malloc(...);
  20.      if (buffer == NULL)
  21.      {
  22.         fclose(fp_in);
  23.         fclose(fp_out);
  24.         perror(...);
  25.         return -1;
  26.      }
  27.    
  28.      /* traitement */
  29.      fclose(fp_in);
  30.      fclose(fp_out);
  31.      free(buffer);
  32. }


 
Tu me rassures. Je croyais que c'était le "return" avant terme qui générait un pb alors que le pb dont tu parles ne vient que de la façon d'écrire du programmeur. Evidemment, ma façon d'écrire mêne à une redondance de code (partout où on libère les ressources). Comme quoi, rien n'est jamais parfait...

Message cité 2 fois
Message édité par Sve@r le 03-05-2006 à 23:39:04

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 03-05-2006 à 23:26:51   

Reply

Marsh Posté le 03-05-2006 à 23:58:24    

Sve@r a écrit :

Délit d'intention. Ma façon d'écrire ce code est toujours ceci :


Ce que je fais en 21 lignes, tu le fais en 34  ? (bon OK, je ne retourne pas l'erreur...) Et il a fallu un effort supplémentaire de raisonnement pour placer les libérations de ressources au bon endroit (dont 3 fois fclose(fp_in) !) etc. Je préfère mon algo 'naturel'... Il induit moins d'erreurs. (Je deviens vieux, j'ai plus trop le temps penser aux details, alors ce qui se fait tout seul ça me va.....)

Message cité 2 fois
Message édité par Emmanuel Delahaye le 04-05-2006 à 00:01:18

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 04-05-2006 à 00:18:42    

Emmanuel Delahaye a écrit :

Ce que je fais en 21 lignes, tu le fais en 34  ? (bon OK, je ne retourne pas l'erreur...) Et il a fallu un effort supplémentaire de raisonnement pour placer les libérations de ressources au bon endroit (dont 3 fois fclose(fp_in) !) etc. Je préfère mon algo 'naturel'... Il induit moins d'erreurs. (Je deviens vieux, j'ai plus trop le temps penser aux details, alors ce qui se fait tout seul ça me va.....)


 
passes au c++, raii et gestion d'erreurs par exceptions te soulageront

Reply

Marsh Posté le 04-05-2006 à 01:54:40    

Sve@r a écrit :

Délit d'intention. Ma façon d'écrire ce code est toujours ceci :

Code :
  1. {
  2.    FILE *fp_in;
  3.    FILE *fp_out;
  4.    char *buffer;
  5.    fp_in = fopen(...);
  6.    if (fp_in == NULL)
  7.    {
  8.       perror(...);
  9.       return -1;
  10.    }
  11.    
  12.     fp_out = fopen(...);
  13.     if (fp_out == NULL)
  14.     {
  15.         fclose(fp_in);
  16.         perror(...);
  17.         return -1;
  18.     }
  19.      buffer=malloc(...);
  20.      if (buffer == NULL)
  21.      {
  22.         fclose(fp_in);
  23.         fclose(fp_out);
  24.         perror(...);
  25.         return -1;
  26.      }
  27.    
  28.      /* traitement */
  29.      fclose(fp_in);
  30.      fclose(fp_out);
  31.      free(buffer);
  32. }


 
Tu me rassures. Je croyais que c'était le "return" avant terme qui générait un pb alors que le pb dont tu parles ne vient que de la façon d'écrire du programmeur. Evidemment, ma façon d'écrire mêne à une redondance de code (partout où on libère les ressources). Comme quoi, rien n'est jamais parfait...


 
Je crois que j'ai un set de macro dans un coin qui gère automatiquement le "défaisage du code", le pb c'est qu'elles nécessites de passer 2x le code dans cpp [:pingouino]
 
( bon ca va hein, j'aime bien jouer à aller trop loin avec le C )

Reply

Marsh Posté le 04-05-2006 à 07:10:51    

Emmanuel Delahaye a écrit :

Ce que je fais en 21 lignes, tu le fais en 34  ?


Hum... j'ai un malloc en plus...

Emmanuel Delahaye a écrit :

Je préfère mon algo 'naturel'... Il induit moins d'erreurs. (Je deviens vieux, j'ai plus trop le temps penser aux details, alors ce qui se fait tout seul ça me va.....)


L'important c'est de se sentir bien avec sa façon de coder. Et puis, toi tu connais le C donc tu peux prendre les décisions en toute connaissance. Yobbas débute donc il était bon de lui montrer les différentes possibilités (avec des avantages... et des inconvénients pour chacune)
 

skelter a écrit :

passes au c++, raii et gestion d'erreurs par exceptions te soulageront


 :heink: Tu devrais consulter son site avant de lui conseiller d'apprendre le C++


Message édité par Sve@r le 04-05-2006 à 07:35:21

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed