зачем использовать указатель на структуру, а не использовать структуру напрямую (C) - PullRequest
1 голос
/ 04 мая 2020

У меня есть два примера, показанных в приведенном ниже коде, которые дают тот же результат. Я вижу, как люди делают пример 1, используя указатель. Но почему бы не выполнить пример 2 и не использовать топор напрямую? есть разница?

typedef struct
{
    uint8_t x;
    uint8_t y;
    uint8_t z;
} xyz_t;

xyz_t a;

void func1(xyz_t* b)
{
    printf("%d", b->x); //example 1
}

void func2()
{
    printf("%d", a.x); //example 2
}

int main()
{
    a.x = 10;
    func1(&a); //example 1
    func2();   //example 2
}

Ответы [ 3 ]

2 голосов
/ 04 мая 2020

Чтобы ответить на ваш вопрос довольно прямо, это как если бы я спросил вас: «Зачем мне передавать переменную в качестве аргумента моей функции, а не просто хранить ее как глобальную переменную?», Но, вероятно, это не тот ответ, который вы ищите, так что вот еще некоторое представление о том, почему указатели могут быть полезны в этом случае:

Указатели полезны, потому что вы можете легче их «перемещать». Вместо того, чтобы каждый раз копировать всю структуру, вы можете просто оставить ее там, где она есть в памяти, и вместо этого передать на нее указатель.

Кроме того, передача указателя означает, что вы можете изменить «a» без необходимо скопировать его обратно, так как структура находится только в одном месте в памяти. исходный вопрос.

Хорошего дня!

2 голосов
/ 04 мая 2020

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

Вторая функция действует напрямую в глобальной переменной, поэтому изменения, очевидно, также отражаются в a.

Соответствующая разница будет отмечена, если вы передадите a по значению, например:

xyz_t a;

void func3(xyz_t b)
{
    printf("%d", b.x); //example 3 
}

//...
func3(a);
//...

Здесь вы передадите a по значению, по сути, копию a, любое изменение, внесенное в a в рамках функции на самом деле будет относиться не к a, а к его копии, и, естественно, он не будет отражаться в исходном a.

Отметив, что вы ничего не меняете, только печать значения, хранящегося в a любого из трех, дает те же результаты.

В этом случае, поскольку вы не пытаетесь изменить переменную, рекомендуется использовать ключевое слово const, чтобы избежать случайного изменения.

void func1(const xyz_t* b)

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

2 голосов
/ 04 мая 2020

если ваша функция была передана в качестве аргумента структуре без указателя, ее данные должны были бы быть скопированы для использования функцией, что может занять некоторое время. Кроме того, если вы хотите изменить структуру в функции и увидеть ее изменения за пределами области действия функции, ваш единственный вариант - отправить ее по указателю, потому что вы указываете функции место в памяти переменной, которую вы хотите изменить, а не (местная) копия. Часто предпочтительнее отправлять переменные по значению, если они не большие и вы не изменяете их, потому что это делает действия функции над ее аргументами более понятными для вызывающего. Если ваша функция может выполнять операцию только с одной переменной, ее использование будет очень ограничено. Вы можете, например, использовать эту же функцию с другим xyz_t, к которому функция не может получить прямой доступ.

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