#include <stdio.h> int i = 3, j = 10; int crypt(int j) { return (i = i+j); } void decrypt(int x, int i) { j += crypt(i); } int main(void) { int i = 0; i = crypt(5); decrypt(i, j); printf("|%d %d|", i, j); return 0; } I'm having trouble figuring out why does it printout |8 28|.The "8" part, I understand that ati = crypt(5) -> j is now 5 in this function -> i = i + j -> There's no i therefore it uses the global variable i = 3 -> i = 3 + 5 -> returns i = 8So the i in the main function becomes 8.But what about the next printout? Why is it 28 instead of 23?The way I read it was like thisdecrypt(i, j) -> decrypt(8, 10) -> x is now 8 and i is now 10 in this function -> j += crypt(i) -> j += crypt(10) -> j in this function is now 10. return ( i = i + j ), there's no i in this function so i = 3 + 10... returns 13?So then j += 13 is 23? Which part of the step did I mess up? I've been reading local / global scope online and I still don't quite get where did I go wrong... Feels like I'm messing up my value for i somewhere. PS: I apologize for the poor formatting, not quite sure how else can I put it cleanly.
4 Réponses :
Vous écrivez:
return (i = i + j), il n'y a pas de i dans cette fonction donc i = 3 + 10 ... renvoie 13?
Non, i
n'est plus 3. Il a été changé en 8 précédemment, c'est-à-dire ici return (i = i + j);
en raison du premier appel de crypt
Lorsque vous écrivez:
Ainsi, le i dans la fonction principale devient 8.
c'est correct, mais le i
global a également été modifié.
Ahh merci! Je vois où je me suis trompé. J'ai complètement oublié le (i = i + j) affectant la variable globale.
Vous avez ici un i et un j globaux, et un i var local. Dans l'ensemble, chaque fois que vous faites référence à i, il vérifie d'abord votre portée actuelle - ainsi, tout changement sera effectué sur votre i local, et le i global ne changera pas. si vous demandez à une fonction en dehors de main de faire quelque chose avec i var, elle vérifie d'abord sa propre portée, puis vérifie si global i var. dans ce cas, les modifications qui seront apportées sont sur le i global.
Alors ... première fois-
local i est défini dans main puis reçoit la valeur de i = crypt (5); une autre chose est que dans cette fonction, vous attribuez également la valeur 8 au i-> global (i = i + j), avant de renvoyer la valeur 8 au i local.
deuxième fonction:
décrypter (i, j); ici, vous envoyez le i local (= 8) et le j global (= 10) à la fonction, dans lequel vous avez:
j + = crypt (i);
ce qui vous donne j = j + ((global) i = 8 + 10): 10 + 8 + 10. et définissez également votre i global sur 18.
Les variables globales sont déclarées en dehors de toute fonction et peuvent être accédé (utilisé) sur n'importe quelle fonction du programme. Les variables locales sont déclaré à l'intérieur d'une fonction, et ne peut être utilisé qu'à l'intérieur de cette fonction. Il est possible d'avoir des variables locales avec le même nom dans des fonctions.
Au premier appel de la fonction crypt (5); vous avez modifié la valeur de la variable globale en,
i = i + j ----> i = 3 + 5 ----> i = 8
Et lorsque la fonction decrypt () est appelée, i = 8 Parce que i est 8 j imprime 28 après l'addition qui est une variable globale.
Considérez la version suivante du code, où les variables ont été renommées pour éviter toute confusion.
#include <stdio.h> int iGlobal = 3, jGlobal = 10; int crypt(int jParam) { return (iGlobal = iGlobal+jParam); } void decrypt(int xUnused, int iParam) { jGlobal += crypt(iParam); } int main(void) { int iLocal = 0; iLocal = crypt(5); decrypt(iLocal, jGlobal); printf("|%d %d|", iLocal, jGlobal); return 0; }
Maintenant, il devrait être relativement facile d'expliquer ce qui se passe lorsque le code est exécuté:
main ()
, iLocal
est zet à 0 main
appelle crypt(5)
crypt
évalue iGlobal + jParam
, c'est-à-dire 3 + 5, et attribue le résultat à iGlobal
, c'est-à-dire iGlobal code > vaut 8
crypt
renvoie 8 main
attribue la valeur de retour de 8 à iLocal
main
appelle decrypt(8,10)
décrypter
les appels crypt(10)
crypt
évalue iGlobal + jParam
, c'est-à-dire 8 + 10, et attribue le résultat à iGlobal
, c'est-à-dire iGlobal code > a 18 ans
crypt
renvoie 18 decrypt
ajoute la valeur de retour de 18 à jGlobal
, c'est-à-dire que jGlobal
est 28 printf
imprime les valeurs de iLocal
, 8 et jGlobal
, 28 La partie compliquée, le cas échéant, est de savoir quand les variables globales sont remplacées (a.k.a. cachées, ou ombrées) par leurs homologues locaux, la réponse étant "chaque fois que possible".
essayez de compiler avec
-Wshadow
, si vous utilisez gcc.Vous oubliez le devoir dans
i = i + j
. Lors du deuxième appel àcrypt
, la valeur dui
global n'est plus3
.return (i = i + j), il n'y a pas de i dans cette fonction donc i = 3 + 10 ... renvoie 13?
Vous avez déjà changé lei
global en < code> 8 lors de l'appel précédent à crypt. Donci
vaut 8 maintenantEt tout cela explique pourquoi jouer avec les globaux et les cacher partiellement chez les locaux est si dangereux ...
Comme l'a dit @SergeBallesta, c'est une mauvaise pratique. Le compilateur ne vous a-t-il pas averti que les variables locales cachaient les globaux? Sinon, examinez l'activation des avertissements du compilateur. Ils vous éviteront beaucoup de chagrin à l'avenir.
Merci beaucoup, je vais essayer de changer mes paramètres de compilateur.