思路:
①首先了解复数四则运算——加、减、乘、除;以及分别对应的公式(以a+bi和c+di为例推导);
加/减法:(a+bi)±(c+di)=(a±c)+(b±d)i
乘法:(a+bi)(c+di)=(ac-bd)+(bc+ad)i
除法:
②根据数据结构的定义,自定义数据类型Complex,利用结构体的知识进行构造复数的实部和虚部(此处数据类型采用double类型,以便于浮点数的运算)。
复数的抽象数据类型定义
ADT Complex{
数据对象:D={e1,e2|e1,e2∈R}
数据关系:R1={<e1,e2>|e1是复数的实部,e2是复数的虚部}
基本操作:
InitComplex(&Z,v1,v2)
操作结果:构造复数Z,其实部和虚部分别被赋役参数v1和v2的值。
Destroy(&Z)
初始条件:复数已存在。
操作结果:复数Z被销毁。
GetReal(Z,&realPart)
初始条件:复数已存在。
操作结果:用realPart返回复数Z的实部值。
GetImag(Z,& imagPart)
初始条件:复数已存在
操作结果:用imagPart返回复数Z的虚部值。
ADD(z1,z2,&z_sum)
初始条件:z1,z2是复数。
操作结果:用z_sum返回两个复数z1,z2的和值。
SUM(z1,z2,&z_sub)
初始条件:z1,z2是复数。
操作结果:用z_sub返回两个复数z1,z2的差值。
MUL(z1,z2,&z_mul)
初始条件:z1,z2是复数。
操作结果:用z_mul返回两个复数z1,z2的积值。
DIV(z1,z2,&z_div)
初始条件:z1,z2是复数。
操作结果:用z_div返回两个复数z1,z2的商值。
}ADT Complex
代码(.h+.c文件)
//complex.h
#include<stdio.h>
#include<stdlib.h>
typedef struct { //自定义complex数据类型
double e1, e2;
}complex;
void InitComplex(complex* z0, double v1, double v2);
void DestoryComplex();
double GetReal(complex z2);
double GetImag(complex z2);
//9_9.c
#include<stdio.h>
#include"complex.h"
void InitComplex(complex* z0, double v1, double v2){ //构造复数的函数
z0->e1 = v1;
z0->e2 = v2;
}
void DestoryComplex(){ //销毁数据的函数
printf("\n系统自动清除内存,数据已被销毁。\n");
}
double GetReal(complex z2) { //得到复数的实部
double* realpart = &z2.e1;
return *realpart;
}
double GetImag(complex z2) { //得到复数的虚部
double* imagpart = &z2.e2;
return *imagpart;
}
void ADD(complex z1, complex z2, complex* z) //复数加法运算
{
z->e1 = z1.e1 + z2.e1;
z->e2 = z1.e2 + z2.e2;
}
void SUB(complex z1, complex z2, complex* z) //复数减法运算
{
z->e1 = z1.e1 - z2.e1;
z->e2 = z1.e2 - z2.e2;
}
void MUL(complex z1, complex z2, complex* z) //复数乘法运算(以a+bi和c+di计算找出普遍规律)
{
z->e1 = z1.e1 * z2.e1 - z1.e2 * z2.e2;
z->e2 = z1.e2 * z2.e1 + z1.e1 * z2.e2;
}
void DIV(complex z1, complex z2, complex* z) //复数除法运算
{
z->e1 = (z1.e1 * z2.e1 + z1.e2 * z2.e2) / (z2.e1 * z2.e1 + z2.e2 * z2.e2);
z->e2 = (z1.e2 * z2.e1 - z1.e1 * z2.e2) / (z2.e1 * z2.e1 + z2.e2 * z2.e2);
}
int main() {
complex z1, z2, z[4]; //z[4]用来储存四个计算过的值
char str[4][16] = { { "SUM 和|| z_sum"},{"SUB 差|| z_sub"},{"MUL 积|| z_mul"},{"DIV 商|| z_div"} }; //为界面优化所设
double z1e1, z1e2, z2e1, z2e2;
printf("[注]减法和除法默认 第一个数 -/÷第二个数 \n\n ——please enter the first complex.\nRealpart:");
scanf_s("%lf", &z1e1);
printf("Imagpart:");
scanf_s("%lf", &z1e2);
printf(" ——please enter the second complex.\nRealpart:");
scanf_s("%lf", &z2e1);
printf("Imagpart:");
scanf_s("%lf", &z2e2);
InitComplex(&z1, z1e1, z1e2); //构造复数,把输入的z1e1(实部)和z1e2(虚部)与z1连接起来
InitComplex(&z2, z2e1, z2e2);
ADD(z1, z2, &z[0]);//调用函数进行计算
SUB(z1, z2, &z[1]);
MUL(z1, z2, &z[2]);
DIV(z1, z2, &z[3]);
printf("\n—Here are the results—\n");
//由于正负原因,输出结果需要对正负进行判断
for (int i = 0; i < 4; i++) {
if (GetImag(z[i]) > 0) { //如果虚部大于零,可直接以a+bi的形式输出
if (GetReal(z[i]) == 0) { //实部等于零,省略
printf("%s=%lfi\n", str[i], GetImag(z[i]));
}
else{ //实部大于或等于0,直接输出
printf("%s=%lf+%lfi\n", str[i], GetReal(z[i]), GetImag(z[i]));
}
}
else if (GetImag(z[i]) == 0) { //如果虚部等于零,则虚部省略
printf("%s=%lf\n", str[i], GetReal(z[i]));
}
else if (GetImag(z[i]) < 0) { //如果虚部小于零,此时虚部自带负号,以abi的形式输出(b自带-号)
if (GetReal(z[i]) == 0) { //与虚部大于零同理
printf("%s=%lfi\n", str[i], GetImag(z[i]));
}
else {
printf("%s=%lf%lfi\n", str[i], GetReal(z[i]), GetImag(z[i]));
}
}
}
DestoryComplex(); //提示数据销毁
return 0;
}