Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

allocation dynamique d'un pointeur

56 réponses
Avatar
prat
bonjour,

J'ai vu dans un bouquin de cours de langage C sur les pointeurs
l'algorithme suivant:

main( )
{
float * pr1,*pr2,*pr3,somme=3D0;


/*allocation dynamique */
pr1=3Dmalloc(sizeof(float));
pr2=3Dmalloc(sizeof(float));
pr3=3Dmalloc(sizeof(float));

/*saisie*/
printf("Entrez 3 notes: ");
scanf("%f %f %f ",pr1,pr2,pr3);

/*calcul de la somme*/
somme=3D*pr1+ *pr2+ *pr3;

/*calcul de la moyenne*/
printf("Moyenne :%f \n ",somme/3);

/*liberation de la m=E9moire*/
free(pr1);
free(pr2);
free(pr3);

}

Mes questions sont:
-les pointeurs ont =E9t=E9 d=E9clar=E9 initialement =E0 la premi=E8re
instruction,pourquoi en plus une allocation dynamique avec malloc( ) et
free( )?Est-elle n=E9cessaire?
-aurai-je pu utiliser l'allocation dynamique sans avoir au pr=E9alable
d=E9clar=E9 mes pointeurs comme =E0 la premi=E8re instruction?


merci.

10 réponses

1 2 3 4 5
Avatar
Eric Levenez
Le 17/01/07 18:08, dans
, « prat »
a écrit :

bonjour,

J'ai vu dans un bouquin de cours de langage C sur les pointeurs
l'algorithme suivant:

main( )


int main(void)

{
float * pr1,*pr2,*pr3,somme=0;


Horrible de mettre tout sur une ligne

/*allocation dynamique */
pr1=malloc(sizeof(float));
pr2=malloc(sizeof(float));
pr3=malloc(sizeof(float));


Aucun test des codes de retour

/*saisie*/
printf("Entrez 3 notes: ");
scanf("%f %f %f ",pr1,pr2,pr3);


Cette commande est à éviter. Il faut aussi tester son code de retour

/*calcul de la somme*/
somme=*pr1+ *pr2+ *pr3;


Les 3 valeurs ne sont pas forcément initialisées (alors que somme l'a été
pour rien).

/*calcul de la moyenne*/
printf("Moyenne :%f n ",somme/3);

/*liberation de la mémoire*/
free(pr1);
free(pr2);
free(pr3);



Return 0;
}


Donc si tu as trouvé ce code dans un bouquin : poubelle direct.

Mes questions sont:
-les pointeurs ont été déclaré initialement à la première
instruction,pourquoi en plus une allocation dynamique avec malloc( ) et
free( )?Est-elle nécessaire?


Que dit le "cours" ? C'est peut-être sur les pointeurs.

-aurai-je pu utiliser l'allocation dynamique sans avoir au préalable
déclaré mes pointeurs comme à la première instruction?


Tu peux allouer un tableau de float au lieu de faire l'allocation valeur par
valeur. On aurait aussi pu faire un simple une allocation automatique :

float pr1;

et remplacer les "*pr1" par "pr1" et les "pr1" par des "&pr1".

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
ALain Montfranc
Eric Levenez a écrit

Donc si tu as trouvé ce code dans un bouquin : poubelle direct.


Je vous trouve un tantinet intégriste. Essayez de montrer l'utilisation
d'un pointeur à un débutant en commençant direct avec un code 100%
propre va le degouter dans 95% des cas. AMHA il vaut mieux commencer
par du code simpliste puis le critiquer en expliquant ses défauts pour
ensuite aboutir au code propre.

Avatar
Pascal Bourguignon
ALain Montfranc writes:

Eric Levenez a écrit

Donc si tu as trouvé ce code dans un bouquin : poubelle direct.


Je vous trouve un tantinet intégriste. Essayez de montrer
l'utilisation d'un pointeur à un débutant en commençant direct avec un
code 100% propre va le degouter dans 95% des cas. AMHA il vaut mieux
commencer par du code simpliste puis le critiquer en expliquant ses
défauts pour ensuite aboutir au code propre.


Surtout que les défauts sont plus dûs à l'histoire des standards
s'accomodant d'implémentations vaseuses ou d'architectures exotiques
qui n'ont quasiment plus de significations de nos jours.

J'aime bien l'histoire, mais c'est sur que d'un point de vue
pédagogique, on peut commencer par présenter ce qui marche en GNU C
sur X86, et ensuite mentionner que le standard ne garanti pas
certaines choses.


--
__Pascal Bourguignon__ http://www.informatimago.com/

