Thread: Pointers and functions help

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    28

    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. #2
    Registered User dariyoosh's Avatar
    Join Date
    Nov 2012
    Location
    Iran / France
    Posts
    38
    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
    Last edited by dariyoosh; 11-29-2012 at 02:04 AM.

  3. #3
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    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.
    Last edited by std10093; 11-29-2012 at 02:33 AM.

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    32
    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. #5
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Quote Originally Posted by Shurik View Post
    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;
    }
    Code - functions and small libraries I use


    It’s 2014 and I still use printf() for debugging.


    "Programs must be written for people to read, and only incidentally for machines to execute. " —Harold Abelson

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    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.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    32
    Quote Originally Posted by std10093 View Post
    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. #8
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Quote Originally Posted by std10093 View Post
    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. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote 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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Oct 2012
    Posts
    28
    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:
    Quote Originally Posted by dariyoosh View Post
    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.

    Quote Originally Posted by std10093 View Post
    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.

    Quote Originally Posted by hk_mp5kpdw View Post
    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.
    Added the closing parenthesis. Thanks!

    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. #11
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    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.
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointers to functions
    By rakeshkool27 in forum C Programming
    Replies: 3
    Last Post: 01-12-2010, 11:13 AM
  2. Functions and pointers
    By vidioholic in forum C Programming
    Replies: 1
    Last Post: 10-25-2007, 07:30 PM
  3. pointers to functions
    By anthonye in forum C Programming
    Replies: 2
    Last Post: 02-05-2002, 02:04 PM
  4. Replies: 1
    Last Post: 01-20-2002, 11:50 AM
  5. pointers to functions
    By canine in forum Windows Programming
    Replies: 2
    Last Post: 11-27-2001, 07:02 PM