NewbieContest

Programmation => Langages compilés => Discussion démarrée par: mogg41 le 16 Août 2008 à 23:22:39



Titre: [Résolu] [C++] Problème avec l'élement 0 d'un tableau.
Posté par: mogg41 le 16 Août 2008 à 23:22:39
Bonjour à tous.

En codant un programme pour résoudre l'épreuve nos chères configs, il m'est arrivé un truc étrange avec l'élément 0 d'un tableau d'entier.

Prenons un bout de code tout simple:
Code:
FILE *test = fopen("prix.txt","r");
int RAM[8];
fscanf(test,"%d",RAM[0]);

Lorsque je compile et exécute j'ai le droit à une belle erreur! Alors que le code:
Code:
FILE *test = fopen("prix.txt","r");
int RAM[8];
fscanf(test,"%d",RAM[1])
fonctionne normalement. J'ai donc pensé qu'il n'y avait pas d'élément 0 en C++ (je viens de passer récemment du C au C++) mais j'ai vérifié et il existe bel et bien.

Je vérifie donc avec le bout de code suivant:
Code:
int RAM[8];
RAM[0]=1;
printf("L'element 0 vaut %d.",RAM[0]);
Et j'obtiens bien 1.

J'ai cherché veinement sur google. Je précise que j'utilise windows XP et dev C++. Cela ne m'empêche pas de continuer mon programme mais j'aimerai bien avoir une explication ou un bout de piste.

Merci de votre lecture.

Mogg


Titre: Re : [C++] Problème avec l'élement 0 d'un tableau.
Posté par: Slack le 17 Août 2008 à 00:22:13
Hum, RTFM...
 =)


Titre: Re : [C++] Problème avec l'élement 0 d'un tableau.
Posté par: simpsonmaniac le 17 Août 2008 à 00:55:07
euh je ne suis pas sûr mais il me semble que le nom du tableau correspond à sa première case
Code:
FILE *test = fopen("prix.txt", "r");
int RAM[8];
fscanf(test, "%d", RAM)


Titre: Re : [C++] Problème avec l'élement 0 d'un tableau.
Posté par: sirk390 le 17 Août 2008 à 02:24:42
Oui, les deux sont faux et ce n'est pas en rapport avec l'élément 0 ou 1.

Il faut passer le paramètre par adresse et non par valeur (sinon fscanf ne pourra rien modifier).
Dans ton example tu envoye le contenu (non initialisé) de RAM[0] à fscanf au lieu de l'adresse à laquelle il pourra sauver le résultat (RAM ou &RAM c'est pareil). il faut un int* au lieu d'un int.
Donc pour la première case du tableau ( RAM[0] ) :
Code:
fscanf(test, "%d", RAM)
ou pour la deuxieme  ( RAM[1] )
Code:
fscanf(test, "%d", RAM + 1)


Titre: Re : [C++] Problème avec l'élement 0 d'un tableau.
Posté par: S3cur3D le 17 Août 2008 à 02:41:04
Salut,

