Aller au contenu

passage de valeur par adresse marche pas!!!


debuthmx

Messages recommandés

J'avais l'habitude d'utiliser l'operatuer d'adresse (&) en C++ pour passer des arguments par adresse à une fonction par exemple:

 
# include <stdio.h>

int somme (int&,int&);

int main()
{
 int k,l,som;

 k=1;
 l=2;
 som=somme(k,l);

 printf("SOM= %i \n",som);
}


int somme (int&i,int&j)
{
  i=i+1;
  j=j+2;

  return (i+j);
}

si vous compiler ce programme sous linux avec le compilateur c du style:


cc -adresse.c

celà ne fonctionne absolument pas!!!

Donc ce qui m'ammene à la question suivante: Dois t'on obligatoirement utiliser un pointeur pour simuler un passage par adresse sous le compilateur cc ?

Merci.

Lien vers le commentaire
Partager sur d’autres sites

En clair :

void toto(int & param1, int & param2) {...}
toto (x, y);

--> devient -->

void (int * param1, int * param2) {...}
toto(&x, &y);

Ca fait d'ailleurs un paquet de temps que la notation avec les & dans le prototype de la fonction est obsolète et fortement déconseillée.

Lien vers le commentaire
Partager sur d’autres sites

En clair :

void toto(int & param1, int & param2) {...}
toto (x, y);

--> devient -->

void (int * param1, int * param2) {...}
toto(&x, &y);

Ca fait d'ailleurs un paquet de temps que la notation avec les & dans le prototype de la fonction est obsolète et fortement déconseillée.

:mdr:

pq l'utilisation des & dans les prototypes est-elle déconseillée ?

comment fais-tu pour prototyper un passage par référence dans ce cas ?

Lien vers le commentaire
Partager sur d’autres sites

Déconseillée justement parce qu'à l'appel de la fonction, tu ne sais pas si tu envoies une valeur ou une adresse !

void toto (int &i, int j) {...}  <-- je demande une @ puis une valeur
toto(x, y);     <-- là tu envoies quoi ? notation ambiguë

Bon si tu as la fonction et son appel sous le nez en même temps, ça peut TE sembler évident. Mais dans un projet un poil plus gros, tu ne sais plus ce que tu envoies comme type de paramètre...

void toto (int *i, int j) {...}  <-- la même fonction, mais bien prototypée
toto(&x, y);   <-- là tu sais que x est une @, et y une valeur

Là tu sais exactement ce que tu fais. Clair ?

Lien vers le commentaire
Partager sur d’autres sites

Déconseillée justement parce qu'à l'appel de la fonction, tu ne sais pas si tu envoies une valeur ou une adresse !

void toto (int &i, int j) {...}  <-- je demande une @ puis une valeur
toto(x, y);     <-- là tu envoies quoi ? notation ambiguë

Bon si tu as la fonction et son appel sous le nez en même temps, ça peut TE sembler évident. Mais dans un projet un poil plus gros, tu ne sais plus ce que tu envoies comme type de paramètre...

void toto (int *i, int j) {...}  <-- la même fonction, mais bien prototypée
toto(&x, y);   <-- là tu sais que x est une @, et y une valeur

Là tu sais exactement ce que tu fais. Clair ?

euh oui, c'est clair, je vois où tu veux en venir...

mais là ou je t'arrete, c'est que tu dis qu'il faut purement et simplement oublier/éviter les passages par référence au profit des passages par pointeur ou par valeur...

:gne:

Je veux bien que cela semble ambigu dans de gros projets, mais il me semble que l'on est censé aller vérifier ses prototypes quand on a un doute. Si je suivais ton raisonnement à la lettre, alors on devrait banir les surcharges, le polymorphisme et autres joyeusetés du C++... car on ne sait plus trops ce qui se passe dans le code si on ne vérifie pas ses prototypes, non ?

PS : il est vrai qu'il aurait fallu introduire un nouvel opérateur pour avoir un passage par référence plus explicite.

Lien vers le commentaire
Partager sur d’autres sites

Non non le polymorphisme et l'héritage (non-multiple) sont nécessaires :)

Mais pour le passage des paramètres, il est préférable d'utiliser "ma" notation.

Heureusement d'ailleurs que les fonctions dans les DLL (code inaccessible) sont programmées de la bonne façon : sinon tu n'aurais aucun moyen d'aller voir le proto pour savoir si le "x" que tu passes est une adresse mémoire ou une valeur.