"You can tell the Lisp programmers. They have pockets full of punch
cards with close parentheses on them." --> http://tinyurl.com/8ubpf


Avatar
Bruno Desthuilliers
bonjour,

J'ai vu dans un bouquin de cours de langage C sur les pointeurs
l'algorithme suivant:

main( )


Bon. Tu peux d'ors et déjà jeter le bouquin (ou caler une armoire avec,
ou t'en servir à d'autres fins si le papier est adéquat...)

C'est:

int main(void) /* au minimum */

ou

int main(int argc, char **argv)

Et de préférence précédé de:
#include <stdlib.h> /* malloc etc*/
#include <stdio.h> /* printf etc */

{
float * pr1,*pr2,*pr3,somme=0;


/*allocation dynamique */
pr1=malloc(sizeof(float));


pr1 = malloc(sizeof *pr1); // cf les FAQ (f)clc
if (pr1 == NULL) {
/* gérer l'erreur ici */
}
pr2=malloc(sizeof(float));
pr3=malloc(sizeof(float));


/* idem */

/*saisie*/
printf("Entrez 3 notes: ");
scanf("%f %f %f ",pr1,pr2,pr3);


cf les FAQ (f)clcl

/*calcul de la somme*/
somme=*pr1+ *pr2+ *pr3;

/*calcul de la moyenne*/
printf("Moyenne :%f n ",somme/3);

/*liberation de la mémoire*/
free(pr1);
/* suivi de : */

pr1 = NULL;
free(pr2);
free(pr3);
/* idem */


/*et il manque:*/
return EXIT_SUCCESS;
}

Mes questions sont:
-les pointeurs ont été déclaré initialement à la première
instruction,pourquoi en plus une allocation dynamique avec malloc( ) et
free( )?Est-elle nécessaire?


Ca dépend de ce que tu veux faire. En l'occurrence, je ne vois pas de
besoin pour dans le code (pourri) en question. Mais es-tu sûr d'avoir
compris les notions de pointeur et d'allocation dynamique ?

-aurai-je pu utiliser l'allocation dynamique sans avoir au préalable
déclaré mes pointeurs comme à la première instruction?


Techniquement, oui, mais ce serait d'une parfaite stupidité.


merci.

De rien. Puis-je te recommander d'investir dans le K&R2 ? Pour ce que ça

vaut, c'est un des rares (<= 5) bouquins d'informatiques que je n'ai
pas utilisé à d'autres fins à ce jour...

HTH

Avatar
Pascal Bourguignon
Bruno Desthuilliers writes:

bonjour,

J'ai vu dans un bouquin de cours de langage C sur les pointeurs
l'algorithme suivant:

main( )


Bon. Tu peux d'ors et déjà jeter le bouquin (ou caler une armoire
avec, ou t'en servir à d'autres fins si le papier est adéquat...)

C'est:

int main(void) /* au minimum */

ou

int main(int argc, char **argv)


Ça dépend du standard. En K&R, main() est parfaitement bon: ça
retourne un int par défaut, et ça accepte un nombre quelconque
d'argument.

Mes questions sont:
-les pointeurs ont été déclaré initialement à la première
instruction,pourquoi en plus une allocation dynamique avec malloc( ) et
free( )?Est-elle nécessaire?


Ca dépend de ce que tu veux faire. En l'occurrence, je ne vois pas de
besoin pour dans le code (pourri) en question. Mais es-tu sûr d'avoir
compris les notions de pointeur et d'allocation dynamique ?


Bonne question. La réponse à apporter serait que déclarer un pointeur
ne l'initialise pas! Il peut pointer n'importe où, et même être
invalide.

Si on ne l'initialise pas avec une adresse (soit obtenue par malloc,
soit prise par l'opérateur unaire &), ça peut planter si on le
déréférence.




-aurai-je pu utiliser l'allocation dynamique sans avoir au préalable
déclaré mes pointeurs comme à la première instruction?



On pourrait écrire:

float *pr1=malloc(sizeof(*pr1));
float *pr2=malloc(sizeof(*pr2));
float *pr3=malloc(sizeof(*pr3));
...


--
__Pascal Bourguignon__ http://www.informatimago.com/

THIS IS A 100% MATTER PRODUCT: In the unlikely event that this
merchandise should contact antimatter in any form, a catastrophic
explosion will result.


Avatar
Bruno Desthuilliers
Eric Levenez a écrit

Donc si tu as trouvé ce code dans un bouquin : poubelle direct.



Je vous trouve un tantinet intégriste.


Non, il a tout à fait raison.

Essayez de montrer l'utilisation
d'un pointeur à un débutant en commençant direct avec un code 100%
propre va le degouter dans 95% des cas.


