Как передать структуру по ссылке в C? - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть структура, которую мне нужно использовать для двух разных переменных (firstVar и secondVar). Я не хочу использовать векторы, просто 2 простые структуры. Поскольку я не хочу дублировать код, который принимает пользовательский ввод, я хотел бы создать действие, которое я вызываю как для (firstVar, так и secondVar)

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

#include <stdio.h>
typedef struct {
    int id;
    float length;
} tMystruct;
tMystruct firstVar;
tMystruct secondVar;

void readStructs(tMystruct *theVar)
{
    scanf("%d",theVar.id);
    scanf("%f",theVar.length);
}

int main(void)
{
    readStructs(&firstVar);
    readStructs(&secondVar);
    return 0;
}

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Вот проблема,

void readStructs(tMystruct *theVar)
{
scanf("%d",theVar.id); //<------problem 
scanf("%f",theVar.length); //<------problem 
}

Вы должны получить доступ к элементу указателя структуры с помощью оператора ->, а также пропустить &, что в конечном итоге приведет к ошибке сегментации.

Вот модифицированный код,

void readStructs(tMystruct *theVar)
{
scanf("%d",&theVar->id);
scanf("%f",&theVar->length);
}
0 голосов
/ 01 ноября 2018

Имейте в виду, что в C на самом деле нет передачи по ссылке , обычно вы передаете по значению. Это тонкое, но важное различие. Учтите это:

void func_a(int *a) {
    a = 0;
}

int main() {
    int value = 5;
    func_a(&value);

    return 0;
}

Здесь мы видим, что мы установили a = 0; Однако это не влияет на фактическое значение, вы просто переходите туда, где оно указывает в локальной области действия функции. Если бы мы действительно хотели изменить значение a, нам бы пришлось его разыменовать.

*a = 0;

В таких языках, как C ++ и C #, существуют языковые конструкции для передачи по ссылке, но в C вы можете передавать только по значению.

Что касается вашего кода, простое исправление:

void readStructs(tMystruct *theVar)
{
    scanf("%d", &theVar->id);
    scanf("%f", &theVar->length);
}

Ваша функция принимает указатель на tMystruct в качестве первого аргумента, поэтому мы можем использовать оператор стрелки -> и получить доступ к значению, а затем взять его адрес и передать его в scanf. Это эквивалентно

void readStructs(tMystruct *theVar)
{
    scanf("%d", &((*theVar).id));
    scanf("%f", &((*theVar).length));
}
0 голосов
/ 01 ноября 2018

Вы просто передаёте их как ссылку. Как уже указывалось, все проходящие в C только по значению; вызываемая функция всегда получает копию того, что вы передаете. Чтобы получить доступ к фактическому значению вне функции, вам нужна информация об адресе + типе, что в C достигается передачей указателя. И в этом нет ничего плохого в вашем коде, кроме вызовов scanf, и вы достигаете того, что выражали на повседневном английском:

Я бы хотел передать структуру действию по ссылке.

Теперь ответим на вопрос, который вы на самом деле задали:

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

void readStructs(tMystruct *theVar)
{
   scanf("%d",&theVar->id);
   scanf("%f",&theVar->length);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...