OVH Cloud OVH Cloud

passer un tableau à une fonction

99 réponses
Avatar
Carmin
Bonjour,

j'apprends C++, et je suis confronté à ce pb : passer un tableau à une
fonction, voilà un code sans utilité mais qui permet de mettre mon pb en
avant : je reçois le message d'erreur suivant: Unresolved external
'ChangerVal(int)' referenced from module prog1.cpp
#include <iostream.h>
#include <conio.h>

void ChangerVal(int);

main()
{
int tab[2];
tab[0]=tab[1]=0;

ChangerVal(tab[2]);
for (int i=0; i<=1; i++)
{cout << tab[i]<<endl;}
getch();
}

void ChangerVal(int tab[2])
{
tab[0]=5;
tab[1]=10;
}
merci de votre aide

10 réponses

Avatar
M.B.
"Jonathan Mcdougall" a écrit dans le message
news: fkFeb.104903$
Que ce soit la pile ou un registre specialisé dans un processeur
particulier, ca ne change rien.

Mon propos est de dire qu'il vaut mieux connaitre ces mecanismes,
ca aide a comprendre certains effets pervers de programmes en phase
de debug.


Et le mien était de dire que ton assertion « Les arguments des
fonctions passent TOUJOURS par la pile. Je suis surpris qu'un
programmeur C++ ne sache pas ca » est fausse.


Tu joues sur les mots.


Peut-être, mais sur un mot écris en MAJUSCULE. Disons que ça attire
un peu plus l'attention des gens. Surtout quand c'est faux.



Non c'est pas faux. Une pile ou une serie de registres speciaux,
c'est du pareil au meme.

MB




Avatar
Loïc Joly
M.B. wrote:

"Jonathan Mcdougall" a écrit dans le message
news: IxEeb.104890$

Connaitre la machine a ajourd'hui (et heureusement) beaucoup moins
d'importance qu'avant. Le décalage est d'après moi un très mauvais
exemple de "savoir programmer avec la connaissance de la machine
qu'on programme". Et je n'arrive pas à en trouver de bons.




Et quand tu as un bug 'Stack Overflow', tu fais quoi si tu
ne sais pas ce qu'est une 'stack' ?


Je traduit ça par : Ya trop de variables locales à des fonctions qui
s'appellent les unes les autres (possibilité de récurssivité mal bornée
?). On dépasse la taille d'une zone mémoire. Je n'ai nullelment besoin
de savoir pourquoi cette zone se nomme stack ou comment elle est
typiquement utilisée.


Et tu expliques comment a des etudiants que le passage d'argument
par adresse ou par valeur ?


Très simplement comme je l'ai appris :

Un passage par valeur fait que la fonction utilise une copie de la
valeur, et donc peut la modifier, mais ça n'impactera pas le code appelant.

Un passage par référence fait que la fonction voit directement la
variable du code appelant (d'où nécessité que ce soit une variable, et
pas une expression)

Un passage par référence à une constante, c'est pareil, sauf que comme
la fonction promet de ne pas modifier, on peut aussi lui passer le
résultat d'une expression, le compilo se dédrouille.


Je ne voit nullement dans cette explication la notion de pile. Je n'ai
moi même vu cette notion que quelques années après avoir compris ça.




Je pense qu'on a tous besoin pour bien maitriser une abstraction d'avoir
une image de ce sur quoi elle est bâtie. Ce qui varie, c'est le nombre
de récursion à faire avant que notre esprit soit satisfait.

Ainsi, il semble que tu ais besoin de remonter jusqu'au niveau d'une
pseudo-architecture de machine pour comprendre et enseigner le C++.

Pour ma part, je remarque souvent que quand je réfléchit à comment
fonctionne un truc en C++, je remonte assez souvent à un pseudo-langage
uniquement procédural à la C ou à la Pascal (par exemple, la notion de
fonction virtuelle est assez proche de celle de pointeur de fonction
dans ma tê^te).

Que l'on travaille avec de telles analogies ne me choque pas. Ce qui me
gêne plus est de vouloir imposer ces analogies qui nous ont aidées (en
fonction entre autre de notre historique) à des gens pour qui elles
risquent d'être un frein.

Ainsi, quand je dois expliquer une fonction virtuelle, je ne parle de
tableau de pointeur de fonctions que si je vois que l'explication que
j'ai donnée en restant au niveau d'abstraction nécessaire pose des
problèmes, et que la personne est familière du domaine de l'analogie
(ici, le C). Autrement, ou en cas d'échec de l'analogie précédente, je
choisirais une autre analogie avec un autre domaine.

--
Loïc


Avatar
M.B.
"Loïc Joly" a écrit dans le message news:
blf7n9$g3p$
M.B. wrote:


Et quand tu as un bug 'Stack Overflow', tu fais quoi si tu
ne sais pas ce qu'est une 'stack' ?


Je traduit ça par : Ya trop de variables locales à des fonctions qui
s'appellent les unes les autres (possibilité de récurssivité mal bornée
?). On dépasse la taille d'une zone mémoire. Je n'ai nullelment besoin
de savoir pourquoi cette zone se nomme stack ou comment elle est
typiquement utilisée.



