# Thread: Pointers and functions help

1. ## Pointers and functions help

I'm currently a student taking an online C programming class, and this board has been a lifesaver. Well, it looks like I need your guys help again.

Was given a fully written code that I needed to write functions for, and I handled the first two alright (forgive any poorly scripted coding. I'm trying my best), but the compiler keeps halting on the third. I'm sure it's something simple, but I can't figure it out. Any help would be appreciated.

Code:
```#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int swapArgs(int *a,int *b);
int divideArgs(int *a, int *b);
double powerArgs(int *a, int *b);

/* MAIN */

int main(int argc, char **argv) {
if (argc != 3) {
printf("?Invalid number of arguments\n");
system("pause");
exit(1);
}
int parmA = atoi(argv[1]);

int parmB = atoi(argv[2]);

/* Part A: Swap the values.  Value in parmA is moved to parmB and vice versa */

/*         Reset the original values after we print the result */

printf("A=%d, B=%d. ",parmA,parmB);

swapArgs(&parmA,&parmB);

parmA = atoi(argv[1]);

parmB = atoi(argv[2]);

/* Part B: Divide parmA by parmB.  Put the quotient in parmA, remainder in parmB */

/*         Reset the original values after we print the result */

printf("Quotient of %d / %d is ",parmA,parmB);

divideArgs(&parmA, &parmB);

parmA = atoi(argv[1]);

parmB = atoi(argv[2]);

/* Part C: Raise parmA to the power of parmB.  Return pointer to the result */

/*         Reset the original values after we print the result */

printf("%d raised to the %d power is ",parmA,parmB);
printf("%.0lf \n", *powerArgs(&parmA, &parmB);

return 0;

}

int swapArgs(int *a, int *b)
{
int tempA = *a, tempB = *b;
*a = tempB;
*b = tempA;

printf("Your first number is now %d, and your second is now %d\n", *a, *b);

*a = tempA;
*b = tempB;
}

int divideArgs(int *a, int *b)
{
int tempA = *a, tempB = *b;
double divisor = *a / *b;

*a = (long) divisor;
*b = divisor - *a;

printf("%d, with the remainder being %f\n", *a, *b);

*a = tempA;
*b = tempB;
}

double powerArgs(double *a, double *b)
{
double powerArgs = pow ((double) *a, (double) *b);
return powerArgs;
}```

2. What is exactly the error message you get when compiler halts upon the third function (therefore powerArgs I guess)?

Also doing casting to double while calling the pow function (in powerArgs) seems to me to be unnecessary as the formal parameters of powerArgs are already double.

Regards,
Dariyoosh

3. This may cause the problem.
Code:
`printf("%.0lf \n", *powerArgs(&parmA, &parmB);`
The function returns a double, as a result you need to get rid of the asterisk, like this
Code:
`printf("%.0lf \n", powerArgs(&parmA, &parmB);`
Edit: Comment about the swap? Do you really need to temp variables?
Can't you do it like this?

Example

Code:
```void swap(int*a , int*b)
{
int temp = *a;
*a = *b;
*b = *temp;
}```
Note that the swapping can also be done with no extra variable in simple cases.

4. In C you can't use same name for function and variable in this function.
Just write:
Code:
`double powerArgs(double *a, double *b) {     return pow (*a, *b); }`

5. Originally Posted by Shurik
In C you can't use same name for function and variable in this function.
Not true.

Counter example follows.
Code:
```#include <stdio.h>

int foo(int a)
{
int foo = a;
return foo;
}

int main(void)
{
int a;

a= foo(5);

printf("%d\n",a);

return 0;
}```

6. Code:
```int parmA = atoi(argv[1]);

int parmB = atoi(argv[2]);

/* Part C: Raise parmA to the power of parmB.  Return pointer to the result */

/*         Reset the original values after we print the result */

printf("%d raised to the %d power is ",parmA,parmB);
printf("%.0lf \n", *powerArgs(&parmA, &parmB);

...

double powerArgs(double *a, double *b)
{
double powerArgs = pow ((double) *a, (double) *b);
return powerArgs;
}```
The call of the powerArgs function has a couple problems beyond those that may have been discussed already. The first is that the printf line contains 2 open parenthesis but only 1 closing parenthesis. The second is that parmA and parmB are type int but you are passing them to a function that expects type double* for some reason. For what the function does, there is no reason to pass any pointers into this function at all, you can simply pass the values.

Code:
```/* Part B: Divide parmA by parmB.  Put the quotient in parmA, remainder in parmB */

/*         Reset the original values after we print the result */

printf("Quotient of %d / %d is ",parmA,parmB);

divideArgs(&parmA, &parmB);

parmA = atoi(argv[1]);

parmB = atoi(argv[2]);

...

int divideArgs(int *a, int *b)
{
int tempA = *a, tempB = *b;
double divisor = *a / *b;

*a = (long) divisor;
*b = divisor - *a;

printf("%d, with the remainder being %f\n", *a, *b);

*a = tempA;
*b = tempB;
}```
Your divideArgs function does not return a value like you say it should. Though it probably should not do so anyway as mentioned in my next paragraph below.

The divideArgs function itself seems a poor place to be doing output directly as your functions seem to be mixing behavior - divideArgs outputs a value and is supposed to return a value but does not and on the other hand the powerArgs function is returning a value which you are attempting to print elsewhere (incorrectly)... this can be confusing. Given what the function does, I would calculate the result and remainder of the division and pass these back through the input parameters. Back in main I would then print the modified parmA/parmB before doing the reset. The function would not need a return value in this case. You might want to add a check so you don't attempt a divide by 0.

You are also doing integer division and assigning this result to a double and then casting the double to a long and then assigning back to an int. WTF?

You are also printing an int using a %f (float) specifier.

Code:
```/* Part A: Swap the values.  Value in parmA is moved to parmB and vice versa */

/*         Reset the original values after we print the result */

printf("A=%d, B=%d. ",parmA,parmB);

swapArgs(&parmA,&parmB);

parmA = atoi(argv[1]);

parmB = atoi(argv[2]);```
According to the description for part A, shouldn't you do the swap before you print the values and then reset parmA/parmB?

Boy, the more I look the more I find. This needs some serious work/redesign.

7. Originally Posted by std10093
Not true.

Counter example follows.
Code:
```#include <stdio.h>

int foo(int a)
{
int foo = a;
return foo;
}

int main(void)
{
int a;

a= foo(5);

printf("%d\n",a);

return 0;
}```
Wow! I didn't know that.
Thanks

8. Originally Posted by std10093
Not true.

Counter example follows.
That makes no sense that the compiler would allow that. What if you wanted to pass 'foo' as a parameter, say, to qsort which expects a function. Or later you wanted to pass 'foo' to another function as a variable? How would the compiler know which interpretation is the one you intended?

9. Originally Posted by nonoob
That makes no sense that the compiler would allow that. What if you wanted to pass 'foo' as a parameter, say, to qsort which expects a function. Or later you wanted to pass 'foo' to another function as a variable? How would the compiler know which interpretation is the one you intended?
It looks like just a case of name hiding, e.g., the effect you get when you declare a variable of the same name as another variable in an outer scope.

10. Thank you for all the responses. Some clarification may be needed. I was given the main, and then asked to write the functions to fit it. The only thing I've done is add math.h, and written the prototypes & functions. Please forgive me if I miss some (to you) simple things. I'm still learning.

As for specific questions:
Originally Posted by dariyoosh
What is exactly the error message you get when compiler halts upon the third function (therefore powerArgs I guess)?
As noted below, I only had one closing parenthesis. Now that I've added a second, I get this:

|58|error: pointer value used where a floating point value was expected|

I've tried casting them as double, setting the function as int, creating an output that was double. And none of it seems to be working.

Also doing casting to double while calling the pow function (in powerArgs) seems to me to be unnecessary as the formal parameters of powerArgs are already double.
I was taught that you always had to cast the two values as double, even if they were already double, for pow to work properly.

Originally Posted by std10093
This may cause the problem.
Code:
`printf("%.0lf \n", *powerArgs(&parmA, &parmB);`
The function returns a double, as a result you need to get rid of the asterisk, like this
Code:
`printf("%.0lf \n", powerArgs(&parmA, &parmB);`
I agree, but I have to use what I was given. I figured it was something that I'd missed, but putting a pointer there for the function name just completely baffled me.

Comment about the swap? Do you really need to temp variables?
Can't you do it like this?

Example

Code:
```void swap(int*a , int*b)
{
int temp = *a;
*a = *b;
*b = *temp;
}```
Note that the swapping can also be done with no extra variable in simple cases.
I was a little tired when I wrote it. Second variable has been removed.

Originally Posted by hk_mp5kpdw
Code:
```int parmA = atoi(argv[1]);

int parmB = atoi(argv[2]);

/* Part C: Raise parmA to the power of parmB.  Return pointer to the result */

/*         Reset the original values after we print the result */

printf("%d raised to the %d power is ",parmA,parmB);
printf("%.0lf \n", *powerArgs(&parmA, &parmB);

...

double powerArgs(double *a, double *b)
{
double powerArgs = pow ((double) *a, (double) *b);
return powerArgs;
}```
The call of the powerArgs function has a couple problems beyond those that may have been discussed already. The first is that the printf line contains 2 open parenthesis but only 1 closing parenthesis. The second is that parmA and parmB are type int but you are passing them to a function that expects type double* for some reason. For what the function does, there is no reason to pass any pointers into this function at all, you can simply pass the values.

Are you saying that I need to rewrite *powerArgs(&parmA, &parmB) or double powerArgs(double *a, double *b). If you mean the former, I can't. I was assigned to work with the code as-is, and short of an actual type-o (such as the parenthesis), I have to make do. If you mean the latter, I've removed the asterisks and castings, but that didnt work. I also tried casting as int and as double without the asterisks'. None of those worked. What do I need to do?

Code:
```/* Part B: Divide parmA by parmB.  Put the quotient in parmA, remainder in parmB */

/*         Reset the original values after we print the result */

printf("Quotient of %d / %d is ",parmA,parmB);

divideArgs(&parmA, &parmB);

parmA = atoi(argv[1]);

parmB = atoi(argv[2]);

...

int divideArgs(int *a, int *b)
{
int tempA = *a, tempB = *b;
double divisor = *a / *b;

*a = (long) divisor;
*b = divisor - *a;

printf("%d, with the remainder being %f\n", *a, *b);

*a = tempA;
*b = tempB;
}```
Your divideArgs function does not return a value like you say it should. Though it probably should not do so anyway as mentioned in my next paragraph below.

The divideArgs function itself seems a poor place to be doing output directly as your functions seem to be mixing behavior - divideArgs outputs a value and is supposed to return a value but does not and on the other hand the powerArgs function is returning a value which you are attempting to print elsewhere (incorrectly)... this can be confusing. Given what the function does, I would calculate the result and remainder of the division and pass these back through the input parameters. Back in main I would then print the modified parmA/parmB before doing the reset. The function would not need a return value in this case. You might want to add a check so you don't attempt a divide by 0.

You are also doing integer division and assigning this result to a double and then casting the double to a long and then assigning back to an int. WTF?

You are also printing an int using a %f (float) specifier.
I borrowed that from an older loop I had been taught so that I could produce an isolated quotient and an isolated remainder. I have subsuquintly removed the %f, as I realized it wasn't needed. Here's a question, then; Is there any way to print the result without tweaking the actual code? As far as I can tell, I need to have the printf be part of the function. Of course, I'm just beginning with pointers and functions, so I'm not quite sure how I'd make a function that doesn't have a printf, but can still return a printed value without a printf in the main function and follow that up by resetting the values. If this is workable, PLEASE let me know, because I hate how much I'm flailing at this.

Code:
```/* Part A: Swap the values.  Value in parmA is moved to parmB and vice versa */

/*         Reset the original values after we print the result */

printf("A=%d, B=%d. ",parmA,parmB);

swapArgs(&parmA,&parmB);

parmA = atoi(argv[1]);

parmB = atoi(argv[2]);```
According to the description for part A, shouldn't you do the swap before you print the values and then reset parmA/parmB?

This is to show the user what numbers they input. swapArgs outputs the switched numbers.

Boy, the more I look the more I find. This needs some serious work/redesign.
Well, I didn't write the main, and the functions are the best I can do right now, so you'll have to forgive me if they're awful.

11. Ok so... The error with the printf was given to you. It may be a test to find it. Put the extra bracket in for now.

If the function powerArgs puts the result in the variable a and returns the address of variable a, the printf statement will dereference the address and print the result.