Как написать функцию, возвращающую матрицу?
Мне нужна функция, возвращающая матрицу вращения 2x2, что-то вроде:
float matrix(float phi){
float R[2][2] = { {cos(phi), -sin(phi)},
{sin(phi), cos(phi)} };
return R;
}
Очевидно, это не работает. Как лучше всего написать эту функцию?
@2012User, 👍0
2 ответа
Лучший ответ:
Один из способов — заставить функцию возвращать указатель с плавающей запятой, т.е. создать новый массив и вернуть его
float** matrix(float phi){
float** R= (float **)malloc(2 * 2 * sizeof(float));
R[0][0]= cos(phi);
R[0][1]= -sin(phi);
R[1][0]= sin(phi);
R[1][1]= cos(phi);
return R;
}
Не забудьте освободить память, если она вам больше не нужна!
Однако я бы посоветовал вам не делать этого, а передать массив в функцию. См. Как объявить массив переменного размера (глобально) и Использует malloc() и free() - действительно плохая идея для Arduino? для объяснения, почему выделение памяти в функции может быть не очень хорошей идеей (во встроенной среде, известной как Arduino)
Вы не можете вернуть массив из функции. Есть несколько альтернативы, однако. Один из них — выделить память для массив внутри функции, как предложено в ответе пользователя2912328. Я бы однако не рекомендую этот подход по причинам, уже указанным в этот ответ.
Обзор других возможных вариантов см. в этом ответе на вопрос «Возврат целочисленного массива из функции».
Теперь ваша проблема немного другая, поскольку у вас есть 2D-массив. Синтаксис C/C++ для решения этих задач сложен, но начнем.
Если вы выберете решение «статический массив» (убедитесь, что вы понимаете последствия), вы могли бы написать:
float (*matrix(float phi))[2]
{
static float R[2][2];
R[0][0] = cos(phi);
R[0][1] = -sin(phi);
R[1][0] = sin(phi);
R[1][1] = cos(phi);
return R;
}
и вы бы использовали его так:
float (*M)[2] = matrix(angle);
Если вместо этого вы позволите вызывающему объекту управлять распределением, то
float (*matrix(float phi, float (*R)[2]))[2]
{
R[0][0] = cos(phi);
R[0][1] = -sin(phi);
R[1][0] = sin(phi);
R[1][1] = cos(phi);
return R;
}
Или можно отказаться от возвращаемого значения, чтобы упростить синтаксис:
void matrix(float phi, float (*R)[2])
{
R[0][0] = cos(phi);
R[0][1] = -sin(phi);
R[1][0] = sin(phi);
R[1][1] = cos(phi);
}
и вы можете использовать его так:
float M[2][2];
matrix(angle, M);
Решение «массив в структуре» более простое.
Если вас беспокоит синтаксис работы с 2D-массивами (это будет понятно), вместо этого вы можете использовать массивы указателей на одномерные массивы. С этим легче справиться, но сложнее распределить. Этот подход мог бы потребовать другого ответа...
Изменить. Один из распространенных способов упростить синтаксис запутанного массива — использовать определения типов. Поскольку идентификатор массива 2x2 превращается в указатель на массив из двух чисел с плавающей запятой, вы можете назвать этот тип:
typedef float (*pmatrix)[2]; // указатель на массив из двух чисел с плавающей запятой
Тогда вместо
float (*matrix(float phi))[2] { ... }
...
float (*M)[2] = matrix(angle);
вы бы написали
pmatrix matrix(float phi) { ... }
...
pmatrix M = matrix(angle);
- Округление до первой значащей цифры
- Печать string and integer LCD
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
- Глобальные переменные занимают много места в динамической памяти.
- (Код ультразвукового датчика: такого файла или каталога нет)
- rfid_default_keys проверить с помощью RC522
Это не то, как вы создаете 2D-массив. Здесь
R[0]
иR[1]
— это неинициализированные указателиfloat *
, аR[0][0]
— это разыменование одного такого указателя. Это неопределенное поведение может привести к сбою программы., @Edgar BonetУх ты... C++ слишком сложно программировать., @2012User
@ Эдгар Боне, как мне написать эту функцию?, @2012User