Et on revient au poste d'origine. Il faut savoir ce qu'est une zone
memoire, donc un tableau.

Donc int tab[2] plus simple que std::vector<int> Tab (2)

CQFD



Et tu expliques comment a des etudiants que le passage d'argument
par adresse ou par valeur ?


Très simplement comme je l'ai appris :

Un passage par valeur fait que la fonction utilise une copie de la
valeur, et donc peut la modifier, mais ça n'impactera pas le code
appelant.


Un passage par référence fait que la fonction voit directement la
variable du code appelant (d'où nécessité que ce soit une variable, et
pas une expression)

Un passage par référence à une constante, c'est pareil, sauf que comme
la fonction promet de ne pas modifier, on peut aussi lui passer le
résultat d'une expression, le compilo se dédrouille.



Ca fait que ... Ca fait que ...

Si tu as des etudiants satisfaits avec ce genre de reponse, tu
as bien de la chance.

MB


Avatar
Jonathan Mcdougall
Et quand tu as un bug 'Stack Overflow', tu fais quoi si tu
ne sais pas ce qu'est une 'stack' ?


Je traduit ça par : Ya trop de variables locales à des fonctions qui
s'appellent les unes les autres (possibilité de récurssivité mal bornée
?). On dépasse la taille d'une zone mémoire. Je n'ai nullelment besoin
de savoir pourquoi cette zone se nomme stack ou comment elle est
typiquement utilisée.



Et on revient au poste d'origine. Il faut savoir ce qu'est une zone
memoire, donc un tableau.

Donc int tab[2] plus simple que std::vector<int> Tab (2)

CQFD


Woaa, je n'ai pas suivis ton résonnement.

Et tu expliques comment a des etudiants que le passage d'argument
par adresse ou par valeur ?


Très simplement comme je l'ai appris :

Un passage par valeur fait que la fonction utilise une copie de la
valeur, et donc peut la modifier, mais ça n'impactera pas le code
appelant.


Un passage par référence fait que la fonction voit directement la
variable du code appelant (d'où nécessité que ce soit une variable, et
pas une expression)

Un passage par référence à une constante, c'est pareil, sauf que comme
la fonction promet de ne pas modifier, on peut aussi lui passer le
résultat d'une expression, le compilo se dédrouille.



Ca fait que ... Ca fait que ...

Si tu as des etudiants satisfaits avec ce genre de reponse, tu
as bien de la chance.


Si tu expliques le fonctionnement interne d'un ordi à un étudiant qui
commence à apprendre la programmation, ils n'ont pas beaucoup de chance.


Jonathan



Avatar
M.B.
"Jonathan Mcdougall" a écrit dans le message
news: YxFeb.104905$

Si tu expliques le fonctionnement interne d'un ordi à un étudiant qui
commence à apprendre la programmation, ils n'ont pas beaucoup de chance.



J'ai deja repondu. Essaye et en rediscutera.

MB

Avatar
Michaël Monerau
wrote:
"Michaël Monerau" wrote in message
news:<tJgeb.200085$...
wrote:
L'auteur de la question initiale a repondu en disant 'merci' la ou
il fallait.


Tu veux dire : après l'explication erronée ?


Explication erronnée ? Si j'ai fait une erreur, je suis tout ouïe ;-)


Je l'ai signalé cependant dans ma réponse à ton posting.

Je ne doute pas que tu saches comment les choses se passent en vérité,
mais ce que tu as écrit en guise de simplification était bel et bien
faux. Et à mon avis, c'était une simplification qui n'en était pas
une, parce qu'elle laissait des mécompréhensions qui poserait d'autres
problèmes à l'avenir.


Oui oui, excuse moi. J'avais annulé le message, mais ça n'a pas semblé
marché. J'avais mal compris ton assertion...

;-)
--
<=- Michaël "Cortex" Monerau -=>




Avatar
Jonathan Mcdougall
Si tu expliques le fonctionnement interne d'un ordi à un étudiant qui
commence à apprendre la programmation, ils n'ont pas beaucoup de chance.



J'ai deja repondu. Essaye et en rediscutera.


Désolé, je n'avais pas suivi tout le fil de discussion.

Je n'ai personellement jamais enseigné au sens large, mais j'ai souvent
servi de "tuteur" personnel. Je suis aussi assez jeune pour me souvenir
des cours que j'ai suivis.

Dans un cours en particulier, j'étais en compagnie de gens qui n'avaient
jamais touché à un ordinateur, tandis que d'autres (dont moi) avaient
pas mal de connaissances en programmation. L'introduction au C++ a été
particulièrement pénible pour ces gens, car la première notion importante
vue était les pointeurs, accompagné de grandes tirades sur l'architecture
des ordinateurs modernes, les addresses, la mémoire et tout le blabla.
Je crois que les étudiants devaient avoir mal aux yeux tellement ils
étaient ronds.

Pour reprendre un peu ce que Christophe disait, certaines connaissances
sont des cercles vicieux : il faut en comprendre une pour comprendre
l'autre et vice-versa. Je crois qu'il faut trancher en essayant
d'expliquer celles qui ont le moins de pré-requis. Expliquer les
deux à la fois est du suicide.

