Как назначить указатель на структуру из другого метода - PullRequest
0 голосов
/ 23 апреля 2020

Так что я не очень хорошо разбираюсь в C / CPP, но я запрограммировал этот кусок кода:

struct vector{
  double x;
  double y;
  double z;
  };

void d_print(vector *v){
    Serial.print("(");
    Serial.print(v->x);
    Serial.print(", ");
    Serial.print(v->y);
    Serial.print(", ");
    Serial.print(v->z);
    Serial.println(");");
    }

void newVector(vector *vec, double x, double y, double z){
  vector a;
  a.x = x;
  a.y = y;
  a.z = z;
  vec = &a;
  d_print(vec);
  }

Когда я вызывал эти методы (да, это на Arduino, так что void setup(), а не int main(), он работал не так, как ожидалось:

void setup() {
  Serial.begin(9600);
  vector* eye, *center, *up;
  newVector(eye, 2.3, 4.1, 5.9);
  newVector(center, 0.0,0.0,-1.0);
  newVector(up, 0.0,1.0,0.0);
  d_print(eye);
  d_print(center);
  d_print(up);
}

ВЫХОД:

12:22:42.198 -> (2.30, 4.10, 5.90);
12:22:42.232 -> (0.00, 0.00, -1.00);
12:22:42.232 -> (0.00, 1.00, 0.00);
12:22:42.267 -> (0.00, 0.00, 0.00);
12:22:42.300 -> (0.00, 0.00, 0.00);
12:22:42.300 -> (0.00, 0.00, 0.00);

Я понимаю, что double x, y, z go выходит из области видимости, и поэтому структура хранит 0.0 для времени выхода void newVector(). Как я могу обойти это?

Я попробовал следующий подход, назначив его указателю структуры:

void newVector(vector *vec, double x, double y, double z){
    vec->x = x;
    vec->y = y;
    vec->z = z;
    d_print(vec);
    }

Я получаю худший вывод:

12:32:31.164 -> (0.00, 0.00, 0.00);
12:32:31.201 -> (0.00, 0.00, 0.00);
12:32:31.201 -> (0.00, 0.00, 0.00);
12:32:31.236 -> (0.00, 0.00, 0.00);
12:32:31.273 -> (0.00, 0.00, 0.00);
12:32:31.273 -> (0.00, 0.00, 0.00);

Я думаю, что это больше связано с тем, как назначить структуру в C / CPP, чем с программным обеспечением Arduino.

Заранее спасибо.

1 Ответ

4 голосов
/ 23 апреля 2020

Основная проблема со всеми вариантами состоит в том, что вы передаете неинициализированные указатели на newVector.

Все указатели должны указывать где-то действительные, в противном случае вы будете иметь неопределенное поведение когда вы пытаетесь разыменовать указатель (т.е. с помощью vec->x).

Простое решение состоит в том, чтобы не использовать указатели в функции setup, а вместо этого использовать объект простой структуры, а затем использовать адрес адреса оператор & для передачи указателей на следующие объекты структуры:

vector eye;
newVector(&eye, 2.3, 4.1, 5.9);
d_print(&eye);

Также обратите внимание, что первая версия функции newVector, которую вы показываете, не будет работать вообще. Используйте второй вариант:

void newVector(vector *vec, double x, double y, double z){
    vec->x = x;
    vec->y = y;
    vec->z = z;
    d_print(vec);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...