wake-up-neo.com

Übergeben Sie struct by reference in C

Ist dieser Code korrekt? Es wird wie erwartet ausgeführt, aber verwendet der Code die Zeiger und Punktnotation für die Struktur korrekt?

struct someStruct {
 unsigned int total;
};

int test(struct someStruct* state) {
 state->total = 4;
}

int main () {
 struct someStruct s;
 s.total = 5;
 test(&s);
 printf("\ns.total = %d\n", s.total);
}
27
Donald

Ihre Verwendung der Zeiger- und Punktnotation ist gut. Der Compiler sollte Fehler und/oder Warnungen anzeigen, wenn ein Problem aufgetreten ist.

Hier ist eine Kopie Ihres Codes mit einigen zusätzlichen Hinweisen und Hinweisen zum Nachdenken über die Verwendung von Strukturen und Zeigern und Funktionen sowie den Umfang von Variablen.

// 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;
}
45

Das ist die korrekte Verwendung der struct. Es gibt Fragen zu Ihren Rückgabewerten.

Da Sie ein vorzeichenloses int drucken, sollten Sie %u anstelle von %d verwenden.

15
Bill Lynch

Ja, das ist richtig. Es macht eine Struktur s, setzt die Summe auf 5, übergibt einen Zeiger darauf an eine Funktion, die mit dem Zeiger die Summe auf 4 setzt, und druckt sie dann aus. -> ist für Mitglieder von Zeigern auf Strukturen und . ist für Mitglieder von Strukturen. So wie du sie benutzt hast.

Die Rückgabewerte sind jedoch unterschiedlich. test sollte wahrscheinlich ungültig sein und main benötigt am Ende einen return 0.

3
nmichaels

Ja. Es ist richtig. Wenn dies nicht der Fall wäre (aus Sicht der./->), würde Ihr Compiler schreien.

1
Raveline

Ja, die korrekte Verwendung von Strukturen. Sie können auch verwenden

typedef struct someStruct {
 unsigned int total;
} someStruct;

Dann müssen Sie nicht struct someStruct s; immer wieder schreiben, sondern können someStruct s; verwenden.

0
Waqar Rashid