Le problème vient aussi du fait que les étudiants manquent d'intérêt
lorsque les explications concernent une notion dont ils ne voient
pas l'application. Pour reprendre l'exemple du tableau vs. vector,
pour comprendre le tableau, ils doivent comprendre le fonctionnement
de la mémoire. Mais pour être intéressés au fonctionnement de la
mémoire, ils doivent avoir vu les tableau.

Par contre, lorsque le vector est bien compris (ce qui n'est pas
compliqué), les étudiants ont moins de difficulté à comprendre
les _rudiments_ des tableaux, rendant possible l'explication de
la mémoire et ensuite la maitrise des tableaux.


Je n'ai jamais dis que la conaissance du fonctionnement interne d'un
ordinateur n'était plus nécessaire à la programmation moderne. J'ai
seulement dis qu'elle l'était beaucoup moins. Pour les notions de bas
niveau d'un langage, il faut comprendre son effet sur l'ordinateur pour
bien l'utiliser. memcpy() en est un bon exemple.


Jonathan


Avatar
Loïc Joly
M.B. wrote:

"Loïc Joly" a écrit dans le message news:
blf7n9$g3p$

M.B. wrote:


Et quand tu as un bug 'Stack Overflow', tu fais quoi si tu
ne sais pas ce qu'est une 'stack' ?


Je traduit ça par : Ya trop de variables locales à des fonctions qui
s'appellent les unes les autres (possibilité de récurssivité mal bornée
?). On dépasse la taille d'une zone mémoire. Je n'ai nullelment besoin
de savoir pourquoi cette zone se nomme stack ou comment elle est
typiquement utilisée.




Et on revient au poste d'origine. Il faut savoir ce qu'est une zone
memoire,


Oui

donc un tableau.


Non, quel rapport ?

Une mémoire, c'est juste un endroit de taille finie où on peut écrire et
lire de l'information.

Un tableau (de type C), ça demande outre la notion de mémoire, les
notions de pointeur, arithmétique de pointeur, liens entre tableaux et
pointeurs et peut-être même padding.


Un passage par référence fait que la fonction voit directement la
variable du code appelant (d'où nécessité que ce soit une variable, et
pas une expression)

Un passage par référence à une constante, c'est pareil, sauf que comme
la fonction promet de ne pas modifier, on peut aussi lui passer le
résultat d'une expression, le compilo se dédrouille.




Ca fait que ... Ca fait que ...

Si tu as des etudiants satisfaits avec ce genre de reponse, tu
as bien de la chance.


Peux-tu toi me dire comment tu l'expliquerais à quelqu'un nouveau à la
programmation ?

Quand on apprend quelquechose, il faut admettre de ne pas tout comprendre.

Je ne pense pas qu'on t'ai expliqué Peano quand on t'as enseigné
l'addition, alors que c'est pourtant fondamental. Apprend-t-on mieux
l'anglais en faisant de la linguistique et de la grammaire, ou en
passant un mois en Angleterre ?

Tu vas encore dire que ça n'a aucun rapport, pourtant le problème est
bien là : Tu estimes qu'il FAUT descendre au niveau d'abstraction d'une
architecture simplifiée d'ordinateur pour apprendre une notion aussi
simple que le passage de paramètres à une fonction (que je répète j'ai
appris sans problèmes et sans ça), mais tu estimes que c'est LE niveau
qu'il faut, et que descendre plus bas (ou pas aussi bas), c'est aller
trop (ou pas assez) loin.

Tant que tu ne m'auras pas expliqué en quoi ce niveau d'abstraction est
auto-suffisant (par rapport au niveau de comment marche la mémoire, le
transistor, les électrons...), j'aurais du mal à penser que ce
raisonnement a vraiment de la valeur.

--
Loïc



Avatar
Gabriel Dos Reis
"M.B." writes:

| Ce qui est surprenant c'est la constante et consternante niaiserie
| de tes reponses.

bel auto-portrait.

-- Gaby
Avatar
Michel Michaud
Dans news:bl9g97$f87$,
Ca tombe bien, j'ai 18 annees d'experience d'enseignement.


J'en ai un peu plus.

On ne peut pas apprendre un langage informatique sans le comprendre,
c'est ridicule et grotesque.


En résumé, je dirais qu'en enseignement tout comme en informatique,
le mot clef c'est « abstraction ». Il est ridicule et grotesque de
vouloir l'oublier.

(Ceci dit, je ne suis pas certain qu'il faut ou qu'il est possible
« d'apprendre » sans comprendre. Mais on doit nécessairement limiter
la portée de « comprendre ».)

Et clairement, d'après mon expérience (et j'ai réellement expérimenté),
apprendre la manipulation des données avec un vecteur
se fait plus facilement avec vector<T> qu'avec T[].

Par contre, malheureusement, on ne peut pas facilement se passer
complètement de T[] en C++, à moins de vouloir écrire du code
vraiment inacceptable (sauf pour l'exercice de se passer de T[] !).
Heureusement on peut faire beaucoup avant d'arriver là.

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/