Ah bon ? Pourquoi ça ? En quoi est-il plus difficile d'écrire un code
propre (surtout sur un exemple aussi crétinesque...) ? En ce qui me
concerne, je ne fais pas confiance à quelqu'un qui ne connait
manifestement pas son sujet, et c'est clairement le cas ici. Dans
d'autres langages de plus haut niveau, ça résulte au pire sur un
programme buggué et une perte de temps (pour le lecteur), mais en C, il
n'y a pas de place pour l'amateurisme (à moins d'être prêt à toutes
sortes de résultats aussis imprévisibles et déplaisants que possible...).

AMHA il vaut mieux commencer par
du code simpliste puis le critiquer en expliquant ses défauts pour
ensuite aboutir au code propre.



100% stupide. Il est bien évidemment préférable de commencer par du code
simple (!- simpliste) *et* propre. *Surtout* pour un débutant.


Avatar
Pierre Maurette
bonjour,

J'ai vu dans un bouquin de cours de langage C sur les pointeurs
l'algorithme suivant:

main( )
{
float * pr1,*pr2,*pr3,somme=0;


/*allocation dynamique */
pr1=malloc(sizeof(float));
pr2=malloc(sizeof(float));
pr3=malloc(sizeof(float));

/*saisie*/
printf("Entrez 3 notes: ");
scanf("%f %f %f ",pr1,pr2,pr3);

/*calcul de la somme*/
somme=*pr1+ *pr2+ *pr3;

/*calcul de la moyenne*/
printf("Moyenne :%f n ",somme/3);

/*liberation de la mémoire*/
free(pr1);
free(pr2);
free(pr3);

}

Mes questions sont:
-les pointeurs ont été déclaré initialement à la première
instruction,pourquoi en plus une allocation dynamique avec malloc( ) et
free( )?Est-elle nécessaire?


Il s'agit de toute évidence d'un code qui se veut pédagogique. Tel
qu'il est le programme est débile. Mais s'il s'agit d'introduire les
pointeurs étape par étape, pourquoi pas. Si par exemple l'étape
suivante est de demander d'abord le nombre de float desquels on veut la
somme et la moyenne. Mais même dans ce cas-là, l'allocation dynamique
ne s'impose pas. Ce qui à mon avis est le signe d'une approche
pédagogique douteuse. Mauvaise opinion confortée par un main() pas très
standard.
Pour expliquer l'allocation dynamique, il me semble qu'il faut la
rendre nécessaire. C'est un peu comme en programmation objet, je crains
de n'avoir jamais à dériver des chats et des chiens d'animaux, puis des
angoras et de gouttières de chats.

-aurai-je pu utiliser l'allocation dynamique sans avoir au préalable
déclaré mes pointeurs comme à la première instruction?


Oui. Mais en C (pré99 en tous cas), il faut tout faire en début de
fonction. Vous auriez pu écrire:
float* pr1=malloc(sizeof(float));
float* pr2=malloc(sizeof(float));
float* pr3=malloc(sizeof(float));

Bien sûr, c'est pas bien. La forme normale est:
float* pr1 = NULL;
/* blah */
if((pr1 = malloc(sizeof *pr1)) == NULL)
{/* blah */}
else
{/* blah */}



--
Pierre Maurette

Avatar
Pierre Maurette
[...]
Il ne faut pas confondre du code simpliste avec du mauvais code.


On peut avoir du code débile justifié par une progression pédagogique.
Si on n'a pas à disposition le fil du chapitre, on peut être
injustement négatif sur le bout de code proposé.
D'un coté, il y a sur ce groupe moribond un plaisir pervers à critiquer
toute tentative un peu imparfaite. D'un autre coté, même (et surtout)
dans un ouvrage de niveau zéro je n'aurais pas osé proposer le code de
l'OP.

--
Pierre Maurette

Avatar
Pierre Maurette
[...]

Voilà, soyons gentil


Ben oui. Si on souhaite un futur à fr.comp.lang.c, il vaut mieux...

--
Pierre Maurette

Avatar
Marc Boyer
Bruno Desthuilliers a écrit :
int main(void) /* au minimum */

ou

int main(int argc, char **argv)


Ben non. Il me semble bien que
int main()
est tout à fait correct. Le void ne sert que s'il s'agit
d'une déclaration de fonction, mais lors de la définition,
cela ne donne pas d'ambiguïté.

Marc Boyer
--
Si tu peux supporter d'entendre tes paroles
Travesties par des gueux pour exciter des sots
IF -- Rudyard Kipling (Trad. André Maurois)

1 2 3 4 5