Homework question on pointers

Pages: 12
The question reads:

"3. Write a program that includes a function int* fun( int* a, int* b, int* c) that returns a pointer to the memory containing the median value of the three variables passed by reference to the function."

The question then provides the following code:
"To test your function, use the following 'main' function. Submit all the code necessary for your function to compile."
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(void)
{
  int a = 2;
  int b = 3;
  int c = 4;

  int* pMedian;

  cout << "Address of a =" << &a << endl;
  cout << "Address of b =" << &b << endl;
  cout << "Address of c =" << &c << endl;
 
  pMedian= fun(&a, &b, &c);

  cout << "Address of the Median=" << pMedian<< endl;
  cout << "The value of the Median=" << *pMedian<< endl;

  return 1;
}


So, I wrote this function:

1
2
3
4
5
6
7
8
int *fun(int *a, int *b, int *c)
{
int ave = (( *a + *b + *c)/3);
int* pMed = &ave;
cout << "ave = " << ave << "&ave = " << &ave << endl;
cout << "pMed = " << pMed << "*pMed = " << *pMed << endl;
return (pMed);
}


I created a variable called ave. I then wrote an expression that dereferences the 3 pointers to variables passed to the function and divided them by 3. I wrote the cout lines to verify that the program actually did the right maths. Then I created a pointer named pMed that points to the address that the average is saved at. Then I outputted that just to make sure all was correct. Then I pass the pointer back to the main function. From reading around the forums, this is extremely bad practice, but it's what the question is asking, so that's what it gets.Putting it all together so it's easy to read:
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
#include <iostream>
#include <cmath>
using namespace std;

int *fun(int *a, int *b, int *c)
{
int ave = (( *a + *b + *c)/3);
int* pMed = &ave;
cout << "ave = " << ave << "&ave = " << &ave << endl;
cout << "pMed = " << pMed << "*pMed = " << *pMed << endl;
return (pMed);
}

int main(void)
{
  int a = 2;
  int b = 3;
  int c = 4;

  int* pMedian;

  cout << "Address of a =" << &a << endl;
  cout << "Address of b =" << &b << endl;
  cout << "Address of c =" << &c << endl;
 
  pMedian= fun(&a, &b, &c);

  cout << "Address of the Median=" << pMedian<< endl;
  cout << "The value of the Median=" << *pMedian<< endl;

  return 1;
}



Unfortunately, my console then outputs:


Address of a =0x7fff5fbffa6c
Address of b =0x7fff5fbffa68
Address of c =0x7fff5fbffa64
ave = 3&ave = 0x7fff5fbffa2c
pMed = 0x7fff5fbffa2c*pMed = 3
Address of the Median=0x7fff5fbffa2c
The value of the Median=32767


Without doing the conversion, I would guess that the line "The value of the Median = 32767" is actually converting the hexadecimal address of the pointer to base 10? Why else would it output 32767?

I've been banging my head against this for a while now...
Last edited on
Well, the first thing to do would be to look up what a median is. It's not an average.

In your fun function ave is a local variable that goes out of scope when the function ends. So the pointer you return points to an area of memory that is not valid after the function returns.
Me sometimes forget math terms. Me go too fast sometimes.

Ok, so the pointer is still pointing to the correct address in memory, but because the
fun
function ended, there is no longer anything stored there. Creating a global or static variable would defeat the purpose of using the pointer, but pointing to any variable inside the function will have the same result. Should the function not contain anything, and just point back to the median value? The function gets sent *a, *b, *c, the median value is b = 3, so just return b?

1
2
3
4
5
int *fun(int *a, int *b, int *c)
{

return (b);
}


Address of a =0x7fff5fbffa6c
Address of b =0x7fff5fbffa68
Address of c =0x7fff5fbffa64
Address of the Median=0x7fff5fbffa68
The value of the Median=3


Somehow I feel I will not receive credit if I do that. I don't understand this question.
The function gets sent *a, *b, *c, the median value is b = 3, so just return b?


No, you shouldn't assume that b is the median. What you need to do is programmatically figure out which int pointed to is the median, and return the pointer to that int.

Suppose the function is called like

1
2
3
4
5
int a = 2 ;
int b = 3 ;
int c = 4 ;

fun( &b, &c, &a )


