4 votes

Pourquoi la variable globale est différente de la variable locale dans cette fonction ?

Ici, j'ai une fonction nommée max(a,b) pour obtenir le nombre maximum de deux. Et j'ai trouvé que la valeur de la variable a y b en utilisant printf() sont différentes après avoir exécuté

printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);

quand a y b sont Global variables y Local variables . Voici mon code :

#include<stdio.h>

int max(int a,int b)
{

    if(a>b)
    {
        //printf("In func max():%d %d \n",a,b);
        return a;
    }
    else {
        //printf("In func max():%d %d \n",a,b);
        return b;
    }

}
void jubu_test(void)
{
    int a=1;
    int b=2;    
    printf("maxab()=%d after max: a=%d b=%d \n",max(a++,b++),a,b);  //a=2,b=3
}
int c=2;
int d=1;
void quanju_test(void)
{
    printf("maxcd()=%d  c=%d d=%d \n",max(c++,d++),c,d);    //c=2,d=1
    c=2;
    d=1;
    int f=max(c++,d++);
    printf("maxcd()=%d after max: c=%d d=%d \n",f,c,d);     //c=3,d=2
}   
int main(int argc, char** argv)
{
    jubu_test();
    quanju_test();
}

Le résultat que j'obtiens sur mon ordinateur est le suivant :

maxab()=2 after max: a=2 b=3
maxcd()=2  c=2 d=1
maxcd()=2 after max: c=3 d=2

Ma question est la suivante : Pourquoi dans la deuxième sortie a et b sont leurs valeurs originales et pourquoi la troisième sortie est a+1 et b+1 ? Pourquoi, lorsque a et b sont des variables globales, la valeur de a et b imprimée ne change que lorsque nous exécutons max(a++,b++) première ? Pourquoi lorsque a et b sont des variables locales, cela n'a pas d'importance ?

Merci ! (utilisant gcc 5.3.0 sur Windows 10)

5voto

Lundin Points 21616

L'expression printf(... max(a++,b++),a,b); es indéfini comportement selon Pourquoi ces constructions (utilisant ++) ont-elles un comportement non défini ? .

L'évaluation de a++ n'est pas séquencé par rapport à l'évaluation de a de même pour b++ y b . Il importe peu qu'il y ait un point de séquence avant l'appel de la fonction, car les sous-expressions peuvent être évaluées avant, dans n'importe quel ordre.

Comportement indéfini = toujours un bug. Cela signifie que le programme peut avoir n'importe quel type de comportement, imprimer n'importe quoi, se planter et brûler, etc.

La raison pour laquelle il s'agit d'un comportement non défini est la suivante, C11 6.5/2 :

Si un effet secondaire sur un objet scalaire n'est pas séquencé par rapport à l'un ou l'autre des éléments suivants un effet secondaire différent sur le même objet scalaire ou une valeur calcul de valeur utilisant la valeur du même objet scalaire, le comportement est indéfini.

( a est un objet scalaire - pas un tableau ou une structure, etc. a++ provoque un effet de bord de la mise à jour de la variable. Ceci n'est pas séquencé par rapport au calcul de la valeur de a ailleurs dans la même expression).


À ne pas confondre avec comportement non spécifié ce qui signifie que le programme se comportera de manière déterministe mais que vous ne pouvez pas savoir de quelle manière. Par exemple, l'ordre d'évaluation des arguments d'une fonction est un comportement non spécifié :

int func (void)
{
  static int x=0;
  x++;
  return x;
}

printf("%d %d", func(), func());

Cela peut imprimer soit 1 2 o 2 1 et nous ne pouvons pas savoir ou supposer lequel s'applique. Le compilateur n'a pas besoin de documenter cela, ni de se comporter de manière cohérente tout au long du programme. Il pourrait choisir un ordre dans un cas et un autre dans un autre cas.

Le code reposant sur un comportement non spécifié est mauvais, mais ne se comportera pas de manière complètement erratique comme le code contenant un comportement indéfini.

3voto

Sourav Ghosh Points 54713

Comme je le crois, cela n'a rien à voir avec la portée des variables. Le langage C ne spécifie pas l'ordre exact de l'évaluation des arguments des fonctions. Il s'agit donc d'un comportement non spécifié.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X