Les pointeurs: je bloque - C - Programmation
Marsh Posté le 28-10-2007 à 22:34:47
il faut allouer tes entier
soit faire un malloc pour que tes *i *j , soit les déclarer correctement ( i,j )
Marsh Posté le 28-10-2007 à 22:53:54
Pour commencer, n'utilise pas scanf(). Utilise fgets() pour lire une chaîne de caractères, puis convertis-la avec strtol().
La fonction scanf() est une fonction qui pose tout un tas de problèmes lorsqu'on ne sait pas l'utiliser de manière adéquate, ce que peu de programmeurs C savent faire.
Ensuite, pour la première valeur (le nombre d'entiers à entrer), pas d'allocation nécessaire. Un entier tout simple suffit, donc "int i" sera parfait, mais on préfèrera un nom plus parlant que "i" qui désigne traditionnellement une variable jetable d'une boucle for.
Ensuite, il te faudra donc un tableau composé de "i" cases, pour recevoir la liste de nombres entrés par l'utilisateur. C'est là qu'interviennent les pointeurs.
Un pointeur, c'est tout bête, ça ne contient que deux informations :
- l'adresse d'un bloc de données précédemment alloué en mémoire
- le type d'objets que contient le bloc
Tu alloues de la mémoire avec malloc(), calloc() ou realloc(). La taille du bloc alloué est calculé avec la formule toute bête : "nombre_d'elements * taille_d'un_element". Cette taille de bloc, tu dois la conserver quelque part (ici c'est facile, c'est "i" pour le nombre, et la taille d'un élément est connue). Parce que si tu ne la conserves pas, tu n'as aucun moyen de la retrouver.
Ces fonctions d'allocations retournent un pointeur vers le bloc mémoire ainsi réservé (ou NULL en cas de problème).
Et voilà, tu as donc un pointeur qui sert à stocker "i" éléments d'une taille particulière, on va dire ici des "int" pour ton usage. Plus qu'à l'utiliser comme un tableau standard pour accéder aux données.
Lorsque tu as terminé avec ce bloc mémoire, tu dois le libérer : free().
Plus d'infos ici : http://mapage.noos.fr/emdel/notes.htm#pointeurs
Marsh Posté le 28-10-2007 à 23:21:46
Merci à vous deux pour vos réponses rapides.
Malheureusement, j'étudie le C en fac et on nous ne laisse que la possibilité d'utiliser scanf() donc je sais pas s'ils accepteraient un fgets().
Il en est de même pour la fonction malloc.
Il n'empêche que ton lien, Elmoricq, m'a été plus qu'utile afin de voir pourquoi mon programme plantait. A l'avenir je saurai que le mélange de scanf et de \n est mauvais pour la santé du programme.
Je vous remercie tous les deux de m'avoir accordé votre temps.
Marsh Posté le 28-10-2007 à 23:28:13
Ton programme plantait parce que scanf(), avec le pattern que tu lui as indiqué, demande l'adresse d'un entier, et que tu lui as fourni l'adresse d'un pointeur d'entiers.
Et tes profs méritent la pelle à clous pour encore enseigner scanf() à leurs élèves.
Marsh Posté le 28-10-2007 à 23:41:00
Elmoricq a écrit : Ton programme plantait parce que scanf(), avec le pattern que tu lui as indiqué, demande l'adresse d'un entier, et que tu lui as fourni l'adresse d'un pointeur d'entiers. |
Ba en fait tout vient du \n car au début, j'avais pas utilisé de pointeur d'entiers et donc quand je lançais le programme j'avais un joli plantage windows. C'est en voyant le &, qu'on utilise dans le scanf, que j'ai voulu essayer avec les pointeurs et pas de chance j'obtenais le même plantage.
Et c'est avec ton explication que j'ai compris mes erreurs.
Et pour mes profs, je pense qu'ils nous enseignent scanf() pour pas s'embêter avec une conversion strtol().
Mais je veux bien une pelle à clous si t'en as une ^^
Marsh Posté le 29-10-2007 à 08:50:28
non, tes profs enseignent scanf parce qu'ils ont INCOMPETENTS. N'ayons pas peur des mots. La quasi totalité des profs de C (et de C++ ) de la quasi totalité des facs (voire même des ecoles d'ingé) ont appris le C pré-K&R à l'arrache parce qu'ils ne trouvaient pas de larbin pr coder à leur place.
( ofc)
Marsh Posté le 29-10-2007 à 08:57:33
peut etre aussi que c'est pour essayer de simplifier un minimum l'apprentissage
scanf est quand meme plus simple a utiliser que le reste , surtout avec les possibilités de formattage intégrée
faut quand meme pas oublier que le C est souvent un langage d'apprentissage malgré sa complexité, donc ca ne me semble pas choquant de prednre quelques raccourcis pour aller à l'essentiel ( implementation d'un agorithme, structure de données , gestion de la mémoire )
Marsh Posté le 29-10-2007 à 09:03:33
flo850 a écrit : scanf est quand meme plus simple a utiliser que le reste , surtout avec les possibilités de formattage intégrée |
ou pas
Marsh Posté le 29-10-2007 à 09:27:41
flo850 a écrit : peut etre aussi que c'est pour essayer de simplifier un minimum l'apprentissage |
scanf() n'est certainement pas plus simple à enseigner que fgets().
Et lorsque l'on voit ensuite, en milieu professionnel, des fscanf() de 30 lignes écrits par des incompétents ne connaissant aucune alternative, on se met à maudire ces professeurs qui ne font pas correctement leur travail : enseigner les bases.
Et scanf() n'est surement pas une fonction de base, tandis que savoir lire une chaîne de caractères proprement sur un flux et savoir ensuite en convertir les données dans le bon type, si.
Marsh Posté le 29-10-2007 à 09:35:43
Je ne sais pas, mais moi, avant de critiquer je me renseignerais.
Si le but de l'enseignement du cours suivi par le P.O. est l'apprentissage du C, alors oui on peut considérer son prof comme incompétent. Maintenant si ce n'est pas le cas, et je doute que le but d'un cours de fac soit la parfaite connaissance du C, je ne vois pas où est le problème.
scanf est difficile d'accès certe, mais c'est quand même mineur par rapport à l'implantation d'un algo.
Les exigences de fac sont différentes des exigences du monde du travail, certains le regretteront sûrement.
Marsh Posté le 29-10-2007 à 09:39:18
Trap D a écrit : Les exigences de fac sont différentes des exigences du monde du travail, certains le regretteront sûrement. |
C'est vrai que c'est nickel de faire des programmes pour les élèves qui plantent dès que t'appuies sur la mauvaise touche
Marsh Posté le 29-10-2007 à 09:41:55
Trap D a écrit : je doute que le but d'un cours de fac soit la parfaite connaissance du C[...] |
Je trouve que tu te contredis. C'est justement parce que ce n'est pas le but d'un cours de FAC d'enseigner tous les recoins sombres (et puants) du C que ceux-ci ne doivent se focaliser que sur la lecture/écriture de flux, la gestion de la mémoire, la gestion des fichiers sources/en-têtes/bibliothèques, et les quelques bonnes pratiques nécessaires.
Pour le reste, il suffit d'un bouquin ou d'un site internet recensant toutes les fonctions existantes, quand on a les bases, on sait les utiliser.
Par conséquent, scanf() est totalement superflu, et est même une "base" dangereuse à avoir dans ses bagages.
Marsh Posté le 29-10-2007 à 09:43:33
Trap D a écrit : |
Pour etre du milieu, je suis aux premières loges pour constater le niveau abyssal en C
de soit disant prof qui, en 2007 hein, apprennent encore à écrire des void main(), font des trastypage sur le retour
de malloc, ne savent pas différencier for de while dans leur cas d'utilisation, ne jurent que par les variables globales,
pour qui les pointeurs "ca sert pas à grand chose" ...
Marsh Posté le 29-10-2007 à 09:45:14
tu as raison, il vaut mieux decouvrir les structure de données ( arbres, table de hachage ) tout seul
en plus ca simplifie vachement les cours d'algo de ne pas avoir a faire l'implementations de trucs barbares ( matrice creuse par exemple )
Marsh Posté le 29-10-2007 à 09:47:18
flo850 a écrit : tu as raison, il vaut mieux decouvrir les structure de données ( arbres, table de hachage ) tout seul |
cross-post ou tu t'adresses bien à moi ?
Mais, pour rebondir sur la SDD, ca devrait être enseigné de manière décorrélé de tout langage puis
utiliser comme support d'exercice de codage en X Y ou Z. Et pas l'inverse.
Une hash_map en Java, en C et en C++ n'a pas la même geule.
Marsh Posté le 29-10-2007 à 09:48:48
Arbres, tables de hachages et tout le toutim', ce ne sont pas des concepts propres au C.
Ce devrait être enseigné en cours d'algorithmes (c'est d'ailleurs le cas, en tout cas dans mon IUT ça l'était). Les cours de C permettent généralement de se familiariser avec les concepts techniques de compilation, gestion de mémoire, bibliothèques partagées/statiques, debugging, etc.
Il faut bien voir que le niveau moyen de l'étudiant de première année consiste essentiellement à faire un dir en ligne de commandes.
Après ça n'empêche pas de demander des cas pratiques en cours d'algorithme dans un langage enseigné par ailleurs. À l'IUT dans lequel j'étais, les cours d'algorithme et de C étaient "synchronisés" par les profs dans ce but.
Marsh Posté le 29-10-2007 à 09:59:07
Taz a écrit : |
Désolé mais moi ça ne me choque pas, c'est de la technique, pas de la théorie.
Marsh Posté le 29-10-2007 à 10:03:27
Trap D a écrit : Désolé mais moi ça ne me choque pas, c'est de la technique, pas de la théorie. |
Réponse typique.
Marsh Posté le 29-10-2007 à 10:13:35
Oui, et alors ?
Il y a des priorités dans l'enseignement, il y a des priorités dans le monde industriel.
L'enseignant préfèrera un algo bien implanté, même s'il y a des bugs dans la saisie des données (tout au moins c'est ce que je préfèrerais si jj'étais dans cette situation), l'industriel préfèrera je suppose un prog qui ne plante pas, même si l'algo n'est pas le plus efficace possible.
Marsh Posté le 29-10-2007 à 10:15:25
Trap D a écrit : |
La priorité dans l'enseignement c'est de former des gens qui, une fois en entreprise ecrivent pas de la merde pou 65euros/h ...
Marsh Posté le 29-10-2007 à 10:16:29
Si tu le dis ...
Mais AMHA la pire merde est celle qu'on ne voit pas.
La correction d'un problème de saisie est simple, quand le P.O. en aura assez de voir que son programme plante parcequ'il a tapé sur 'a' au lieu de '1', il se posera des questions sur sa méthode de saisie, il utilisera fgets et les fonctions de conversion qui vont bien avec, il trouvera éventuellement la soluce sur le site d'Emmanuel et basta.
S'il a des difficultés à résoudre un problème, à concevoir la formalisation des données, là c'est plus coton à résoudre et c'est là qu'un enseignement est utile.
Marsh Posté le 29-10-2007 à 10:27:39
Trap D a écrit : Oui, et alors ? |
Si t'es pas capable de lire un entier, je vois pas comment aller plus loin.
Marsh Posté le 29-10-2007 à 10:54:57
J"Si t'es pas capable de lire un entier, je vois pas comment aller plus loin."
Ça dépend de la finalité du cours (qu'on ne connait d'ailleurs pas), si c'est apprendre le C, Ok, sinon pour moi, c'est secondaire.
Marsh Posté le 29-10-2007 à 11:22:55
salut, moi j'aurais fait ca:
Code :
|
Marsh Posté le 29-10-2007 à 11:27:42
Le gars qui arrive après la guerre sur "faut pas utiliser scanf()" et qui en fout partout dans un code laid à mourir, des cast sur malloc(), une modification du seul moyen de retrouver le nombre d'éléments stockés dans le tableau, etc.
Marsh Posté le 29-10-2007 à 11:35:57
je veux bien plus de précisons sur l'utilisation du scanf de la bonne maniere (pas en remplacement par fgets)
pour l'utilisation de i, il n'a pas précisé l'utilité de l'enregistrement de x nombre
pour le code laid je veux bien des critiques (c'est le but)
Marsh Posté le 29-10-2007 à 11:47:18
Utilise fgets + sscanf.
Si tu veux faire l'idiot avec scanf:
- regarde le code de retour
- amuse toi bien à purger les caractères à la con
Non, idiot n'est pas le terme. Je devrais dire dément. Les déments qui utilisent scanf finissent toujours par dire "putain ça marche pas, je vais fflush(stdin)"
Pour l'exercice : fais un programme qui doit lire un entier, l'afficher et surtout ne pas planter quand on tape "coin" ...
Marsh Posté le 29-10-2007 à 12:56:02
scanf est pour les dements mais sscanf est pour les semi-dements
Utilise fgets + strtol pour lire un entier
Marsh Posté le 29-10-2007 à 14:07:28
djobidjoba a écrit : salut, moi j'aurais fait ca: |
Oué:
|
Ceci fonctionne :
Code :
|
Press ENTER to continue. |
Pose des questions si tu ne comprends pas...
Evidemment, on peut simplifier en créant des fonctions de saisies...
Marsh Posté le 29-10-2007 à 14:08:21
djobidjoba a écrit : je veux bien plus de précisons sur l'utilisation du scanf de la bonne maniere (pas en remplacement par fgets) |
http://xrenault.developpez.com/tutoriels/c/scanf/
Have fun !
Marsh Posté le 29-10-2007 à 14:11:42
Gruikmusic a écrit : scanf est pour les dements mais sscanf est pour les semi-dements |
Rien à voir... sscanf() ne laisse pas trainer des caractères dans les flux, provoquant une instabilité à la prochaine lecture... Il est trivial de tester la valeur retournée par sscanf() pour savoir si la ou les conversions se sont bien passées. Il est vrai, cependant, que strtol() et ses soeurs, offrent de meilleurs contrôles (débordement, notamment avec errno qui vaut alors ERANGE)
Marsh Posté le 29-10-2007 à 15:10:12
merci pour les explications détaillées:
2 trucs qui m'échappent :
n = scanf ("%d", p + i); équivaut à &p[i] ?
et
free (p), p = NULL; // 2 lignes en 1 ??
Marsh Posté le 29-10-2007 à 15:24:18
djobidjoba a écrit : |
Oui
Citation : |
En quelque sorte, oui.
Marsh Posté le 01-11-2007 à 01:42:50
Code :
|
Etant donné que moins c'est long, plus c'est simple, moins il y a de bug, je me permet de proposer ma solution
Spoiler : Evidemment on ne peut ni retrouver les nombres saisies, ni retrouver leur nombre, mais c'était pas demandé |
Marsh Posté le 02-11-2007 à 01:30:23
Pingumaru a écrit : Bonsoir,
|
ton j est un pointeur sur un entier, quand tu utilises scanf faut faire scanf("%d",j);
j'avais le méme problème sur un programme et ça marchait comme çà.
Marsh Posté le 28-10-2007 à 22:24:17
Bonsoir,
j'essaye de m'entrainer à manipuler les pointeurs en faisant l'exercice suivant:
On souhaite saisir une certaine quantité de nombres entiers, cette quantité doit être donnée par l’utilisateur. Donnez
un programme permettant la saisie de la quantité et celle des entiers.
J'ai réussi à faire ça:
Et lorsque je compile, je n'ai aucun problème, alors qu'en l'éxecutant, le programme me demande de choisir mon nombre d'entiers à entrer, je l'entre, et paf ça plante.
Je sèche totalement sur ce coup là.
Merci