Copie d'une variable

Discutez d'informatique ici !
barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

Copie d'une variable

par barbu23 » 26 Oct 2014, 15:02

Bonjour à tous, :happy3:

Pourriez vous m'expliquer la chose suivante :

Je dispose du programme suivant :

#include
#include

void decoupeMinutes(int heures, int minutes);

int main(int argc, char *argv[])
{
int heures = 0, minutes = 90;

/* On a une variable minutes qui vaut 90.
Après appel de la fonction, je veux que ma variable
"heures" vaille 1 et que ma variable "minutes" vaille 30 */

decoupeMinutes(heures, minutes);
printf("%d heures et %d minutes", heures, minutes);
return 0;
}

void decoupeMinutes(int heures, int minutes)
{
heures = minutes / 60; // 90 / 60 = 1
minutes = minutes % 60; // 90 % 60 = 30
}


On me dit la chose suivant :

... Quand vous « envoyez » une variable à une fonction, une copie de la variable est réalisée. Ainsi, la variable heures dans la fonction decoupeMinutes n'est pas la même que celle de la fonction main ! C'est simplement une copie !


Que signifie le mot "copie" dans cette citation ?
Si la variable à l’intérieur de la fonction n'est qu'une copie de la variable de la fonction "main", qu'est ce que ça change concrètement ?

Merci d'avance. :happy3:



Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 26 Oct 2014, 15:15

Pour te rendre compte simplement de ceci, je te conseille de t'intéresser à la portée des variables. Ce qu'on appelle le scope (si je me rappelle bien de ce que l'on m'a dit lol :ptdr: )




Teste le code suivant et tu ddevrais comprendre par toi même cette notion de copie.




Code: Tout sélectionner
int main()
{

int x = 10;
printf("x= %d avant la fonction\n",x);
multiplication10(x);
printf("x=%d après la fonction\n",x);
return 0;

}




Code: Tout sélectionner
void multiplication10(int x)
{
     x=x*10;
     printf("x=%d pendant la fonction\n",x);
}



Que va afficher selon toi ce morceau de code ?
Comment remédier à ce problème ?
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

par barbu23 » 26 Oct 2014, 15:28

Bonjour @Rockleader : :happy3:

Il affichera, d'après mon cours :
- avant la fonction.
- pendant la fonction
- après la fonction.
car le à l’intérieur de le fonction multiplication est supprimé à la fin de l'exécution de la fonction multiplication, il me semble.
Comment remédier à ce problème ? Perso, je ne sais pas. Je suis au chapitre qui parle des pointeurs. Faut-il les utiliser ici. Je n'ai pas encore fini la lecture de ce chapitre pour voir comment les utiliser dans notre cas. :happy3:

Merci d'avance pour vos éclaircissements. :happy3:

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 26 Oct 2014, 15:32

C'est bien cela.


Les pointeurs sont une solution au problème.

Dans certains cas lorsque la variable sera un tableau on ne pourra pas y échapper.


Cependant ici pour une variable que je qualifierais de simple.

La méthode consiste à transformer le void en int.


Code: Tout sélectionner
int main()
{

int x = 10;
printf("x= %d avant la fonction\n",x);
x=multiplication10(x);
printf("x=%d après la fonction\n",x);
return 0;

}

int multiplication10(int x)
{
     x=x*10;
     printf("x=%d pendant la fonction\n",x);
    return x;
}



On récupère la valeur de x à la sortie de la fonction car une fois la fonction terminé cette valeur n'existe plus.
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

par barbu23 » 26 Oct 2014, 15:41

Merci beaucoup. :happy3:
Donc, finalement, on peut définir une copie d'une variable globale, comme étant une variable locale à l’intérieur d'une fonction, qui porte le même nom que la variable globale, et qui est détruit à la fin de l’exécution de cette fonction, non ?
Merci d'avance. :happy3:

barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

par barbu23 » 26 Oct 2014, 15:42

Rockleader a écrit:C'est bien cela.


Les pointeurs sont une solution au problème.

Code: Tout sélectionner
int main()
{

int x = 10;
printf("x= %d avant la fonction\n",x);
x=multiplication10(x);
printf("x=%d après la fonction\n",x);
return 0;

}

int multiplication10(int x)
{
     x=x*10;
     printf("x=%d pendant la fonction\n",x);
    return x;
}




Comment utiliser les pointeurs de la manière la plus simple possible, pour résoudre le problème que tu proposes ?

Merci d'avance. :happy3:

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 26 Oct 2014, 15:45

salut,

