Pass struct by reference in C

后端 未结 5 646
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-13 02:28

Is this code correct? It runs as expected, but is this code correctly using the pointers and dot notation for the struct?

struct someStruct {
 unsigned int t         


        
相关标签:
5条回答
  • 2020-12-13 02:43

    Your use of pointer and dot notation is good. The compiler should give you errors and/or warnings if there was a problem.

    Here is a copy of your code with some additional notes and things to think about so far as the use of structs and pointers and functions and scope of variables.

    Note: A code writing difference in the source example below is I put a space after the struct name and before the asterisk in the function definition/declaration as in struct someStruct *p1; and the OP put a space after the asterisk as in struct someStruct* p1;. There is no difference to the compiler, just a readability and habit difference for the programmer. I prefer putting the asterisk next to the variable name to make clear the asterisk changes the variable name it is next to. This is especially important if I have more than one variable in a declaration or definition. Writing struct someStruct *p1, *p2, var1; will create two pointers, p1 and p2, and a variable, var1. Writing struct someStruct* p1, p2, var1; will create single pointer, p1 and two variables p2 and var1

    // Define the new variable type which is a struct.
    // This definition must be visible to any function that is accessing the
    // members of a variable of this type.
    struct someStruct {
        unsigned int total;
    };
    
    /*
     * Modifies the struct that exists in the calling function.
     *   Function test() takes a pointer to a struct someStruct variable
     *   so that any modifications to the variable made in the function test()
     *   will be to the variable pointed to.
     *   A pointer contains the address of a variable and is not the variable iteself.
     *   This allows the function test() to modify the variable provided by the
     *   caller of test() rather than a local copy.
     */
    int test(struct someStruct *state) {
        state->total = 4;
        return 0;
    }
    
    /* 
     * Modifies the local copy of the struct, the original
     * in the calling function is not modified.
     * The C compiler will make a copy of the variable provided by the
     * caller of function test2() and so any changes that test2() makes
     * to the argument will be discarded since test2() is working with a
     * copy of the caller's variable and not the actual variable.
     */
    int test2(struct someStruct state) {
        state.total = 8;
        return 0;
    }
    
    int test3(struct someStruct *state) {
        struct someStruct  stateCopy;
        stateCopy = *state;    // make a local copy of the struct
        stateCopy.total = 12;  // modify the local copy of the struct
        *state = stateCopy;    /* assign the local copy back to the original in the
                                  calling function. Assigning by dereferencing pointer. */
        return 0;
    }
    
    int main () {
        struct someStruct s;
    
        /* Set the value then call a function that will change the value. */
        s.total = 5;
        test(&s);
        printf("after test(): s.total = %d\n", s.total);
    
        /*
         * Set the value then call a function that will change its local copy 
         * but not this one.
         */
        s.total = 5;
        test2(s);
        printf("after test2(): s.total = %d\n", s.total);
    
        /* 
         * Call a function that will make a copy, change the copy,
           then put the copy into this one.
         */
        test3(&s);
        printf("after test3(): s.total = %d\n", s.total);
    
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-13 02:46

    Yes, its correct usage of structures. You can also use

    typedef struct someStruct {
     unsigned int total;
    } someStruct;
    

    Then you won't have to write struct someStruct s; again and again but can use someStruct s; then.

    0 讨论(0)
  • 2020-12-13 02:57

    That's correct usage of the struct. There are questions about your return values.

    Also, because you are printfing a unsigned int, you should use %u instead of %d.

    0 讨论(0)
  • 2020-12-13 03:04

    Yep. It's correct. If it wasn't (from the . / -> point of view), your compiler would yell.

    0 讨论(0)
  • 2020-12-13 03:05

    Yes, that's right. It makes a struct s, sets its total to 5, passes a pointer to it to a function that uses the pointer to set the total to 4, then prints it out. -> is for members of pointers to structs and . is for members of structs. Just like you used them.

    The return values are different though. test should probably be void, and main needs a return 0 at its end.

    0 讨论(0)
提交回复
热议问题