Thread: Passing pointers into function

  1. #1
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174

    Passing pointers into function

    I want to scan numbers in from within a function, but have access to them in main, so I tried using pointers to do so:


    Code:
    // Path Of Exile socket colours simulation
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define TRUE 0==0
    #define FALSE 0==1
    #define RED 0
    #define GREEN 1
    #define BLUE 2
    #define ALL 3
    
    int isNum(char *s);
    int scanSockets(int *colourP[ALL], int sockets);
    
    int main(int argc, char **argv) {
        if (argc != 2 || isNum(argv[1]) == FALSE) {
            fprintf(stderr, "Format: ./poeChrom <num simulations>\n");
            return 1;
        }
    
        int sockets;
        int colour[ALL] = {0};
        int *colourP[ALL] = {&colour[RED], &colour[GREEN], &colour[BLUE]};
        int flag = FALSE;
        
        printf("\n\tNumber of linked sockets: ");
        scanf("%d", &sockets);
        printf("\t-----\n\tSockets that are wished for\n"
               "\t(format \"<R num> <G num> <B num>\" in that order)\n"
               "\te.g. 1 2 2 for 1R 2G 2B: ");
               
        if (scanSockets(colourP[ALL], sockets) == FALSE) {
            fprintf(stderr, "Invalid entry\n\n");
            return EXIT_FAILURE;
        } else
            printf("SUCCESS\n");
    
        return EXIT_SUCCESS;;
    }
    
    int isNum(char *s) {
        
        for (; *s != '\0'; s++)
            if (*s < '0' || *s > '9') return FALSE;
    
        return TRUE;
    }
    
    int scanSockets(int *colourP[ALL], int sockets) {
        int colour[ALL];
        int i, scan, valid = TRUE;
        int sum = 0;
        
        scan = scanf("%d %d %d", colour[RED], colour[GREEN], colour[BLUE]);
        if (scan != 3)
            return FALSE;
            
        for (i=0; i<ALL; i++) {
            if (colour[i] < 0) valid = FALSE;
            sum += colour[i];
        }
        if (sum == 0 || sum > sockets) valid = FALSE;
        
        for (i=0; i<ALL; i++) *colourP[i] = colour[i];
        //printf("IN FUNC = %d %d %d\n", colour[RED], colour[GREEN]
        //                                        , colour[BLUE]);
        
        return valid;
    }

    But I'm getting the errors

    poeChrom.c: In function ‘main’:
    poeChrom.c:34:5: warning: passing argument 1 of ‘scanSockets’ from incompatible pointer type [enabled by default]
    poeChrom.c:15:5: note: expected ‘int **’ but argument is of type ‘int *’
    poeChrom.c: In function ‘scanSockets’:
    poeChrom.c:56:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat]
    poeChrom.c:56:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 3 has type ‘int’ [-Wformat]
    poeChrom.c:56:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 4 has type ‘int’ [-Wformat]

    If you can't follow what I'm trying to do, just ask and I'll try my best to explain it. Thanks!

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    If I understand your intent you don't need colourP at all. Just pass colour to your function and don't declare another colour in it. And you need ampersands in front of colour[RED], etc., in your scanf.

    ALL would be better named NUM_COLOURS.

    You'll want to put parens around 0==0 and 0==1 in your defines (or simply use 1 and 0). A nicer way to do this is
    Code:
    enum BOOL {FALSE, TRUE};
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by oogabooga View Post
    If I understand your intent you don't need colourP at all. Just pass colour to your function and don't declare another colour in it. And you need ampersands in front of colour[RED], etc., in your scanf.

    ALL would be better named NUM_COLOURS.

    You'll want to put parens around 0==0 and 0==1 in your defines (or simply use 1 and 0). A nicer way to do this is
    Code:
    enum BOOL {FALSE, TRUE};
    You, also, don't want #define FALSE (0==0) at all, because that expression is, well, true

  4. #4
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    It looks like the following call is wrong:

    Code:
    scanSockets(colourP[ALL], sockets)
    colourP[ALL] is a single member of the array when you probably want to pass the array itself to the function

    Code:
    scanSockets(colourP, sockets)

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    If you want false and true the standard way is the following

    Code:
    #include <stdbool.h>
    
    ...
    
    bool x = true;
    if (x)
       ...

  6. #6
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174
    Quote Originally Posted by oogabooga View Post
    If I understand your intent you don't need colourP at all. Just pass colour to your function and don't declare another colour in it.
    That won't do because I'm going to be using the numbers I scanned in not only in the function, but later on outside of the function too.

    Quote Originally Posted by oogabooga View Post
    And you need ampersands in front of colour[RED], etc., in your scanf.
    Yes, thanks for spotting that.

    Quote Originally Posted by oogabooga View Post
    ALL would be better named NUM_COLOURS.
    I'll be using it a lot and would rather stick to the shorter word, but I'll keep that in mind.

    Quote Originally Posted by oogabooga View Post
    You'll want to put parens around 0==0 and 0==1 in your defines (or simply use 1 and 0). A nicer way to do this is
    Code:
    enum BOOL {FALSE, TRUE};
    Are the parenthesis necessary? And how do I use that enum line exactly?

    Quote Originally Posted by c99tutorial View Post
    It looks like the following call is wrong:

    Code:
    scanSockets(colourP[ALL], sockets)
    colourP[ALL] is a single member of the array when you probably want to pass the array itself to the function

    Code:
    scanSockets(colourP, sockets)
    Yes thank you! That's exactly what I needed. It all works as intended now

  7. #7
    misoturbutc Hodor's Avatar
    Join Date
    Nov 2013
    Posts
    1,787
    Quote Originally Posted by Mentallic View Post
    Are the parenthesis necessary?
    Yes, they are.

    Consider:

    Code:
    #define TRUE 0==0
    
    //...
    
    int a = 5;   // It doesn't matter what value a is, it's just a test
    
    if (a == TRUE) {
        // Do something
    }
    After macro expansion the code will look like this (minus the comments)

    Code:
    #define TRUE 0==0
    
    //...
    
    int a = 5;   // It doesn't matter what value a is, it's just a test
    
    if (a == 0 == 0) {
        // Do something
    }
    A more classic example would be something like

    Code:
    #define A 4
    #define B 6
    #define TOTAL A + B
    
    printf("Half of the total is %d\n", TOTAL / 2);
    Yielding

    Code:
    printf("Half of the total is %d\n", 4 + 6 / 2);
    Which is incorrect due to operator precedence. (It will print 7 rather than the expected answer of 5)
    Last edited by Hodor; 12-04-2013 at 05:25 PM.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If you don't want to (or cannot, because you are compiling with respect to pre-C99) use what is provided by <stdbool.h>, and if you don't want to use the enum solution, then you might as well go with:
    Code:
    #define TRUE 1
    #define FALSE 0
    since (0 == 0) will definitely evaluate to 1 and (0 == 1) will definitely evaluate to 0.
    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

  9. #9
    Registered User
    Join Date
    Mar 2010
    Location
    Australia
    Posts
    174
    Thanks Hodor, that makes a lot of sense now.

    Quote Originally Posted by laserlight View Post
    If you don't want to (or cannot, because you are compiling with respect to pre-C99) use what is provided by <stdbool.h>, and if you don't want to use the enum solution, then you might as well go with:
    Code:
    #define TRUE 1
    #define FALSE 0
    since (0 == 0) will definitely evaluate to 1 and (0 == 1) will definitely evaluate to 0.
    If I use
    Code:
    enum BOOL {FALSE, TRUE}
    then I'm guessing FALSE is replaced with 0 and TRUE with 1, right? But do I also need to add this enum line in all of the functions that I want to use it in? The benefit of the define is that I just need to write it once before my main function.

    I used to use 0 and 1, but then our new professor seemed to prefer equalities and it just caught on. I'm not sure why he prefers it now that I think about it.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Mentallic
    I'm guessing FALSE is replaced with 0 and TRUE with 1, right?
    Yes. Well, not exactly a "dumb" text replacement like a macro, but those will be the corresponding values.

    Quote Originally Posted by Mentallic
    But do I also need to add this enum line in all of the functions that I want to use it in?
    No, the enum was defined at file scope hence it is in the scope of all the functions in the file. If you have multiple source files, you would place this enum in a header.

    Quote Originally Posted by Mentallic
    I used to use 0 and 1, but then our new professor seemed to prefer equalities and it just caught on. I'm not sure why he prefers it now that I think about it.
    Perhaps he simply was not aware that (0 == 0) == 1 and hence had the worry that some other non-zero value might be used to denote "true".
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Pointers - Passing to function
    By kerrymaid in forum C Programming
    Replies: 2
    Last Post: 07-06-2010, 08:01 AM
  2. Passing array to function using pointers
    By nowber in forum C Programming
    Replies: 2
    Last Post: 10-19-2009, 02:08 PM
  3. Replies: 9
    Last Post: 10-15-2008, 03:08 AM
  4. Passing array of pointers to function
    By phennings in forum C Programming
    Replies: 5
    Last Post: 09-29-2007, 11:45 AM
  5. Passing function pointers
    By keira in forum C Programming
    Replies: 6
    Last Post: 09-29-2007, 03:55 AM