on peut définir une copie d'une variable globale, comme étant une variable locale à l’intérieur d'une fonction, qui porte le même nom que la variable globale, et qui est détruit à la fin de l’exécution de cette fonction

oui
la vie est une fête :)

barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

par barbu23 » 26 Oct 2014, 15:48

fatal_error a écrit:oui

Merci. :happy3:

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 14:25

par Cliffe » 26 Oct 2014, 15:59

@Rockleader qui donne des explications maintenant :p, comme quoi ... :lol3:

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 26 Oct 2014, 17:00

Cliffe a écrit:@Rockleader qui donne des explications maintenant :p, comme quoi ... :lol3:




C'est pas beau de se moquer :ptdr:




Par contre, je réagis au message de fatal error du coup qui répond oui à ceci


on peut définir une copie d'une variable globale, comme étant une variable locale à l’intérieur d'une fonction, qui porte le même nom que la variable globale, et qui est détruit à la fin de l’exécution de cette fonction





L'intérêt de la variable globale ce n'est pas que justement elle n'est pas copié mais connu partout ?



Concrètement (j'ai pas testé pour le coup mais j'ai clairement des souvenirs de mon compilo qui me sort un warning)


Si on est bien dans ce cas là

Code: Tout sélectionner
#define VAR 20


int main()
{
int x=VAR+1; // x vaudra 21
...
return 0;
}


void weird()
{
int VAR = 5;
//Je suis presque sur qu'ici le compilo va râler et dire qu'on redéfini une variable déjà connu. Sa va pas générer une erreur mais je suis pas sur que ce soit très bon de faire ça...
}



Après, si la réponse est: Oui mais déconseillé alors je suis un peu plus rassuré :zen:
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 26 Oct 2014, 17:24

L'intérêt de la variable globale ce n'est pas que justement elle n'est pas copié mais connu partout ?

l'intérêt de la variable globale... c'est une question que faut trop développer...

Dans ton exemple tes define sont préprocessés idem avant de compiler tes sources, le préprocesseur va remplacer les occurrences de VAR par 20, idem x = 20+1 ok mais int 20=5 c'est faux, car une variable doit pas commencer par un chiffre...

Ton exemple n'illustre donc en rien un masquage de variable.

le masquage c'est simplement ceci:
Code: Tout sélectionner
int GLOBAL = 5;
void toto(){
 int GLOBAL = 3;//this is "shadowing" the global variable GLOBAL and creating a local variable named GLOBAL..
 GLOBAL++;
}
int main(){
 toto(); //toto is writting on its local variable which is named GLOBAL...
 printf("%d", GLOBAL);//GLOBAL here is our global variable which has stayed _untouched_ until now
}
la vie est une fête :)

barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

par barbu23 » 26 Oct 2014, 19:41

Re - bonjour,

Svp, corrigez moi ce que je vais dire. J'appliquerai les pointeurs au problème proposé par @Rockleader. :happy3:

Bref, les pointeurs sont des variables un "peu spéciales", car ce sont des variables conçu pour ne contenir que l'adresse d'autres variables, contrairement aux variables ordinaires, qui sont conçu pour contenir des valeurs quelconques de type int, float , double ... etc.

Notre problème @Rockleader était de pouvoir modifier le contenu d'une variable globale à l'aide de sa copie ( variable locale ) qui se trouve à l'intérieur d'une fonction.

Dans l'exemple de @Rockleader :

int main()
{

int x = 10;
printf("x= %d avant la fonction\n",x);
multiplication10(x);
printf("x=%d après la fonction\n",x);
return 0;

}

void multiplication10(int x)
{
x=x*10;
printf("x=%d pendant la fonction\n",x);
}


Après compilation et exécution, la console affichera :
- avant la fonction.
- pendant la fonction
- après la fonction.

A l'aide des pointeurs, comme suit :

int main()
{

int x = 10;
printf("x= %d avant la fonction\n",x);
multiplication10(&x);
printf("x=%d après la fonction\n",x);
return 0;

}

void multiplication10(int *y)
{
*y=x*10;
printf("*y=%d pendant la fonction\n",x);
}


On obtient après exécution et compilation :

- avant la fonction
- avant la fonction
- après la fonction

Etes vous d'accord avec ce que j'écris là ?
Pour celui qui ne comprend pas pourquoi, vous me faites un signe, et je vous expliquerai volontiers. ( Je n'ai pas voulu introduire une explication détaillée car j'ai un petit peu la flemme )

Est ce que quelqu'un peut me corriger ?

Merci d'avance. :happy3:

