IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Variable qui change de valeur à chaque appel de fonction


Sujet :

C

  1. #1
    En attente de confirmation mail
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Points : 52
    Points
    52
    Par défaut Variable qui change de valeur à chaque appel de fonction
    Bonjour,

    Je débute depuis 10 mois pour apprendre le langage C à raison de 4-8 hr par semaine. Dans le code ci-dessous repris du chapitre 10 du site.
    je ne comprends pas comment à l'appel de EgalCh 'n' change de valeur (ou conserve la valeur - de l'appel de la dernière fonction - décrémentée).

    J'ai une petite idée des notions de static...Est-ce que ça s'applique dans ce cas? Par défaut, c'est toujours la même chose. Dans les autres langages qui emploient des fonctions avec. Je m'éloigne peut-être du sujet dans la dernière question, c'est juste pour anticiper disons...

    Merci,
    Pascal

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <stdio.h>
     
    int main(void)
    {
    	char *ChercheCh(char *Ch1, char *Ch2) ;
    	char Txt1[50] ;
    	char Txt2[50] ;
    	char *pTxt1 = Txt1 ;
    	char *pTxt2 = Txt2 ;
    	char *rep ;
     
    	printf("\n\nEntrez un mot a rechercher : ") ;
    	fgets(pTxt1, 50, stdin) ;
    	printf("\nEntrez une phrase sujet : ") ;
    	fgets(pTxt2, 50, stdin) ;
     
    	rep = ChercheCh(pTxt1, pTxt2) ;
     
    	printf("\nPosition : %c", *rep) ;	
     
    	printf("\n\n") ;
    	return 0;
    }
     
    char *ChercheCh(char *Ch1, char *Ch2)
    {
    	int LongCh(char *Ch) ;
    	int EgalCh(int n, char *Ch1, char *Ch2) ;
    	int Lg ;
     
    	Lg = LongCh(Ch1) ;
     
    	while ( *Ch2  &&  !EgalCh(Lg, Ch1, Ch2) )
    		Ch2++ ;
     
    	return Ch2 ;
    }
     
    int LongCh(char *Ch)
    {
    	char *p ;
     
    	for ( p = Ch  ;  *p  ;  p++ )
    		;
     
    	return p - Ch ;
    }
     
    int EgalCh(int n, char *Ch1, char *Ch2)
    {
    	while ( --n  &&  *Ch1 == *Ch2 )
    	{
    		Ch1++ ;
    		Ch2++ ;
    	}
    	return ( *Ch1 == *Ch2 ) ;
    }

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Je n'ai pas compris ta question mais je vais t'éclaircir un peu sur ce qui se passe : EgalCh n'est appelée que par ChercheCh. Cet appel est effectué dans une boucle (donc plusieurs fois) mais à chaque fois, la valeur affectée au paramètre n est Lg, qui est égal à LongCh(Ch1). n reçoit donc la même valeur à chaque appel. Maintenant, qu'est-ce que tu veux qu'il se passe ?

    static ne peut pas s'appliquer à un argument d'une fonction.

  3. #3
    En attente de confirmation mail
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Points : 52
    Points
    52
    Par défaut
    Ce que je veux dire est que Lg est décrémenté par l'intermédiaire de EgalCh car
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while ( --n  &&  *Ch1 == *Ch2 )
    	{
    'While" (ci-dessus) est faux si par exemple *Ch1 est "bonjour" et *Ch2 est "jour"... n = 8 mais 'b' n'est pas égal à 'j' alors while quitte MAIS la variabe n ou Lg est décrémentée de 1 soit 7 au lieu de 8. 7 est la valeur de "n" lors de l'appel suivant sinon while ne s'arrête plus.

    Je ne comprends pas comment la fonction ChercheCh conserve la valeur de Lg reçue de son dernier appel?

    J'espère arriver à me faire comprendre même si ce n'est pas clair.

    Merci

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    n est une variable locale de la fonction EgalCh. ChercheCh lui envoie la valeur de la variable Lg à chaque appel ; cette variable n'est calculé qu'une fois, ici :
    Par conséquent, n vaut toujours la même valeur à chaque fois qu'on entre dans EgalCh, c'est à dire la valeur de Lg.

    Je ne comprends donc pas ta question.

    Par contre, il y a un bug dans ton code. En effet, imagine que le mot à chercher n'existe pas. La boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( *Ch2  &&  !EgalCh(Lg, Ch1, Ch2) )
    est donc susceptible de faire planter EgalCh, en lui faisant lire un accès mémoire situé en dehors du tableau Txt2 (via le pointeur Ch2), au cas où la taille additionnée des deux chaînes dépasse 50 (valeur que tu as fixé pour la taille du second tableau).

    Et il y a aussi une chose qui ne va pas. Si tu as un seul caractère à trouver dans la phrase, la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( --n  &&  *Ch1 == *Ch2 )
    ne sera même pas parcourue. Il faut décrémenter non pas avant mais après l'évaluation des conditions. Si n vaut un, la boucle doit être parcourue une fois. S'il vaut deux, elle doit être parcourue deux fois. Etc. Or, là, on diminue d'office un caractère au mot à rechercher.
    Il faudrait plutôt remplacer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( n--  &&  *Ch1 == *Ch2 )
    Je te conseille aussi de faire en sorte que ChercheCh retourne NULL si le mot à chercher n'est pas trouvé.

  5. #5
    En attente de confirmation mail
    Homme Profil pro
    Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php
    Inscrit en
    Mars 2010
    Messages
    48
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Gestion comptable - Spécialiste Excel, Vba, - Débutant MySql, Javascript, Python, Php

    Informations forums :
    Inscription : Mars 2010
    Messages : 48
    Points : 52
    Points
    52
    Par défaut
    Je suis d'accord avec une chose :
    la limite de 50 peut engendrer une erreur lors de l'exécution si le nombre de caractères dépasse...

    Seulement la variable Lg ne me parle pas. Le code affecte à Lg le nombre de caractère de Ch1.

    Citation Envoyé par jeroman Voir le message
    n est une variable locale de la fonction EgalCh. ChercheCh lui envoie la valeur de la variable Lg à chaque appel ; cette variable n'est calculé qu'une fois, ici :
    Par conséquent, n vaut toujours la même valeur à chaque fois qu'on entre dans EgalCh, c'est à dire la valeur de Lg.

    Je ne comprends donc pas ta question.

    Par la suite Lg devient le paramètre n de EgalCh lors de sa déclaration.

    Pour que le code fonctionne le code suivant de la fonction EgalCh :
    while ( --n && *Ch1 == *Ch2 )
    doit faire en sorte que la valeur n soit la valeur de l'appel précédent dans le cas contraire, il y aura toujours la même comparaison sur les même lettres.


    Par contre, il y a un bug dans ton code. En effet, imagine que le mot à chercher n'existe pas. La boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( *Ch2  &&  !EgalCh(Lg, Ch1, Ch2) )
    est donc susceptible de faire planter EgalCh, en lui faisant lire un accès mémoire situé en dehors du tableau Txt2 (via le pointeur Ch2), au cas où la taille additionnée des deux chaînes dépasse 50 (valeur que tu as fixé pour la taille du second tableau).

    Et il y a aussi une chose qui ne va pas. Si tu as un seul caractère à trouver dans la phrase, la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( --n  &&  *Ch1 == *Ch2 )
    ne sera même pas parcourue. Il faut décrémenter non pas avant mais après l'évaluation des conditions. Si n vaut un, la boucle doit être parcourue une fois. S'il vaut deux, elle doit être parcourue deux fois. Etc. Or, là, on diminue d'office un caractère au mot à rechercher.
    Il faudrait plutôt remplacer par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( n--  &&  *Ch1 == *Ch2 )
    Je suis qu'à moitié d'accord avec n-- :
    car fgets comptabilise '\n' dans la longueur de la chaine mémorisée. Si '\n' compte comme un caractère, il n'est pas utile de rechercher à le comparer avec le début de l'autre chaîne de caractères.


    Je te conseille aussi de faire en sorte que ChercheCh retourne NULL si le mot à chercher n'est pas trouvé.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Par la suite Lg devient le paramètre n de EgalCh lors de sa déclaration.

    Pour que le code fonctionne le code suivant de la fonction EgalCh :
    while ( --n && *Ch1 == *Ch2 )
    doit faire en sorte que la valeur n soit la valeur de l'appel précédent dans le cas contraire, il y aura toujours la même comparaison sur les même lettres.
    Euh...

    On va résumer l'exécution du programme.

    Tout d'abord, on entre dans le main, on initialise les pointeurs, on fait la saisie des chaines.

    Ensuite, on lance ChercheCh avec comme paramètres les deux pointeurs (pointant sur les deux chaines).

    Cette fonction calcule une seule fois la longueur du mot à chercher, cette valeur ne change plus par la suite. Le résultat est stocké dans Lg.

    Ensuite, on lance la boucle principale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while ( *Ch2  &&  !EgalCh(Lg, Ch1, Ch2) )
       Ch2++ ;
    qui va boucler un certain nombre de fois. A chaque fois qu'on revient en début de boucle, on teste en premier si la phrase à analyser n'est pas finie ; si elle n'est pas finie, on teste alors le retour de la fonction EgalCh afin de savoir si une occurrence a été trouvée. Cette fonction envoie à chaque fois la valeur de la variable Lg en paramètre, c'est-à-dire toujours la même. C'est un passage par copie. La variable locale n est crée lors de l'appel à EgalCh et détruite une fois que la fonction se termine. La variable est toujours initialisée avec la valeur de Lg à chaque entrée dans la fonction.

    dans le cas contraire, il y aura toujours la même comparaison sur les même lettres.
    Il n'y aura pas de comparaison sur les mêmes lettres, car dans la boucle principale, regarde bien ce qui est écrit en rouge :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while ( *Ch2  &&  !EgalCh(Lg, Ch1, Ch2) )
    Ch2++ ;
    Lg n'est ni plus ni moins que la longueur du mot à rechercher. A chaque tour de boucle, tu incrémentes Ch2, ce qui provoque le test à partir d'un caractère toujours plus à droite à chaque fois.

    Par exemple, si tu as une chaine "cde" à rechercher dans la chaine "abcdef", on opère comme tu le fais.
    On teste les 3 premières lettres de "abcdef". On sort de EgalCh dès la première lettre, car elle est différente (donc sortie de boucle). On avance ensuite d'un caractère via la boucle principale, grâce à la ligne en rouge de la boucle (juste au-dessus).
    On teste ensuite les 3 premières lettres de "bcdef". Même chose : on sort de EgalCh dès la première lettre, car elle est différente. On avance ensuite d'un caractère.
    On teste ensuite les 3 premières lettres de "cdef". Et là, bingo. La fonction renvoie 1. La boucle principale teste ses deux conditions ET, et le résultat vaut 0 (car !1 == 0), ce qui provoque alors la sortie de cette boucle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int EgalCh(int n, char *Ch1, char *Ch2)
    {
    	while ( --n  &&  *Ch1 == *Ch2 )
    	{
    		Ch1++ ;
    		Ch2++ ;
    	}
    	return ( *Ch1 == *Ch2 ) ;
    }
    Je n'avais pas fait attention, mais il y a un bug là aussi. A l'intérieur, de la boucle, n'oublie pas que tu incrémentes Ch1 et Ch2. Regarde maintenant la condition dont se sert ton return pour renvoyer la valeur. Lorsqu'une occurrence est trouvée, tu ne retournes pas la comparaison de la nième lettre respective des deux chaines, mais de celles qui suivent.
    Si tu cherches "abc" dans "abcdef", l'occurrence est bien trouvée, mais ta fonction ne va pas retourner 'c' == 'c', mais '\n' == 'd' (voire '\0' == 'd'). Ta boucle principale n'y verra donc que du feu et continuera à tourner.

    car fgets comptabilise '\n' dans la longueur de la chaine mémorisée. Si '\n' compte comme un caractère, il n'est pas utile de rechercher à le comparer avec le début de l'autre chaîne de caractères.
    Je te conseille alors de supprimer le '\n' final et de le remplacer par 0. Ce sera beaucoup plus propre. Tu peux t'inspirer de ce code : http://c.developpez.com/faq/?page=cl...ran#CONS_fgets

Discussions similaires

  1. Variable qui change de valeur "toute seule"
    Par GDMINFO dans le forum C++
    Réponses: 9
    Dernier message: 14/10/2010, 18h12
  2. Variables qui perdent leur valeur lorsqu'utilisées dans fonction
    Par damlarumeur dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/02/2009, 09h05
  3. Variable qui change de valeur toute seul :(
    Par lcfseth dans le forum C
    Réponses: 12
    Dernier message: 22/12/2007, 12h25
  4. [JMeter] Récupration d'une variable qui change à chaque process
    Par vendeeman dans le forum Tests et Performance
    Réponses: 3
    Dernier message: 11/12/2007, 12h00
  5. Réponses: 6
    Dernier message: 18/01/2007, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo