-2

I am having trouble understanding how to obtain the correct values outputted by the following C++ code when trying to solve it by hand.

#include <iostream>
using namespace std;

int f(int a, int & b,int *c){
    a += 1;
    b += 3;
    *c += 4;
    return a+b+(*c);
}
int main() {
    int a = 3, b = 4,c = 5;
    cout << "total: " << f(b,c,&a) << endl;
    cout << "a= " << a << " b= " << b << " c= " << c << endl;
    
    a = 3, b = 4,c = 5;
    cout << "total: " << f(a,a,&a) << endl;
    cout << "a= " << a << " b= " << b << " c= " << c << endl;
    return 0;
}

I know the result should be:

total: 20
a= 7 b= 4 c= 8
total: 24
a= 10 b= 4 c= 5

But everytime I try to solve this code by hand (attempt to write out the steps and assignments on a piece of paper) I can't seem obtain the correct total or values. Can anyone help me understand what is happening inside the function with a, b, and c (maybe a step-by-step explanation?). There must be something I am not understanding with the referencing/dereferencing or the pointers that is causing mistakes in my logic. Even ChatGPT is spitting out the incorrect answer after trying to execute the code...

For example if I try the first set of of inputs inside the function, here's what I understand:

  • int a = 4;
  • int &b = 5; //since c = 5
  • int *c = &a; //&a = 3

Then I start to execute the body of the function:

  • a += 1 now gives me a = 5;
  • b += 3 now gives me c = 8 since b is a reference to c so it really only is c that changes;
  • *c += 4 now takes the value stored in &a initialized as 3 and adds 4 so a's new value is 7;

The final tally is a = 7, b = 4 (hasn't changed), and c = 8. These values are correct, but the return portion of the function does not work with these values:

a+b+(*c) should be 7+4+(7), but the result of that is 18, while the correct answer is 20.

What's worst is that if I use the same logic for the second time the function is called, my values are incorrect but my total is correct... I'm lost.

  • 1
    We can't debug your program for you. Use a debugger. [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) – Jason Feb 20 '23 at 03:58
  • `a = 3, b = 4,c = 5;` This is... suspect – Nicol Bolas Feb 20 '23 at 03:59
  • @NicolBolas I think it's just to reset the int values back to their original states for the second time the function is called since the function changes the values after executed. – user21247827 Feb 20 '23 at 04:02
  • 2
    Btw `int &b = 5;` is not valid in c++. You can/should use a **debugger** instead of doing it by hand. – Jason Feb 20 '23 at 04:02
  • @JasonLiam I am not asking someone to debug my code, I am asking for someone to explain the results since I am trying to better understand what is going on under the hood with this function. The code contains no errors, but my logic does. – user21247827 Feb 20 '23 at 04:04
  • 1
    @user21247827 the way programmers typically understand program behavior that is confusing them is by using a debugger. A debugger will show you exactly what is happening as your program runs. – Drew Dormann Feb 20 '23 at 04:05
  • 1
    Well, we can't tell you what's wrong with the "steps and assignments on a piece of paper" that you wrote out, unless you show what, exactly, those steps and assignments. Can you [edit] your question and include what you believe is happening, and I'm confident that someone will point out the exact error. If you would like for someont to "explain" and help you "understand what is going on", then you need to show what you believe "is going on", so that others can help you "understand". – Sam Varshavchik Feb 20 '23 at 04:05
  • @SamVarshavchik the second part of my post attempts to show what steps I am doing when trying to arrive at the solution. I'm not sure what else to add to this post to better show my steps. – user21247827 Feb 20 '23 at 04:07
  • 2
    @user21247827: "*I am not asking someone to debug my code, I am asking for someone to explain the results*" That's what "debugging" *is*: it's what you do when your code produces a result inconsistent with the result you expected. – Nicol Bolas Feb 20 '23 at 04:11
  • I suspect the OP has caused self-confusion by using the same names in both `main()` and the function arguments. For example, the call `f(b,c,&a)` causes `b` to become `a` (in the function `f()`), `c` to become `b`, and `a` to become `*c`. – Peter Feb 20 '23 at 04:15
  • @SamVarshavchik and Peter thank you very much for your comments! Changing the names of the variables in the function to x, y, z has made everything infinitely easier to understand! Thank you for taking the time to break down what I was doing wrong! – user21247827 Feb 20 '23 at 04:28

2 Answers2

2

The final tally is a = 7, b = 4 (hasn't changed), and c = 8. These values are correct, but the return portion of the function does not work with these values:

What is getting you tripped up is that a, b, and c in your main are not the same as a, b, and c in the f(). The

return a+b+(*c);

Uses what f() knows as a, b, and c. This is part of f(). f()'s variables is the only thing that this return statement knows anything about, and it has absolutely no knowledge at all, whatsoever, about any variables in main. So to know what these variables are you just have to reread what you wrote yourself:

a += 1 now gives me a = 5;

b += 3 now gives me c = 8 since b is a reference

but this b, right here is the very exact, same b that's in the return expression.

*c += 4 now takes the value stored in &a initialized as 3 and adds 4 so a's new value is 7;

But this is the c in the expression. So

return a+b+(*c);

computes 5+8+7 or 20, as you've observed.

The second expression works the same way.

You're getting tripped up by the fact that f()'s variables use the same names as the variables in main(). It also doesn't help that pointers and references from one refer to variables in the other.

It might be helpful for you to rename the variables in f():

int f(int x, int & y,int *z){
    x += 1;
    y += 3;
    *z += 4;
    return x+y+(*z);
}

This should be logically equivalent to the original function, but with less confusion.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
1

This is easiest to do with pictures, so I'll try to make some ascii art that shows what is going on.

Here is the situation just after the first call has entered f:

main   a:3   b:4   c:5
         ^           ^
         |       /---/
         |      /
 f     c:*   b:*   a:4

Here 'main' and 'f' each have their own 'a', 'b', and 'c'; and 'b' and 'c' in 'f' point at/refer to things in main's stack frame. I've reversed the order c/b/a in 'f' in order to not have crossing lines.

After the 3 adds in f, we have

main   a:7   b:4   c:8
         ^           ^
         |       /---/
         |      /
 f     c:*   b:*   a:5

In the second call to f, things look like:

main   a:3   b:4   c:5
         ^
         |\--\
         |    \
 f     c:*   b:*   a:3

and after the adds:

main   a:10   b:4   c:5
         ^
         |\--\
         |    \
 f     c:*   b:*   a:4
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226