Передать структуру по ссылке в C - PullRequest
29 голосов
/ 30 ноября 2010

Этот код правильный? Он работает, как ожидалось, но правильно ли этот код использует указатели и точечные обозначения для структуры?

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);
}

Ответы [ 5 ]

50 голосов
/ 26 октября 2012

Вы хорошо используете указатель и точечную нотацию. Компилятор должен выдавать вам ошибки и / или предупреждения в случае возникновения проблемы.

Вот копия вашего кода с некоторыми дополнительными примечаниями и вещами, о которых следует подумать, в том числе об использовании структур и указателей, функций и области видимости переменных.

// 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;
}
15 голосов
/ 30 ноября 2010

Это правильное использование структуры. Есть вопросы о ваших возвращаемых значениях.

Кроме того, поскольку вы печатаете неподписанное целое, вы должны использовать %u вместо %d.

3 голосов
/ 30 ноября 2010

Да, все верно. Он создает структуру s, устанавливает ее итоговое значение 5, передает указатель на нее в функцию, которая использует указатель для установки итогового значения 4, а затем распечатывает ее. -> - для членов указателей на структуры, а . - для членов структур. Так же, как вы их использовали.

Хотя возвращаемые значения отличаются. test, вероятно, должно быть недействительным, а main нуждается в return 0 в конце.

1 голос
/ 30 ноября 2010

Да.Это правильно.Если бы это не было (с точки зрения. / ->), ваш компилятор выкрикнул бы.

0 голосов
/ 19 апреля 2018

Да, его правильное использование структур.Вы также можете использовать

typedef struct someStruct {
 unsigned int total;
} someStruct;

Тогда вам не придется писать struct someStruct s; снова и снова, но вы можете использовать someStruct s; тогда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...