Petit souci avec un petit programme en C, Mais attention je débute (un vrai novice) |
Bienvenue invité ( Connexion | Inscription )
Petit souci avec un petit programme en C, Mais attention je débute (un vrai novice) |
13 Nov 2014, 20:43
Message
#1
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Bonjour
Je vais vous exposer mon souci, mais avant je tiens à vous signaler que je suis un vrai débutant, donc peut-être que mon souci en fera rire plus d'uns, mais comme le ridicule ne tue pas, alors voici ce que je vous expose : Je viens d'écrire ceci sous xcode en mode console : #import <stdio.h> int main () { char c, reponse; c = '*'; int i; entree : for ( i=1; i<=5; i++) printf("%s", &c); printf("\n"); printf("On recommence ?"); scanf("%c", &reponse); if (reponse == 'O' || reponse == 'o') goto entree; } Je vous l'avez bien dit que je débutais. j'en suis à la fonction goto (oui je sais certains me diront de ne pas l'utiliser, mais bon j'apprends) Donc lorsque je lance le programme celui-ci m'affiche bien "*****", mais là ou ça ne va plus c'est au moment de scanf. Quand je réponds "O" ou "o" le programme s'arrête. Pourquoi ? -------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
13 Nov 2014, 22:25
Message
#2
|
|
Terminaltor Moderating Machine Groupe : Admin Messages : 24 449 Inscrit : 25 Oct 2002 Lieu : Jeumont (59) Membre no 4 319 |
Il y a plusieurs problèmes dans ce code :
* Le plus grave : printf("%s", &c); -> va lire une chaîne commençant à l’adresse mémoire de c ; en fonction de ce qu’il y a derrière, ça va afficher n’importe quoi ; au pire, ça ne trouvera pas de '\0' avant une zone protégée, et ça fera core dump ; utiliser à la place printf("%c",c); * Ne pas utiliser goto (surtout pour un cas pareil), préférer un do { } while() ou un while() { } * S’il n’y a pas de flush, le second passage dans "scanf" va lire le caractère de retour qui a été tapé précédemment avec le 'O' ou 'o' ; il faut vider stdin avec quelque chose comme : char ff; while((ff=getchar())!='\n'&&ff!=EOF); Mais de manière générale, scanf c’est moisi… -------------------- I think therefore I Mac
|
|
|
13 Nov 2014, 23:55
Message
#3
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Je te remercie pour ces explications, il va falloir que je décortique tout ça, car pour moi il y a des explications qui me sont incompréhensibles (du moins pour le moment).
-------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
14 Nov 2014, 05:09
Message
#4
|
|
Terminaltor Moderating Machine Groupe : Admin Messages : 24 449 Inscrit : 25 Oct 2002 Lieu : Jeumont (59) Membre no 4 319 |
En gros, le programme correct donne ça :
Code #import <stdio.h> int main() { char c='*', reponse, f; int i; do { for (i=1;i<=5;i++) printf("%c",c); printf("\n"); printf("On recommence ?"); scanf("%c",&reponse); while((f=getchar())!='\n'&&f!=EOF) ; } while(reponse=='O'||reponse=='o'); return 0; } PS : j’ai déplacé le sujet car il n’y a aucun rapport avec la technologie Apple -------------------- I think therefore I Mac
|
|
|
14 Nov 2014, 18:23
Message
#5
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Je te remercie (Je croyais que xCode était une technologie Apple).
J'ai moi aussi effectué une modification (celle-ci radicale), car j'ai aussi employé do...while. Code #import <stdio.h> int main () { char c; c = '*'; int i, ii, r =0; do { for ( i=1; i<=10; i++) printf(" %d", i); printf("\n"); { for (ii=1; ii<=20; ii++) printf("="); printf("=\n\n"); } do { printf("On recommence ?\n"); printf("1 - Oui\n"); printf("2 - Non\n"); printf("Votre choix : "); scanf("%d", &r); } while (r > 2 || r < 1); } while (r == 1); } Et ça marche. -------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
14 Nov 2014, 20:38
Message
#6
|
|
Terminaltor Moderating Machine Groupe : Admin Messages : 24 449 Inscrit : 25 Oct 2002 Lieu : Jeumont (59) Membre no 4 319 |
Le char « c » n’est plus utilisé
La première boucle do … while est une boucle infinie ; si (r > 2 || r < 1) est faux (et donc qu’on sort de la seconde boucle do … while), ça veut dire que r==1, donc tu n’en sortiras jamais. Si le but était vraiment de faire une boucle infinie, il y a plus simple for(;;) { } PS : Xcode n’est pas une technologie, c’est un IDE ( https://fr.wikipedia.org/wiki/Environnement..._développement ) -------------------- I think therefore I Mac
|
|
|
14 Nov 2014, 23:55
Message
#7
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Exact c n'est plus utilisé, j'ai tout simplement oublié de la retirer.
Pourtant lorsque la 1ere boucle se termine, le programme s'arrête et attend une entrée. Donc quand je tape 1 (pour Oui) la boucle recommence. Tandis que quand je tape 2 (pour Non) le programme s'arrête. -------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
15 Nov 2014, 09:41
Message
#8
|
|
Terminaltor Moderating Machine Groupe : Admin Messages : 24 449 Inscrit : 25 Oct 2002 Lieu : Jeumont (59) Membre no 4 319 |
Ah oui, ça veut être 2 aussi, je ne l’ai pas compilé, juste regardé rapidement ^^
dans ce cas, j’aurais fait un for(;;) { [...] if(r==2) break; } pour plus de clarté (mais après c’est une question de goût) -------------------- I think therefore I Mac
|
|
|
15 Nov 2014, 11:47
Message
#9
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 964 Inscrit : 3 Nov 2005 Membre no 49 239 |
un petit conseil en passant:
mettre toujours les {} pour definir les blocs même s'il n'y a qu'une seule instruction. par exemple ton Code for(...) printf(...) devrait s'ecrire Code for (...) { printf(...) ... } |
|
|
16 Nov 2014, 00:20
Message
#10
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Je vous remercie tous les deux pour vos suggestions. Comme quoi j'ai encore pas mal de chemin à faire pour maitriser le C. Mais je suis persévérant.
-------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
16 Nov 2014, 13:20
Message
#11
|
|
Oui ? Groupe : Membres Messages : 3 889 Inscrit : 24 Jun 2003 Lieu : BZH Membre no 8 224 |
J'ai moi même pas mal galéré lors de l'apprentissage du langage C... Pourtant j'étais loin d'être un novice en programmation. Un bouquin qui m'avait vraiment aidé à l'époque s'intitule : "Langage C : les finesses d'un langage redoutable" ISBN : 2200210957 auteur : Jacquelin CHARBONNEL Le titre parle de lui même, il n'est pas réédité, mais tu devrais pouvoir en trouver d'occasion; ce genre de livre ne se jette pas... -------------------- "Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan) |
|
|
16 Nov 2014, 20:16
Message
#12
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Merci pour cette recommandation. Pour ma part j'ai acheté :
Programmer en langage C par Claude Delannoy (5e édition). -------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
17 Nov 2014, 10:31
Message
#13
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 486 Inscrit : 29 Aug 2002 Membre no 3 340 |
Excellent choix !
J'allais fouiller dans mes archives pour retrouver cet auteur... J'ai trouvé son style très didactique, normal pour un prof chercheur Dans un autre genre, utile mais extrêmement pointu (sur les pointeurs) The C Puzzle Book (ISBN-10: 0201604612 / ISBN-13: 978-0201604610) Alan Feuer Des exemples à s'arracher les cheveux. J'en avais déjà soumis un il y a longtemps à Schlum http://forum.macbidouille.com/index.php?sh...p;hl=alan+feuer Du genre: il faut s'intéresser précisément au comportement du pré-processeur, qui ignore le C, il ne fait que pré-processer #define negation(x) -x int y = 5; y = negation(-y); On obtient quoi? y = -(-5) ou --y = 3? Heureusement, les pré-processeurs sont prévisibles aujourd'hui. J-P Ce message a été modifié par Jaypee - 17 Nov 2014, 11:15. |
|
|
17 Nov 2014, 13:10
Message
#14
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Bonjour,
Par moment je m'arrache les cheveux, donc pour le moment je vais rester petit. J'ai bien le temps de grandir. -------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
18 Nov 2014, 04:51
Message
#15
|
|
Terminaltor Moderating Machine Groupe : Admin Messages : 24 449 Inscrit : 25 Oct 2002 Lieu : Jeumont (59) Membre no 4 319 |
Aaaaah, une macro sans variable parenthésée, vade retro
Une petite astuce pour les macros « multi-lignes » : Code #define LIGNES(x) do { <blabla1>; <blabla2>; } while(0) Marchera dans tous les cas genre : Code LIGNES(1);
if(toto) LIGNES(2); else if(titi) { LIGNES(3); <balbla>; } else LIGNES(4); -------------------- I think therefore I Mac
|
|
|
18 Nov 2014, 11:35
Message
#16
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 486 Inscrit : 29 Aug 2002 Membre no 3 340 |
Je dois un peu diluer la sauce pour le bénéfice de PapouMAC :
En C, on peut parfois ne pas utiliser une fonction mais une macro. La macro va fabriquer le code C qui sera ensuite compilé. Par exemple, si on souhaite du code super efficace, minimisant l'accès à la mémoire, et éviter de stocker une variable souvent utilisée, on peut définir la valeur comme une macro: Code #include <stdio.h> #define PI 3.1415 int main (int argc, char* argv[] ) { float rayon = 1.50; float perimetre = 2 * PI * rayon; printf("%f\n", perimetre); } PI n'est pas gardé en mémoire, la pré-compilation (invisible et automatique) fait une substitution globale de PI par sa valeur dans le source. Si on utilise la commande qui fait la pré-compilation ou qui lance le pré-processeur seul cpp, on le voit: Code # 493 "/usr/include/stdio.h" 2 3 4 # 2 "preproc.c" 2 int main (int argc, char* argv[] ) { float rayon = 1.50; float perimetre = 2 * 3.1415 * rayon; printf("%f\n", perimetre); } Ce que Schlum partage généreusement, c'est un truc pour faire une macro plus complexe, sur plusieurs lignes, qui va être acceptée au milieu de n'importe quel code C: - en début de code - au milieu - ou à la fin C'est l'idée d'un bout de code "passe-partout". A quoi ça peut-il servir ? Parfois, dans certain type de code très pointu (un pilote, un driver) le seul moyen de déboguer, c'est d'écrire des traces avec des printf. On peut donc imaginer une macro qui affiche l'état du programme, de ses variables essentielles. Donc on parsème le code de cette macro. Elle doit pouvoir être insérée partout. Une fois le problème débogué, rigoureusement, il faudrait supprimer la macro, mais par paresse ou prévision d'un besoin futur, on pourra redéfinir la macro avec un commentaire englobant sa définition pour ne pas générer les traces dans le code qui ira en production (c'est pas super propre mais c'est une possibilité) Au passage, petite explication sur le piège de la macro sans parenthèses: Autrefois, les pré-compilateurs C, faisant un peu ce qu'ils voulaient, ou alors il fallait préciser leur comportement par une option: Code #include <stdio.h> #define PI 3.1415 #define NEGATION(x) -x int main (int argc, char* argv[] ) { float rayon = 1.50; float perimetre = 2 * PI * rayon; printf("%f\n", NEGATION(-perimetre)); } Et voici ce qu'a produit le pré-processeur, tout va bien, on voit l'espace après le -, mais rien ne l'y obligeait : Code # 2 "preproc.c" 2 int main (int argc, char* argv[] ) { float rayon = 1.50; float perimetre = 2 * 3.1415 * rayon; printf("%f\n", - -perimetre); } Pour conclure, deux bonnes pratiques : - Les MACROS sont écrites en majuscules pour bien rappeler qu'elles ne sont pas des fonctions - Les variables dans la définition à droite, doivent toujours recevoir des parenthèses, c'est une sécurité. Code #define NEGATION(x) -(x) Et le code produit sera sans ambiguité : Code int main (int argc, char* argv[] ) { float rayon = 1.50; float perimetre = 2 * 3.1415 * rayon; printf("%f\n", -(-perimetre)); } Voilà, J-P Ce message a été modifié par Jaypee - 18 Nov 2014, 11:55. |
|
|
18 Nov 2014, 16:22
Message
#17
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
Bonjour
Ouh là là ! Où est l'aspirine SVP ? Enfin, si j'ai bien compris, il vaut mieux utilise #define pour définir une valeur que de la ranger dans une variable. Ce message a été modifié par PapouMAC - 18 Nov 2014, 16:25. -------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
18 Nov 2014, 17:27
Message
#18
|
|
Macbidouilleur d'Or ! Groupe : Membres Messages : 2 486 Inscrit : 29 Aug 2002 Membre no 3 340 |
Si c'est une constante, oui.
Sinon une variable classique est nécessaire pour changer la valeur initiale. J-P |
|
|
18 Nov 2014, 22:31
Message
#19
|
|
Macbidouilleur de bronze ! Groupe : Membres Messages : 336 Inscrit : 25 Sep 2004 Lieu : Occitanie Membre no 24 178 |
J'avais bien saisi que c'était préférable pour une constante.
Et merci à tous pour ces précieux renseignements, qui me font avancer dans la compréhension du langage C. Ce message a été modifié par PapouMAC - 18 Nov 2014, 22:32. -------------------- MAC PRO 2009 (MAC OS 10.14.6) 2 x 3,33 Ghz 6-CoreIntel Xeon(5.1), , 64 Go.Carte graphique NVIDIA GeForce GTX 680.
Mac Studio M2 Max, 32Go, 1To |
|
|
Nous sommes le : 24th April 2024 - 10:01 |