Cliffe
Membre Rationnel
Messages: 967
Enregistré le: 12 Juin 2012, 14:25

par Cliffe » 26 Oct 2014, 19:45

tape "référence C++" sur google.
Il faut éviter les pointeurs au maximum.

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 26 Oct 2014, 19:46

dans l'idée c'est ok

mais testes ton idée avant de demander si c'est bon ou pas
la vie est une fête :)

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 26 Oct 2014, 19:48

tape "référence C++" sur google.
Il faut éviter les pointeurs au maximum.

Code: Tout sélectionner
#include
#include

c'est ptet du C qu'il est en train d'apprendre...enfin j'espère :lol3:
la vie est une fête :)

barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

par barbu23 » 26 Oct 2014, 19:52

Oui, j'apprends du C, et j'ai la flemme de le télécharger sur mon ordinateur, car ça demande beaucoup de temps. :hum: :happy3:
Merci en tous cas. :happy3:

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 26 Oct 2014, 20:10

je crois que si tu veux apprendre le C, tu as intérêt à télécharger quand même parce que tester fait parti de l'apprentissage, t'apprendras pas grand chose sinon (et au passage, même avec un 56k, le temps de téléchargement il est complètement négligeable par rapport au temps d'apprentissage)

eventuellement testes un compilateur en ligne, mais tu te mets dans un environnement inconfortable pour rien
la vie est une fête :)

Avatar de l’utilisateur
Rockleader
Habitué(e)
Messages: 2126
Enregistré le: 11 Oct 2011, 19:42

par Rockleader » 26 Oct 2014, 23:33

Si t'es sur linux, rien à télécharger pour faire du C

Si t'es sur windows, tu prend un truc style code blocks et en 2 min tu peux faire du C...

Je traduis les saintes paroles de fatal error:


C'est en testant que l'on apprend à programmer.


T'auras beau avoir toute la connaissance du monde, si tu n'as jamais pratiqué ça ne sert à rien...



"Fatal" a écrit:Dans ton exemple tes define sont préprocessés idem avant de compiler tes sources, le préprocesseur va remplacer les occurrences de VAR par 20, idem x = 20+1 ok mais int 20=5 c'est faux, car une variable doit pas commencer par un chiffre...


Damned, je t'explique pourquoi je fais la confusion; pour la raison très simple que pour moi il n'y a pas d'intérêt à utiliser une variable globales si ce n'est pour l'utiliser comme une constante. Ou alors peut être pour faire de la POO, mais là on sort du C à mon avis.

Mais je suis amplement d'accord avec tout ce que tu as dis ;)
Cette histoire est entièrement vraie puisque je l'ai inventé du début à la fin !

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 27 Oct 2014, 00:16

pour moi il n'y a pas d'intérêt à utiliser une variable globales si ce n'est pour l'utiliser comme une constante

une variable globale c'est qu'une variable avec une grosse portée.

si t'as une variable locale par exemple au sein d'une classe, mais que ta classe fait 10000 lignes, ben ta variable elle pas plus clean que la variable dite globale. Donc il faut pas croire que des qu'on fait pas de variables globales c'est des bonnes variables.

Ensuite dans certaines applis, pour des raisons de contraintes (systèmes embarqués) on peut utiliser des variables globales..., de même pour des raisons de perf.
Maintenant, la qualité veut que même si c'est une variable globale tu la passes en pointeur/référence en arguments afin de pouvoir plus facilement tester ta méthode mais c'est un détail.

Bref, oui généralement une variable globale c'est une constante mais pas forcément (ex: paramètres de configuration de ton application)
la vie est une fête :)

barbu23
Membre Transcendant
Messages: 5466
Enregistré le: 18 Fév 2007, 18:04

par barbu23 » 11 Nov 2014, 17:04

Bonjour à tous, :happy3:

Est ce que quelqu'un peut m'expliquer le fonctionnement du code suivant écrit en langage C++ :

Code: Tout sélectionner
string const nomFichier("C:/Nanoc/Scores.txt");
ofstream monFlux(nomFichier.c_str());


Je ne comprends pas pourquoi : nomFichier reçoit c_str(), pour devenir : nomFichier.c_str(), parce que le type : string n'est pas une structure, non ?
Et pourquoi déclarer une variable comme suit : ofstream monFlux(nomFichier.c_str()); Je sais qu'il s'agit d'un flux et non d'une variable, mais je ne comprends pas à quoi sert cette ligne dans le code, ni comment elle fonctionne.

Merci d'avance pour vos éclaircissements. :happy3:

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 16 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite