Как мне написать эту запись и процедуру на C ++? Как мне перевести код в класс и методы вместо прямого перевода?
type
complex=record
im,re:real;
end;
procedure NumberMultiplication(a:complex; var b:complex; k:byte);
begin
b.re:=a.re*k;
b.im:=a.im*k;
end;
Стандартная библиотека C ++ уже предоставляет эту функциональность.
Включить заголовок <complex>
, используйте тип std::complex<double>
Экспресс умножения с обычным *
,
Пример:
#include <complex>
using Complex = std::complex<double>;
using Byte = unsigned char;
auto operator*( Byte const b, Complex const& c )
-> Complex
{ return Complex( b )*c; }
#include <iostream>
using namespace std;
auto main() -> int
{
Byte const b = 42;
Complex const c = {2, 3}; // 2 + 3*i
cout << b*c << endl;
}
В C ++ вы могли бы:
struct complex {
double im, re;
};
Процедура может быть записана как:
void NumberMultiplication(complex a, complex &b, byte k)
{
b.re = a.re * k;
b.im = a.im * k;
}
Это прямой перевод из реализации Паскаля; возможно, есть лучшие способы написать это на C ++ в зависимости от ваших общих целей.
Вы можете определить свою собственную структуру
struct complex
{
double re, im;
}
void NumberMultiplication(const complex a; complex &b, short int k)
{
b.re = a.re * k;
b.im = a.im * k;
}
(почему байт — короткий тип int ???).
Я предпочитаю лучший подход, который заключается в
#include <complex>
std::complex<double> a, b;
short int k;
b = a * k;
(все еще озадаченный коротким int). Вы можете проверить ссылку на сложный класс на http://www.cplusplus.com/reference/complex/
Как уже упоминалось, самый прямой перевод — заменить Паскаль. record
с struct
, Обратите внимание, что C ++ эквивалент byte
является unsigned char
поэтому самым прямым переводом будет:
struct complex
{
double re, im;
};
void NumberMultiplication(complex a, complex& b, unsigned char k)
{
b.re = a.re*k;
b.im = a.im * k;
}
Однако это не самый лучший перевод. Первое, что нужно упомянуть, это то, что C ++, в отличие от Pascal, позволяет возвращать структурированные типы (я думаю, что существуют диалекты Pascal, которые тоже допускают это). Поэтому вы можете изменить NumberMultiplication
к функции, возвращающей complex
:
complex NumberMultiplication(complex a, unsigned char k)
{
complex b { a.re*k, a.im * k };
return b;
}
Обратите внимание, что в приведенном выше коде я использовал возможность инициализации C ++ struct
непосредственно при определении локальной переменной. Однако вы можете сделать еще лучше, дав complex
конструктор:
struct complex
{
double re, im;
complex(double real, double imag = 0); // constructor declaration
};
// inline is a hint for the compiler to optimize by inserting that code
// into calling code
inline complex::complex(double real, double imag):
re(real),
im(imag) // these initialize the members
{
// here you could write other code to be executed on initialization
// (not needed in this case)
}
complex NumberMultiplication(complex a, unsigned char k)
{
return complex(a.re * k, a.im * k);
}
Обратите внимание, что второй аргумент конструктора (double imag
) имеет аргумент по умолчанию (= 0
); это позволяет опустить мнимую часть; более того, теперь конструктор может вызываться только с одним аргументом (и не помечается как explicit
), это также позволяет неявному преобразованию удваиваться, то есть теперь вы можете написать, например,
complex z = NumberMultiplication(3.0, 7);
и это будет означать так же, как
complex z = NumberMultiplication(complex(3.0, 0.0), 7);
Следующее улучшение заключается в использовании перегрузки операторов C ++: нет необходимости придумывать причудливое имя функции для операции, в которой мы обычно использовали бы оператор умножения. *
за; мы можем определить этот оператор умножения для наших собственных типов, просто используя специальное имя функции operator*
:
complex operator*(complex a, unsigned char k)
{
return complex(a.re * k, a.im * k);
}
с этим теперь вы можете просто написать е. г.
complex x(1,2), y;
unsigned char c = 42;
y = x*c;
Конечно, вы также можете иногда захотеть написать y=c*x
вместо этого и хочу, чтобы это работало тоже. К счастью, вы можете сделать это благодаря перегрузке функций: просто добавьте
complex operator*(unsigned char k, complex a)
{
return complex(a.re * k, a.im * k);
}
и компилятор выберет правильную функцию для вызова из типов.
Далее мы можем улучшить complex
структура, чтобы сделать его правильным классом, скрывая переменные-члены. Мы предоставляем функции доступа для чтения реальных и мнимых частей. Итак, теперь мы получаем:
class complex
{
public:
complex(double real, double imag=0);
double real();
double imag();
};
inline complex::complex(doube real, double imag):
re(real),
im(imag)
{
};
inline double complex::real()
{
return re;
}
inline double complex::imag()
{
return im;
}
complex operator*(complex a, unsigned char k)
{
return complex(a.real() * k, a.imag() * k);
}
complex operator*(unsigned char k, complex a)
{
return complex(a.real() * k, a.imag() * k);
}
Теперь комплексные числа требуют, конечно, гораздо больше операций, чем просто умножение; но, к счастью, вы можете спасти себя всю эту работу, потому что кто-то уже сделал это для вас. В C ++ существует заголовок complex
который содержит полную реализацию комплексных чисел. Поэтому вы можете просто написать
#include <complex>
и использовать тип std::complex<double>
везде, где ваш код на Паскале использует самоопределение complex
тип.
Я бы интерпретировал это следующим образом
strcut complex
{
double im;
double re;
};complex operator *( const complex &c, int k )
{
return { k * c.im, k * c.re };
}
complex operator *( int k, const complex &c )
{
return { k * c.im, k * c.re };
}
То есть операция будет коммутативной. Ты можешь написать
complex c = { 1, 2 };
c = 3 * c;
c = c * 3;
Или, если ваш компилятор не поддерживает список инициализатора, то
strcut complex
{
double im;
double re;
};complex operator *( const complex &c, int k )
{
complex tmp = { k * c.im, k * c.re };
return tmp;
}
complex operator *( int k, const complex &c )
{
complex tmp = { k * c.im, k * c.re };
return tmp;
}