éternel débutant en C pour mon plaisir, je me permets de venir vous
demander quelques éclaircissements sur une situation que je n'arrive pas
à comprendre :
J'utilise le cours en ligne spécial "grand débutant" du "site du zéro" :
<http://www.siteduzero.com/tutoriel-3-14189-apprenez-a-programmer-en-c.html>
Je réalise les exercices du cours dans deux environnements différents :
- sous windows vista avec l'IDE visual C++ 2008 express
- sous linux ubuntu 9.04 avec gcc
J'ai écrit un programme dans le cadre des exercices proposés sur les
tableaux par ce cours en ligne. Le fichier en question peut être
téléchargé ici :
< http://dl.free.fr/to7PFReLM/tableau.c>
Ce qui m'étonne, c'est que j'arrive à compiler sans difficulté ce code
sous Linux, et que le programme se comporte exactement comme je le
souhaite. Par contre, sous Windows, impossible de compiler, l'IDE me
renvoie 42 erreurs et 31 avertissements !!! La plupart des erreurs
semblent être liées aux variables. Par exemple :
"erreur de syntaxe : absence de ';' avant 'type'"
"identificateur non déclaré"
Or, j'ai beau lire et relire mon code, les variables me sembles toutes
déclarées correctement et il ne manque à mon sens pas de ";" en fin
d'instructions. De plus, comme je le disais au début, le même code se
compile sans aucune erreur sous Linux ...
Alors, comment expliquer que deux compilateurs réagissent aussi
différemment, et où et mon erreur ?
Merci par avance du temps que vous pourrez me consacrer,
Mais la question n'est pas là, le pointeur est transparent pour l'utilisateur, c'est tout ce qui compte.
Je ne trouve pas qu'il soit transparent, et tu expliques toi-même pourquoi ci-dessous.
Il suffit jusque que l'utilisateur sache qu'il peut modifier le contenu du tableau passé en paramètre depuis sa fonction, le pourquoi du comment, on s'en fout, dans un premier temps du moins.
Donc c'est pas transparent. Ça crée une règle en apparence arbiraire du genre « on peut pas modifier les paramètres depuis une fonction, sauf si c'est des tableaux ». Si l'utilisateur me ressemble un tant soit peu, au bout de quelques règles arbitraires comme ça, il décrète que le truc (le langage ou le cours, au choix) est un m*rdier incohérent et il décroche.
Il me semblait que t'avais compris la différence qu'il peut y avoir entre une interface et une implémentation, les cordonniers ....
Mauvais exemple. Là, ce qui guide le comportement de l'interface (« on peut modifier les arguments si c'est des tableaux ») est justement l'implémentation. Donc il y a de toutes façon un couplage fort entre les deux dans ce cas précis, contrairement aux grands principes qu'on nous apprend en général. C'est pas forcément une bonne idée au niveau pédagogique que de vouloir nier cette réalité.
-- Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
candide scripsit:
Mais la question n'est pas là, le pointeur est transparent pour
l'utilisateur, c'est tout ce qui compte.
Je ne trouve pas qu'il soit transparent, et tu expliques toi-même
pourquoi ci-dessous.
Il suffit jusque que
l'utilisateur sache qu'il peut modifier le contenu du tableau passé en
paramètre depuis sa fonction, le pourquoi du comment, on s'en fout,
dans un premier temps du moins.
Donc c'est pas transparent. Ça crée une règle en apparence arbiraire du
genre « on peut pas modifier les paramètres depuis une fonction, sauf si
c'est des tableaux ». Si l'utilisateur me ressemble un tant soit peu, au
bout de quelques règles arbitraires comme ça, il décrète que le truc (le
langage ou le cours, au choix) est un m*rdier incohérent et il décroche.
Il me semblait que t'avais compris la
différence qu'il peut y avoir entre une interface et une
implémentation, les cordonniers ....
Mauvais exemple. Là, ce qui guide le comportement de l'interface (« on
peut modifier les arguments si c'est des tableaux ») est justement
l'implémentation. Donc il y a de toutes façon un couplage fort entre les
deux dans ce cas précis, contrairement aux grands principes qu'on nous
apprend en général. C'est pas forcément une bonne idée au niveau
pédagogique que de vouloir nier cette réalité.
--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Mais la question n'est pas là, le pointeur est transparent pour l'utilisateur, c'est tout ce qui compte.
Je ne trouve pas qu'il soit transparent, et tu expliques toi-même pourquoi ci-dessous.
Il suffit jusque que l'utilisateur sache qu'il peut modifier le contenu du tableau passé en paramètre depuis sa fonction, le pourquoi du comment, on s'en fout, dans un premier temps du moins.
Donc c'est pas transparent. Ça crée une règle en apparence arbiraire du genre « on peut pas modifier les paramètres depuis une fonction, sauf si c'est des tableaux ». Si l'utilisateur me ressemble un tant soit peu, au bout de quelques règles arbitraires comme ça, il décrète que le truc (le langage ou le cours, au choix) est un m*rdier incohérent et il décroche.
Il me semblait que t'avais compris la différence qu'il peut y avoir entre une interface et une implémentation, les cordonniers ....
Mauvais exemple. Là, ce qui guide le comportement de l'interface (« on peut modifier les arguments si c'est des tableaux ») est justement l'implémentation. Donc il y a de toutes façon un couplage fort entre les deux dans ce cas précis, contrairement aux grands principes qu'on nous apprend en général. C'est pas forcément une bonne idée au niveau pédagogique que de vouloir nier cette réalité.
-- Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Manuel Pégourié-Gonnard
Marc Espie scripsit:
In article <4aae3487$0$7785$, Stephane Legras-Decussy wrote:
plus simplement j'ai constaté que le débutant est completement perdu à cause de '*' qui dans un cas déclare le pointeur int *p et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a; int *p;
car dans le premier cas 'a' est effectivement un objet de type int que tu peux utiliser directement, alors que dans le deuxième cas, tu dois te farcir l'allocation de mémoire avant de pouvoir considérer que l'expression *p est un truc de type int valide.
Bref, j'ai peut-être tort, mais dans ma tête je préfère me dire qu'il y a effectivement deux opérateurs '*' différents, l'un qui sert à déréférencer et l'autre à construire des types, et que c'est raisonnable de les nommer pareil à cause de l'argument que tu donnes.
-- Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Marc Espie scripsit:
In article <4aae3487$0$7785$426a74cc@news.free.fr>,
Stephane Legras-Decussy <killyourself@yesnocancel.com> wrote:
plus simplement j'ai constaté que le débutant
est completement perdu à cause de '*'
qui dans un cas déclare le pointeur int *p
et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment
tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de
type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a;
int *p;
car dans le premier cas 'a' est effectivement un objet de type int que
tu peux utiliser directement, alors que dans le deuxième cas, tu dois te
farcir l'allocation de mémoire avant de pouvoir considérer que
l'expression *p est un truc de type int valide.
Bref, j'ai peut-être tort, mais dans ma tête je préfère me dire qu'il y
a effectivement deux opérateurs '*' différents, l'un qui sert à
déréférencer et l'autre à construire des types, et que c'est raisonnable
de les nommer pareil à cause de l'argument que tu donnes.
--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
In article <4aae3487$0$7785$, Stephane Legras-Decussy wrote:
plus simplement j'ai constaté que le débutant est completement perdu à cause de '*' qui dans un cas déclare le pointeur int *p et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a; int *p;
car dans le premier cas 'a' est effectivement un objet de type int que tu peux utiliser directement, alors que dans le deuxième cas, tu dois te farcir l'allocation de mémoire avant de pouvoir considérer que l'expression *p est un truc de type int valide.
Bref, j'ai peut-être tort, mais dans ma tête je préfère me dire qu'il y a effectivement deux opérateurs '*' différents, l'un qui sert à déréférencer et l'autre à construire des types, et que c'est raisonnable de les nommer pareil à cause de l'argument que tu donnes.
-- Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Pierre Maurette
Manuel Pégourié-Gonnard, le 14/09/2009 a écrit :
Marc Espie scripsit:
In article <4aae3487$0$7785$, Stephane Legras-Decussy wrote:
plus simplement j'ai constaté que le débutant est completement perdu à cause de '*' qui dans un cas déclare le pointeur int *p et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a; int *p;
car dans le premier cas 'a' est effectivement un objet de type int que tu peux utiliser directement, alors que dans le deuxième cas, tu dois te farcir l'allocation de mémoire avant de pouvoir considérer que l'expression *p est un truc de type int valide.
Bref, j'ai peut-être tort, mais dans ma tête je préfère me dire qu'il y a effectivement deux opérateurs '*' différents, l'un qui sert à déréférencer et l'autre à construire des types, et que c'est raisonnable de les nommer pareil à cause de l'argument que tu donnes.
Je me répète, mais je trouve que:
int a; int* p;
est bien plus clair. En fait impérativement:
int a; int* p = NULL;/* ou int* p = &a; ou int* p = malloc(sizeof *p); */
-- Pierre Maurette
Manuel Pégourié-Gonnard, le 14/09/2009 a écrit :
Marc Espie scripsit:
In article <4aae3487$0$7785$426a74cc@news.free.fr>,
Stephane Legras-Decussy <killyourself@yesnocancel.com> wrote:
plus simplement j'ai constaté que le débutant
est completement perdu à cause de '*'
qui dans un cas déclare le pointeur int *p
et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment
tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de
type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a;
int *p;
car dans le premier cas 'a' est effectivement un objet de type int que
tu peux utiliser directement, alors que dans le deuxième cas, tu dois te
farcir l'allocation de mémoire avant de pouvoir considérer que
l'expression *p est un truc de type int valide.
Bref, j'ai peut-être tort, mais dans ma tête je préfère me dire qu'il y
a effectivement deux opérateurs '*' différents, l'un qui sert à
déréférencer et l'autre à construire des types, et que c'est raisonnable
de les nommer pareil à cause de l'argument que tu donnes.
Je me répète, mais je trouve que:
int a;
int* p;
est bien plus clair. En fait impérativement:
int a;
int* p = NULL;/* ou int* p = &a; ou int* p = malloc(sizeof *p); */
In article <4aae3487$0$7785$, Stephane Legras-Decussy wrote:
plus simplement j'ai constaté que le débutant est completement perdu à cause de '*' qui dans un cas déclare le pointeur int *p et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a; int *p;
car dans le premier cas 'a' est effectivement un objet de type int que tu peux utiliser directement, alors que dans le deuxième cas, tu dois te farcir l'allocation de mémoire avant de pouvoir considérer que l'expression *p est un truc de type int valide.
Bref, j'ai peut-être tort, mais dans ma tête je préfère me dire qu'il y a effectivement deux opérateurs '*' différents, l'un qui sert à déréférencer et l'autre à construire des types, et que c'est raisonnable de les nommer pareil à cause de l'argument que tu donnes.
Je me répète, mais je trouve que:
int a; int* p;
est bien plus clair. En fait impérativement:
int a; int* p = NULL;/* ou int* p = &a; ou int* p = malloc(sizeof *p); */
Ce n'est pas mon avis. Bien sûr si tu parles abstraitement pour décrire des choses abstraites... Je ne crois pas vraiemnt à cette histoire de "faculté d'abstraction" comme si ça existait intrinsèquement.
Moi si, alors essayons de préciser. Ce que tu expliques, c'est que tout n'est pas tout blanc ou tout noir, que (presque) tout le monde est capable de comprendre des concepts qui sont un peu abstraits. Jusque-là on est d'accord mais le constat est un peu banal.
Ce qui est important, c'est la capacité, quand on est confronté à une abstraction /nouvelle/, d'arriver rapidement à la considérer comme quelque chose de naturel, qu'on peut manipuler facilement, et sur quoi on peut alors s'appuyer pour comprendre d'autres choses.
Et cette capacité-là, l'expérience (en tout cas la mienne) montre qu'elle est très variable selon les individus et leur parcours.
-- Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
candide scripsit:
Ce n'est pas mon avis. Bien sûr si tu parles abstraitement pour
décrire des choses abstraites... Je ne crois pas vraiemnt à cette
histoire de "faculté d'abstraction" comme si ça existait
intrinsèquement.
Moi si, alors essayons de préciser. Ce que tu expliques, c'est que tout
n'est pas tout blanc ou tout noir, que (presque) tout le monde est
capable de comprendre des concepts qui sont un peu abstraits. Jusque-là
on est d'accord mais le constat est un peu banal.
Ce qui est important, c'est la capacité, quand on est confronté à une
abstraction /nouvelle/, d'arriver rapidement à la considérer comme
quelque chose de naturel, qu'on peut manipuler facilement, et sur quoi
on peut alors s'appuyer pour comprendre d'autres choses.
Et cette capacité-là, l'expérience (en tout cas la mienne) montre
qu'elle est très variable selon les individus et leur parcours.
--
Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Ce n'est pas mon avis. Bien sûr si tu parles abstraitement pour décrire des choses abstraites... Je ne crois pas vraiemnt à cette histoire de "faculté d'abstraction" comme si ça existait intrinsèquement.
Moi si, alors essayons de préciser. Ce que tu expliques, c'est que tout n'est pas tout blanc ou tout noir, que (presque) tout le monde est capable de comprendre des concepts qui sont un peu abstraits. Jusque-là on est d'accord mais le constat est un peu banal.
Ce qui est important, c'est la capacité, quand on est confronté à une abstraction /nouvelle/, d'arriver rapidement à la considérer comme quelque chose de naturel, qu'on peut manipuler facilement, et sur quoi on peut alors s'appuyer pour comprendre d'autres choses.
Et cette capacité-là, l'expérience (en tout cas la mienne) montre qu'elle est très variable selon les individus et leur parcours.
-- Manuel Pégourié-Gonnard Institut de mathématiques de Jussieu http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/
Pierre Maurette
Richard Delorme, le 14/09/2009 a écrit :
Le 14/09/2009 18:42, Pierre Maurette a écrit :
Je me répète, mais je trouve que:
int a; int* p;
est bien plus clair.
Moi je ne trouve pas.
Entre autre parce que :
int* p, a;
ne déclare pas deux pointeurs.
Oui. Je l'ai déjà noté un "peu plus bas". Règle de style, typedef, etc. Vous ne trouvez pas ça /bien plus clair/ parce que vous le savez, parce que vous êtes expert. Je me situe - et pourtant je ne suis pas enseignant, Dieu m'en préserve - par rapport au débutant. Je dirais "s est un /char étoile/", /char étoile/ est clairement un type (dérivé).
-- Pierre Maurette
Richard Delorme, le 14/09/2009 a écrit :
Le 14/09/2009 18:42, Pierre Maurette a écrit :
Je me répète, mais je trouve que:
int a;
int* p;
est bien plus clair.
Moi je ne trouve pas.
Entre autre parce que :
int* p, a;
ne déclare pas deux pointeurs.
Oui. Je l'ai déjà noté un "peu plus bas". Règle de style, typedef, etc.
Vous ne trouvez pas ça /bien plus clair/ parce que vous le savez, parce
que vous êtes expert. Je me situe - et pourtant je ne suis pas
enseignant, Dieu m'en préserve - par rapport au débutant. Je dirais "s
est un /char étoile/", /char étoile/ est clairement un type (dérivé).
Oui. Je l'ai déjà noté un "peu plus bas". Règle de style, typedef, etc. Vous ne trouvez pas ça /bien plus clair/ parce que vous le savez, parce que vous êtes expert. Je me situe - et pourtant je ne suis pas enseignant, Dieu m'en préserve - par rapport au débutant. Je dirais "s est un /char étoile/", /char étoile/ est clairement un type (dérivé).
In article <4aae3487$0$7785$, Stephane Legras-Decussy wrote:
plus simplement j'ai constaté que le débutant est completement perdu à cause de '*' qui dans un cas déclare le pointeur int *p et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a; int *p;
car dans le premier cas 'a' est effectivement un objet de type int que tu peux utiliser directement, alors que dans le deuxième cas, tu dois te farcir l'allocation de mémoire avant de pouvoir considérer que l'expression *p est un truc de type int valide.
Dans le premier cas ("int a;") tu dois affecter une valeur à "a" avant de pouvoir l'utiliser. Dans le second cas ("int *p;"), tu dois affecter une valeur à "p" avant de pouvoir l'utiliser. Cette affectation peut invoquer une allocation de mémoire ou non. Dans les deux cas, tu dois affecter une valeur à la variable avant de pouvoir l'utiliser.
int a; int* p = NULL; /* du code */ p = &a;
Je n'ai pas affecté de valeur à a avant de l'utiliser.
-- Pierre Maurette
Gabriel Dos Reis, le 14/09/2009 a écrit :
Manuel Pégourié-Gonnard <mpg+news@elzevir.fr> writes:
Marc Espie scripsit:
In article <4aae3487$0$7785$426a74cc@news.free.fr>,
Stephane Legras-Decussy <killyourself@yesnocancel.com> wrote:
plus simplement j'ai constaté que le débutant
est completement perdu à cause de '*'
qui dans un cas déclare le pointeur int *p
et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment
tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de
type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a;
int *p;
car dans le premier cas 'a' est effectivement un objet de type int que
tu peux utiliser directement, alors que dans le deuxième cas, tu dois te
farcir l'allocation de mémoire avant de pouvoir considérer que
l'expression *p est un truc de type int valide.
Dans le premier cas ("int a;") tu dois affecter une valeur à "a"
avant de pouvoir l'utiliser. Dans le second cas ("int *p;"), tu dois
affecter une valeur à "p" avant de pouvoir l'utiliser. Cette
affectation peut invoquer une allocation de mémoire ou non.
Dans les deux cas, tu dois affecter une valeur à la variable avant de
pouvoir l'utiliser.
int a;
int* p = NULL;
/* du code */
p = &a;
Je n'ai pas affecté de valeur à a avant de l'utiliser.
In article <4aae3487$0$7785$, Stephane Legras-Decussy wrote:
plus simplement j'ai constaté que le débutant est completement perdu à cause de '*' qui dans un cas déclare le pointeur int *p et dans l'autre cas est un opérateur a = *p
J'avoue que c'est un truc qui m'a chiffoné un bon moment.
Bof, ca c'est pas un vrai souci, de mon point de vue. Ca depend comment tu expliques. Pour moi, int *p, ca te dit que l'expression *p est de type int. Et donc c'est le meme operateur.
Hum. Il me semble qu'il y a quand même une grande différence entre
int a; int *p;
car dans le premier cas 'a' est effectivement un objet de type int que tu peux utiliser directement, alors que dans le deuxième cas, tu dois te farcir l'allocation de mémoire avant de pouvoir considérer que l'expression *p est un truc de type int valide.
Dans le premier cas ("int a;") tu dois affecter une valeur à "a" avant de pouvoir l'utiliser. Dans le second cas ("int *p;"), tu dois affecter une valeur à "p" avant de pouvoir l'utiliser. Cette affectation peut invoquer une allocation de mémoire ou non. Dans les deux cas, tu dois affecter une valeur à la variable avant de pouvoir l'utiliser.
int a; int* p = NULL; /* du code */ p = &a;
Je n'ai pas affecté de valeur à a avant de l'utiliser.