D'ailleurs regarde les proto des fonctions standard : quand tu appelles scanf par exemple, tu écris : scanf ("%s", &ma_chaine);

Je t'invite par ailleurs à étudier le K&R et la "C++ FAQ Lite" dispo depuis peu sur le net, sa lecture est très instructive.

Lien vers le commentaire
Partager sur d’autres sites

Je ne suis pas trop d'accord avec Sentinel sur la facon d'ecrire du code C++.

D'une part -et d'une facon generale-, les pointeurs ("*") sont a bannir en C++ quand c'est possible. C'est justement le cas du passage de parametre par reference ou le pointeur n'apporte rien.

D'autre part, le "&" est obligatoire dans certains cas (exple : constructeurs par copie) et n'est nullement obsolete.

Quant aux DLL C++, la documentation de ce qu'elles contiennent doit suffire a savoir si les parametres passes vont etre modifies ou non. Si on ne sait pas exactement comment appeler une fonction et ce qu'elle fait, c'est qu'il y a un probleme... :)

Lien vers le commentaire
Partager sur d’autres sites

Non non le polymorphisme et l'héritage (non-multiple) sont nécessaires :)

Mais pour le passage des paramètres, il est préférable d'utiliser "ma" notation.

Heureusement d'ailleurs que les fonctions dans les DLL (code inaccessible) sont programmées de la bonne façon : sinon tu n'aurais aucun moyen d'aller voir le proto pour savoir si le "x" que tu passes est une adresse mémoire ou une valeur.

D'ailleurs regarde les proto des fonctions standard : quand tu appelles scanf par exemple, tu écris : scanf ("%s", &ma_chaine);

Je t'invite par ailleurs à étudier le K&R et la "C++ FAQ Lite" dispo depuis peu sur le net, sa lecture est très instructive.

euh là, je suis désolé, mais tu as toujours accès aux protos des fonctions que tu appelles... sinon c'est de la programmation poubelle avec des warnings dans tous les sens.

Pour moi, c'est assez simple : si tu n'as pas le proto (déclaration) d'une fonction, tu ne l'utilises pas !!! Les *.h, c'est pas fait pour les chiens. J'ai la tolérance 0 pour les déclaration implicites depuis un link foireux d'une fonction à 6 paramètres avec seulement 5 paramètres (vive gcc sous LynxOS).

Si on te fournit des DLL sans les déclarations s'y rapportant, tu ferais mieux de les éviter. Sinon tu te mets toi-même la corde au cou dans des applications critiques.

PS : J'ai commencé le C en 92 et je fais activement du C/C++ depuis 96 :D , mais je vais lire ta doc car j'adore apprendre de nouveaux trucs :mdr: , puis j'ai eu une blague avec new/delete qui avaient changés sans que je ne le sache.

PPS : un petit tutorial assez sympa, surtout le chapitre 7 :)

PPPS : selon TES sources, on est censé préférer les références aux pointeurs en C++ ... No comment ...

Lien vers le commentaire
Partager sur d’autres sites

C++ FAQ Lite :

Note: Les programmeurs C de la vieille guarde n'aiment pas parfois les références car ils apportent une sémantique de référence qui n'est pas explicite dans le code de l'appelé. Après un peu d'expérience en C++, cependant; on réalise rapidement que c'est une forme de dissimulation d'information, qui est un actif plutôt qu'un passif. En effet, les programmeurs devraient écrire le code dans le langage du problème plutôt que le langage de la machine.

Je ne partage pas du tout son point de vue sur le fait que cette dissimulation d'information doive être considérée comme un avantage. Si on utilise la méthode par référence, quand on lit le source, on est incapable de dire si les valeurs passées en paramètre ont pu ou non être modifiées par l'eppel de la fonction (à moins d'aller systématiquement fouiller dans les 1000 .h inclus au début du programme pour retrouver le prototype de la fonction qu'on appelle). Je trouve cela extrêmement dangereux.

On aurait pu également, comme tu dis, inventer un nouvel opérateur ou une nouvelle notation pour clarifier la notation... Enfin, il y a déjà tant de choses mal foutues dans le C++...

En attendant je préfère utiliser des pointeurs (éventuellement const). La syntaxe en est peut-être un peu plus volumineuse dans le corps de la fonction, mais au moins le code est plus explicite, aussi bien dans la fonction elle-même que dans ses appels.

Je m'explique : prenons une fonction qui demande un &i. Dans la fonction, un bête "i++" a immédiatement des conséquences à l'extérieur de la fonction. Or cette notation "i++" n'indique en rien qu'on travaille sur davantage qu'une simple variable locale : la confusion est si vite arrivée. Alors qu'un "*i++" est déjà beaucoup plus parlant : le programmeur sait qu'il manipule une variable qui est potentiellement visible à plus large échelle.

Pour avoir débuggé pas mal de code (même écrit par des programmeurs C chevronnés), je garantis que la syntaxe par pointeurs est nettement plus "franche" : les erreurs engendrées par la notation & sont plutôt insidieuses et assez raides à détecter.

PS : Effectivement pour les bouts de code sans documentation (ou avec une doc MSDN :francais: ) , je les fuis comme la peste :8

PPS : je programme également en C/C++ depuis 1995 (j'avais acheté Turbo C++... ah c'était le bon temps), et également en plein d'autres langages de toutes natures. Ca ne sert à rien d'essayer de jouer à celui qui a la plus grosse (c'est pê pas moi :yes: )... Ce n'est pas mon propos. Je préfère plutôt partager les expériences et les points de vue, c'est plus enrichissant comme discussions... et je ne cite pas "mes" sources pour prouver à tout prix que j'ai raison, mais plutôt pour élargir le débat, indiquer une nouvelle piste de réflexion. Bonne lecture :yes:

Lien vers le commentaire
Partager sur d’autres sites

PPS : je programme également en C/C++ depuis 1995 (j'avais acheté Turbo C++... ah c'était le bon temps), et également en plein d'autres langages de toutes natures. Ca ne sert à rien d'essayer de jouer à celui qui a la plus grosse (c'est pê pas moi :-D )... Ce n'est pas mon propos. Je préfère plutôt partager les expériences et les points de vue, c'est plus enrichissant comme discussions... et je ne cite pas "mes" sources pour prouver à tout prix que j'ai raison, mais plutôt pour élargir le débat, indiquer une nouvelle piste de réflexion. Bonne lecture  :yes:

Je n'ai pas dit ça pour voir qui a la plus grosse (quoique :yes: ), mais plutôt pour calmer un EVENTUEL novice et pour éviter de lancer un débat avec qqn qui n'aurait pas les bases nécéssaires, ce qui ne semble pas être le cas :8

pour le reste, sous windows, on utilise Visual studio qui affiche les prototypes en pop-up, et sous linux, on a source-navigator et autres qui permettent de sauter directement à la définition de la fonction... ce n'est donc pas un vrai problème... puis en ligne de commande, il y a grep...

Je passe toujours toutes mes classes en référence et non en valeur => quand je vois une classe comme argument, je sais que c'est une référence... et j'utilise un système de préfixes/suffixes pour mes variables, ce qui m'en donne immédiatement la nature sans avoir à chercher leur déclaration.

Il est débile et dangereux, à mon avis, de faire un passage par référence sur autre chose qu'une classe. Ensuite, depuis une série de bugs incohérent quant à l'ordre de calcul des paramètres d'une fonction (théoriquement de gauche à droite) dû à une optimisation de compilo, je ne mets plus trops de ++ ou -- dans mes paramètres.

Pour les erreurs "raides", on peut en avoir avec d'autres choses que les références, genre oublier le 0 de fin de chaîne, ne pas vérifier les mallocs, faire des machines d'état trops complexes et mal structurées, ne pas faire attention à l'alignement des données sur différentes architectures et compilos, etc, etc... et trops faire confiance au compilo.

PS : faire ++/-- sur une classe, c'est bien plus un cas d'école qu'un cas que l'on peut rencontrer sur le terrain, non ? Je ne connais pas de programmeur qui redéfinisse cet opérateur pour sa classe, c'est déja très limite pour les opérateurs arithmétiques... et c'est carrément impensable en dehors des programmes de calcul...

PPS : c'est pas courant de voir qqn citer une source en contradiction avec ses dires :francais:

PPPS : je ne crois pas aux erreurs raides... un foi qu'on a trouvé la correction à apporter, ça semble toujours simple, le plus difficile étant de débusquer le bug en question. Si la correction n'est pas simple, c'est qu'elle nécéssite une réécriture d'une partie du code et que la partie du programme en question était mal conçue... ce qui doit potentiellement remettre en question les capacités du programmeur "coupable". Je veux bien que l'on soit distrait, mais les erreurs de conceptions sont, à mes yeux, assez graves. C'est grace à ce genre de programmeurs que l'on obtient de bombes à retardement comme Windows...

Lien vers le commentaire
Partager sur d’autres sites

Ah ça pour retarder, elle retarde :mdr:

En fait sur mes exemple on s'est mal compris, je parlais de types simples et toi de classes.

Enfin c'est vrai que ++ sur une classe, c'est envisageable mais pas méga courant :jesquate:

Il est vrai que passer des classes par référence est utile, mais il faut tout de même bien le préciser, non seulement dans les commentaires de la classe et de l'appel, mais aussi en utilisant un système de préfixes (que, d'ailleurs, tout programmeur vétéran a adopté depuis longtemps).

Personnellement j'ai appris les pointeurs (et surtout toute l'algorithmie qui va avec) sous feu Turbo Pascal, ce qui fait qu'en passant au C/C++ je n'ai eu aucun problème de conception dans mes programmes. Malheureusement, les Ecoles/IUT/Facs aujourd'hui font apprendre la programmation directement avec le C, langage assez délicat à (bien) manier, ce qui donne les résultats que l'on sait (blue screen anyone ?).

Pour la source (C++ faq lite), c'est simplement que j'étais d'accord avec la partie qui disait que le recours aux références cachait pas mal de choses au programmeur... Et donc ça ne me plaisait pas trop. Et puis cette doc est intéressante, je pense que tu devrais aimer.

Tiens sinon pour rire, regarde là... C'est pas des guignols qui ont pondu les codes (Larry Wall... :D ), mais... disons que j'hésiterais à coder comme ça :francais:

http://www.de.ioccc.org/years.html

Lien vers le commentaire
Partager sur d’autres sites

Ah ça pour retarder, elle retarde :mad2:

En fait sur mes exemple on s'est mal compris, je parlais de types simples et toi de classes.

Enfin c'est vrai que ++ sur une classe, c'est envisageable mais pas méga courant :D

Il est vrai que passer des classes par référence est utile, mais il faut tout de même bien le préciser, non seulement dans les commentaires de la classe et de l'appel, mais aussi en utilisant un système de préfixes (que, d'ailleurs, tout programmeur vétéran a adopté depuis longtemps).

Personnellement j'ai appris les pointeurs (et surtout toute l'algorithmie qui va avec) sous feu Turbo Pascal, ce qui fait qu'en passant au C/C++ je n'ai eu aucun problème de conception dans mes programmes. Malheureusement, les Ecoles/IUT/Facs aujourd'hui font apprendre la programmation directement avec le C, langage assez délicat à (bien) manier, ce qui donne les résultats que l'on sait (blue screen anyone ?).

Pour la source (C++ faq lite), c'est simplement que j'étais d'accord avec la partie qui disait que le recours aux références cachait pas mal de choses au programmeur... Et donc ça ne me plaisait pas trop. Et puis cette doc est intéressante, je pense que tu devrais aimer.

Tiens sinon pour rire, regarde là... C'est pas des guignols qui ont pondu les codes (Larry Wall... :8 ), mais... disons que j'hésiterais à coder comme ça :francais:

http://www.de.ioccc.org/years.html

C'est vrai que dans les écoles, il y a une approche un peu trops rapide du C, mais c'est surtout pour "filtrer" les étudiants. Dans mon école, j'ai eu 3 ans de C/C++/Système/ASM (je me souviendrai toujours de ce prof qui a voulu me coincer comme les autres et qui s'est fait baiser en beauté sur une histoire d'algo numérique en C), alors qu'une école "concurrente" voyait le C/C++ en 1 semestre, et ils se la petaient à cause du prof qui s'y croyait vraiment. A la sortie, ils avaient un niveau lamentable, 6 mois plus tards, ils n'y connaissaient plus rien...

Pour les références, il est vrai que l'on masque des choses au lecteur, et ce n'est pas dans la logique du C...

Pour les pointeurs, j'essaye de ne les utiliser que dans le cas de tableaux ou de calculs multidimensionels (matrices à 2,3,4,5,... dimensions), pas pour un seul élément, mais ce n'est pas toujours possible.

Dans les fléaux de la programmation, on a aussi les variable globales, leur nombre est inversément proportionel aux compétences du programmeur.

En ce qui concerne le site avec le concours du code le plus obscur, je penses que je vais essayer un de ces 4, j'ai déja pondu des trucs logiques, structurés mais assez rébarbatifs et incompréhensibles pour le profane (on n'a pas toujours le choix) tout en respectant l'indentation et en utilisant des noms de variables clairs.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...