Which pointer are you returning then?
I would still return b. &b is still the address of the variable b, which has a value of 3.

But your fun function doesn't receive pointers as inputs. It receives addresses of variables. If I return b, I'm not returning a pointer, I'm returning the address of b?
Last edited on
The fun function does receive pointers as inputs. Pointers hold addresses of variables.

Let me make it a little clearer:

1
2
3
4
5
int d = 2 ;
int e = 3 ;
int f = 4 ;

fun( &f, &d, &e);


If your fun defintion is:

1
2
3
4
int *fun(int *a, int *b, int *c)
{
return (b);
}


Will you be returning the correct pointer?


So in your code, &f counts as a pointer? My class was taught that a pointer is a variable that points to an address.

1
2
int Value = 5;
int* Valueptr = &Value


We can just skip to &Value?

Going back to your example, I would guess that the function accepts the arguments in the same order as those sent, even though the variable names have changed, so if you returned b, you would really be returning d, which is 2, which would b incorrect.
closed account (3qX21hU5)
Im not so good on pointers yet, (havent read to much into them yet) but it looks like you need a way to determine what int variable is the median. So why not write a simple function to determine a median of a set of ints then use that function in your fun function?

I would guess that the function accepts the arguments in the same order as those sent

Assuming is bad, since the function could except the arguments in a any order. Which is why you would need a function to determine what the median would be no matter what order the arguments are inputed
Last edited on
Then I return to a question of scope. I can write a function that does anything, but if I point to a variable within that function, that variable ceases to exist when the function ends.
To start with, not sure why main is returning 1. That program will never close.

Now, all you have to do it determine which variable refers to the median of the 3 variables, then return the address of THAT variable alone. Some form of if statement should suffice. Not really sure how you could code something to determine the median, but iirc median is the mid point between the max and min values. So your function would first have to find both of those and then then add them together and divide by 2 and see which value is equal to that. Or you can subtract min from max, add that value to min, then see which value THAT equals. Then return the address of the variable that that equals and voila.

In other words:

1
2
3
4
5
6
7
int med = (max + min)/2;
if (*a == med)
    return a;
else if (*b == med)
    return b;
else if (*c == med)
    return c;


Also, &f passes that variable by reference, meaning it passes the address of the original variable to the function. To hold the address you need a pointer. &f is not a pointer but a reference to a variable. And yes, functions receive arguments in the order they are called, to the parameters in the order they are declared in the function declaration.
Last edited on
So in your code, &f counts as a pointer? My class was taught that a pointer is a variable that points to an address.


It is correct that a pointer is a variable that holds an address. &f would be an address. The address is assigned to the first parameter (which is a pointer) in the call to fun. You did exactly the same thing with &a, &b, and &c.

The names of the parameters in the function have no relation to any names anywhere else.

Going back to your example, I would guess that the function accepts the arguments in the same order as those sent, even though the variable names have changed, so if you returned b, you would really be returning d, which is 2, which would b incorrect.


Sound reasoning. It holds true for the example I gave where the names of the variables were the same as the names of the parameters to the function. When the address of b in main was fed to the function, it was supplied in the variable a inside the function. So returning b from the function, would've been incorrect.

which would b incorrect.


Was funnier than you gave me credit for.

To start with, not sure why main is returning 1. That program will never close.


This part was supplied by the question. We always end with return 1. My programs seem to end just fine.

There are plenty of algorithms for determining the median of a range of numbers; googling 'median algorithm' should return more than you can read in an evening. I'm not worried about writing a median function, it's pointers that I don't get. Which, returning to that, no matter what function I write, like I said above, won't the variable I point to be meaningless, like in the first iteration? If b (or any variable) is defined in main, and passed to fun, I still have to somehow point back to the pointer. In the end, won't I always have to return one of the variables that was sent?

I think this is a very clumsy question. Using pointers in this way is a recipe for circular logic. I think I'm starting to see what it wants me to see, but this would be more fun as an array.
Last edited on
To start with, not sure why main is returning 1. That program will never close.


Not correct. The return value has no effect on the closing of the program.

A return value of 0 indicates all went well, any other value indicates a problem of some kind. This is handy if you are writing a script that runs your program. You can test the return value, and take action if all is not well.

This part was supplied by the question. We always end with return 1. My programs seem to end just fine.


You should return 0 if all is well, something else otherwise.
1
2
3
4
int * some_func(int* n)
{
    return n ;
}


Do we take the address of anything here? So are we dealing with the address of a local variable?
Ah right, my bad TIM.

Which, returning to that, no matter what function I write, like I said above, won't the variable I point to be meaningless, like in the first iteration? If b (or any variable) is defined in main, and passed to fun, I still have to somehow point back to the pointer. In the end, won't I always have to return one of the variables that was sent?


You already have 3 pointers declared in the function. Each one points back to a variable you passed to it. So all you have to do is determine which address points to the median value and return that address back to pMedian.
Last edited on
Do we take the address of anything here?


I feel like no. The * means a pointer, so this function's input is coming from a specific block of memory, reserved by the variable 'n.'

So are we dealing with the address of a local variable?


As far as some_func is concerned, n is a global variable, sent by something more powerful than itself.


I feel like no. The * means a pointer, so this function's input is coming from a specific block of memory, reserved by the variable 'n.'

This function's "input," which is an address, is stored in the variable n. All the function does is return the address that's fed to it.


As far as some_func is concerned, n is a global variable, sent by something more powerful than itself.

n is a local variable. If it were considered a global variable, we might be tempted to return a pointer to it since it's scope would be larger than that of the function, which would be wrong.
@Raezzor
Ah right, my bad TIM.


I forgot to mention it is confusing because it is opposite to C / C++. In C / C++ 0 is false, but for a program return value, 0 means all OK, this is an OS thing. Maybe this explains the OP's misconception?

Don't worry, I have been making multiple silly screwups today (much worse than your minor one), and you have been giving good advice during your time on the forum

Cheers

@macleight

I am not sure whether you know all this already, but here goes.....

Pointers and references are bit confusing because of the multiple meanings of the operators.

* declares a pointer type , and dereferences it as well.
& takes the address of a variable - this can be assigned to a pointer variable.

& also specifies a reference .

http://www.cprogramming.com/tutorial/references.html
So, round two. Or eight. I don't know, I don't care. I hate this problem and I hate this pointer shit and I don't want to do it anymore.

I added some logic to my function, so that it would determine which value was the median. Obviously, it would only work for three values, but actual median algorithms are a bit too powerful for this.

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
#include <iostream>
#include <cmath>
using namespace std;

int *fun(int *b, int *a, int *c)
{
if (&a > &c && &b > &a)
return a;
else if (&b > &c && &a > &b)
return b;
else if (&c > &b && &a > &c)
return c;
}

int main(void)
{
  int a = 2;
  int b = 3;
  int c = 4;

  int* pMedian;

  cout << "Address of a =" << &a << endl;
  cout << "Address of b =" << &b << endl;
  cout << "Address of c =" << &c << endl;
 
  pMedian= fun(&a, &c, &b);

  cout << "Address of the Median=" << pMedian<< endl;
  cout << "The value of the Median=" << *pMedian<< endl;

  return 1;
}


The reasoning behind this is that the function is being passed three arguments, all pointers to variables declared inside the main function. The function also has to be labeled with a *, because otherwise the compiler bitches about converting int* to int or vice versa, but I don't understand that part because the function isn't a pointer, it's a function. Anyways, it receives the three variables, then goes about executing the if/else if statements. It then returns the correct if statement.

EXCEPT NOT.

What it does return seems to be dependent on this line:

 
pMedian= fun(&a, &c, &b);


Whichever value is passed in the middle slot is the value that is returned. I have swapped everything else around and this is the one that changes it.

Also, the code still doesn't 'return a pointer' as the question demands. Which I still don't get. Everytime I try to tell it to

 
return *a;


or *b or anything, it says invalid conversion of int to int*. It will only return a pointer if only pointers are used.

Seriously, I'm so over this. Thank you for helping me, and know that I will never, EVER make use of this knowledge once I pass this question.
1
2
3
4
5
6
7
8
9
int *fun(int *b, int *a, int *c)
{
    if (&a > &c && &b > &a)
        return a;
    else if (&b > &c && &a > &b)
        return b;
    else if (&c > &b && &a > &c)
        return c;
}


You are comparing the addresses of the pointers. Compare what is pointed to.
Pages: 12