0
#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 at

i = 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 = 8

So 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 this

decrypt(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.

  • 2
    try compiling with `-Wshadow`, if you are using gcc. – Duck Dodgers Jan 02 '19 at 12:38
  • 3
    You forget the assignment in `i = i + j`. In the second call to `crypt` the value of the global `i` is no longer `3`. – Some programmer dude Jan 02 '19 at 12:39
  • `return ( i = i + j ), there's no i in this function so i = 3 + 10... returns 13?` You have already changed the global `i` to `8` in the previous call to crypt. So `i` is 8 now – Karthick Jan 02 '19 at 12:39
  • 2
    And all that explains why playing with globals and partially hiding them in locals is so dangerous... – Serge Ballesta Jan 02 '19 at 12:43
  • As @SergeBallesta said, this is a bad practice. Did you compiler not warn you that the local variables were hiding the globals? If not, look into enabling compiler warnings. They will save you a lot of grief in future. – Tim Randall Jan 02 '19 at 13:42
  • Thank you guys so much, I'll look into changing my compiler settings. – Nattymaths Jan 02 '19 at 15:01

4 Answers4

1

You write:

return ( i = i + j ), there's no i in this function so i = 3 + 10... returns 13?

No, i is not 3 anymore. It was changed to 8 previously, i.e. here return (i = i+j); due to the first call of crypt

When you write:

So the i in the main function becomes 8.

it's correct but the global i was changed as well.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • Ahh thank you! I see where I went wrong. I completely forgot about the ( i = i+j) affecting the global variable. – Nattymaths Jan 02 '19 at 15:01
0

You have here a global i and j, and a local i var. In the main when ever you refer to i, it first checks your current scope - so any changes there will be made on your local i, and the global i will not change. if you ask a function out side of main to do something with i var, it checks its own scope first, and then checks for global i var. in this case the changes that will be made are on the global i.

So.. first time-

local i is set in main and then receives the value of i = crypt(5); another thing is that in this function you also assign the 8 value to the global i-> (i = i+j), before returning the 8 value to the local i.

second function:

decrypt(i, j); here you send the local i(= 8) and global j(=10) to the function, in it you have:

j += crypt(i);
which gives you j= j+((global) i = 8 + 10): 10+8+10. and also set your global i to 18.

H.cohen
  • 517
  • 3
  • 9
0

Global variables are declared outside any function, and they can be accessed (used) on any function in the program. Local variables are declared inside a funcion, and can be used only inside that function. It is possible to have local variables with the same name in different functions.

At the first call of function crypt(5); you have modified the global variable value to,

i = i+j ----> i = 3+5 ----> i=8

And when decrypt() function is called, i=8 Because of i is 8 j prints 28 after additon which is a global variable .

You can see how memory is allocated in C

Sujay
  • 588
  • 6
  • 15
0

Consider the following version of the code, where variables have been renamed to avoid any 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;
}

Now, it should be relatively easy to explain what happens when the code is executed:

  1. In main(), iLocal is zet to 0
  2. main calls crypt(5)
  3. crypt evaluates iGlobal+jParam, i.e. 3+5, and assigns the result to iGlobal, i.e. iGlobal is 8
  4. crypt returns 8
  5. main assigns the return value of 8 to iLocal
  6. main calls decrypt(8,10)
  7. decrypt calls crypt(10)
  8. crypt evaluates iGlobal+jParam, i.e. 8+10, and assigns the result to iGlobal, i.e. iGlobal is 18
  9. crypt returns 18
  10. decrypt adds the return value of 18 to jGlobal, i.e. jGlobal is 28
  11. printf prints the values of iLocal, 8, and jGlobal, 28

The complicated part, if any, is knowing when the global variables are replaced (a.k.a. hidden, or shadowed) by their local counterparts, the answer being "whenever possible".

Tim Randall
  • 4,040
  • 1
  • 17
  • 39