Si je ne me trompe pas, tu devrais avoir quelquechose du style "expects int* but type is int".
Donc, c'est un warning et non pas une erreur (ce qui permet à la compilation de continuer son cours).
Comme d'habitude, les messages sont assez explicites. Les fonctions de la famille scanf attendent toujours un pointeur en argument afin de ranger la valeur obtenue à l'adresse pointée. Dans ton cas, tu donnes RAM[0] qui référence directement l'entier se trouvant à l'offset 0. Par conséquent, mettre simplement RAM (qui référence l'adresse de début du tableau) comme dit dans le dernier message devrait supprimer ce message d'avertissement.
Même si tu ne l'as pas vu, le même warning doit sortir pour RAM[1]. Dans ce cas, il faudrait mettre RAM+1 pour supprimer le message, c'est à dire l'adresse du tableau + 1(*sizeof(type du tableau)).
Voilà pour ce message d'avertissement.

Sinon, une remarque générale. Les quotes que tu sors là c'est 100% du C. Pourquoi le compiler en tant que C++ ???
Honnêtement, C et C++ sont deux langages différents, ayant des philosophies différentes et des buts différents.
Le C++ est construit autour de la POO. Ainsi, il existe des classes pour gérer les fichiers (ifstream, ofstream, fstream)  ou encore des objets permettant l'accès direct aux flux standards (cin, cout, ...) ainsi que des opérateurs de manipulation de ces flux. Bref, rien de ce que je vois ici en 3 lignes et que je verrais dans un code C++ ayant le même but.
Ce n'est pas une mauvaise critique (personnellement je préfère beaucoup le C au C++), mais ce code n'est pas du C++, donc compilons-le en C. Ou si du C++ est utilisé ailleurs, faisons tout le code en C++.

Ensuite, pour la question de départ, C++ vient directement du C et, à part quelques anciennes notations excentriques du C, tout ce qui existait en C a perduré en C++, donc les concepts de base comme le départ des tableaux sont identiques. Par contre j'ai en tête plusieurs exemples de codes en C compilant mal en C++ (même si ça n'a rien à voir ici), donc gardons chaque langage et chaque compilateur associé où il se doit ;-)

Voilà j'espère ne pas avoir été trop brouillon et confus dans la réponse comme mon état de fatigue et l'heure le permettraient...

S3cur3D

Edit: Désolé de me faire echo de toi, sirk390, j'étais parti faire autre chose au milieu de l'écriture de ma réponse..


Titre: Re : [C++] Problème avec l'élement 0 d'un tableau.
Posté par: _o_ le 17 Août 2008 à 08:58:22
Je n'ai pas grand chose à ajouter à ce que vient de dire S3cur3d, sinon rappeler deux principes essentiels de la compilation, de mon point de vue :
1) Il faut configurer systématiquement son compilateur en lui demandant d'afficher tous les avertissements (pour gcc et dérivés, c'est le paramètre -Wall).
2) Un code correct ne doit afficher aucun avertissement à la compilation. Les avertissements préviennent de choses qui ne tiennent pas debout. Au mieux, il s'agit de bricolages sans conséquence, mais ce n'est pas propre. Au pire, un avertissement montre une erreur de programmation qui peut finir en crash. Je ne compte plus le nombre de fois où je me suis battu avec un bug idiot, avant de me rendre compte que le compilateur me prévenait depuis le début avec un avertissement d'un truc bizarre.


Titre: Re : [C++] Problème avec l'élement 0 d'un tableau.
Posté par: mogg41 le 17 Août 2008 à 11:49:19
Merci à tous de vos réponses.

Je vais vous répondre dans l'ordre.

@Slack: J'avoue honteusement ne pas avoir été voir la déclaration de la fonction dans la librairie. Non pas par fainéantise mais juste parce que j'avais l'habitude d'utiliser la fonction fscanf de cette manière sans jamais avoir la moindre erreur d'exécution (en C). J'ai donc pensé, à tord, que cela venait d'une particularité du C++ plutôt que d'une erreur de codage de ma part :oops:

@simpsonsmaniac: Effectivement.

@sirk390: Tout me semble plus clair maintenant.

@S3cur3D: Je viens de me mettre au C++ il y a 2-3 jours. J'utilise dans mon programme des fonctions spécifiques au C++ mais je dois avouer qu'elles ne sont pas pour l'instant prédominantes.
J'ai décidé de coder mixte (C et C++). Puis au fur et à mesure d'éliminer les bouts de code en C par leur équivalent C++ afin de finir par coder qu'en C++. Peut être n'est-ce pas la bonne méthode pour passer du C au C++.

@_o_ :1) Je m'en vais ce ce pas configurer correctement mon compilateur.
2) Je sens que les avertissements vont pleuvoir dans tous mes anciens codes.

EDIT: Epreuve validée 1h après avoir lu vos réponses. Merci encore!