//
// 要求:(1)定义一个结构体类型来描述复数。
// (2)复数之间的加法、减法、乘法和除法分别用不用的函数来实现。
// (3)必须使用结构体指针的方法把函数的计算结果返回。
// 说明:用户输入:运算符号(+,-,*,/) a b c d.
// 输出:a+bi,输出时不管a,b是小于0或等于0都按该格式输出,输出时a,b都保留两位。
//
//输入:
// - 2.5 3.6 1.5 4.9
//输出:
// 1.00+-1.30i
//
这个问题现在学到了两种解法,都可以通过编译,第一种呢,是从网上看到的:
#include<stdio.h>
char sign;
double a, b, c, d;
scanf("%c%lf%lf%lf%lf",&sign,&a,&b,&c,&d);
if( sign == '+' )
printf("%.2lf+%.2lfi",a+c,b+d);
if( sign == '-' )
printf("%.2lf+%.2lfi",a-c,b-d);
if( sign == '*' )
printf("%.2lf+%.2lfi",a*c-b*d,a*d+b*c);
if( sign == '/' )
printf("%.2lf+%.2lfi",(a*c + b*d)/(c*c + d*d),(b*c - a*d)/(c*c + d*d));
return 0;
}
这个题像这样硬做并不难,但是如果要遵从题目要求:1、定义一个结构体类型来描述复数 2、必须用结构体指针的方法把函数的计算结果返回。 作为一个不是很熟练思维又慢的初学者,我是有一些方的。但还好最后在大神的指点下,还是勉强把它写了出来。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct fushu{
double real;
double i;
};
fushu* add(fushu a, fushu b){
fushu* ret = (fushu*)malloc(sizeof(fushu));
ret->real = a.real + b.real;
ret->i = a.i + b.i;
return ret;
}
fushu* minus(fushu a, fushu b){
fushu* ret = (fushu*)malloc(sizeof(fushu));
ret->real = a.real - b.real;
ret->i = a.i - b.i;
return ret;
}
fushu* multiply(fushu a, fushu b){
fushu* ret = (fushu*)malloc(sizeof(fushu));
ret->real = a.real*b.real - a.i*b.i;
ret->i = a.real*b.i + a.i*b.real;
return ret;
}
fushu* divide(fushu a, fushu b){
fushu* ret = (fushu*)malloc(sizeof(fushu));
ret->real = (a.real*b.real + a.i*b.i)/(b.real*b.real + b.i*b.i);
ret->i = (a.i*b.real - a.real*b.i)/(b.real*b.real + b.i*b.i);
return ret;
}
int main()
{
char sign;
fushu m;
fushu n;
scanf("%c%lf%lf%lf%lf",&sign,&m.real,&m.i,&n.real,&n.i);
if( sign == '+' ){
add(m,n);
printf("%.2lf+%.2lfi\n",add(m,n)->real,add(m,n)->i);
}
if( sign == '-' ){
minus(m,n);
printf("%.2lf+%.2lfi\n",minus(m,n)->real,minus(m,n)->i);
}
if( sign == '*' ){
multiply(m,n);
printf("%.2lf+%.2lfi\n",multiply(m,n)->real,multiply(m,n)->i);
}
if( sign == '/' ){
divide(m,n);
printf("%.2lf+%.2lfi\n",divide(m,n)->real,divide(m,n)->i);
}
return 0;
}
看上去有些长,但其实只要明白最简单的加法是怎么写出来的,其他的只是改几个字母而已。
解决这个问题过程中,发现了自己的几个薄弱知识点:
1.在C与C++之间,定义结构体变量调用的方式是小有不同的,
<1>在C语言中,可以用:
typedef struct Student{
double a;
double b;
}; 这时我们只是定义了结构体类型名,定义结构体变量时,要写 struct Student stu1;
而如果想省点事的话,就这样写:
typedef struct Student{
double a;
double b;
}Stu; 这个意思就是 让 Stu = struct Student, 后面再定义结构体变量时,就可以写 Stu stu1; <2>在C++中,可以用:
struct Student{
double a;
double b;
}; 而在这里,可以看到C++的简洁,我们后面想定义结构体变量时,直接可以写Student stu1;
而如果你不幸习惯性地用C语言的方式写了的话
typedef struct Student{
double a;
double b;
}Stu; 没关系,这本来就和C语言一样,Stu在这里还是会等于struct Student,
当然,也可能有人这么写:
struct Student{
double a;
double b;
}Stu; 不要想当然地与C语言类比了,Stu这时不等于Student,这里的意思是用Student这个结构体类型定义了Stu 这个结构体变量,而且,我们还可以定义更多的结构体变量(你开心就好)
struct Student{
double a;
double b;
}Stu1,Stu2,Stu3……;
2、定义函数的时候,发现很蒙逼
回顾一下要求,用结构体指针的方法把函数值返回
所以要定义一个结构体指针类型的函数,才会需要返回结构体指针
所以以加法为例:fushu* add(fushu a, fushu b){
...
} 因为我们要输入两组复数,所以我们在定义两组结构体变量,a,b
3、实现函数的时候,不知道怎么写
要返回结构体指针,需要再定义一个指针型变量才行,
... {
fushu* ret = malloc(sizeof(ret));(注意,这一步这么写就错了,编译器会告诉你void型变量不能
... 传给指针型变量,其实呢,只需要改一个小地方就可以了,
return ret; (fushu*)(malloc(sizeof(ret)) 这样两边就一样了)
}
其实身为初学者我并不明白这一步的用处,后来查阅一些资料,明白了,malloc是用来人为给各种类型的变量分配内存空间用的,涉及到堆栈的问题,简单一说,“堆”就是我写的这样,用malloc手动分配空间,其实用new也可以,不多说,而“栈”,大家最熟了,就是用int,char,double......这些类型名来让系统自动给你分配空间,而大小都已经定好了,你不需要再改,最后回来,如果这一步不手动分配空间的话,函数结束时,空间会自动销毁,那时我们的指针就不知道该指向哪里去了,这样是很危险的,也就是常说的“野指针”,一个不知道指向哪里的东西,总是有些诡异呀 (可能语言不严谨,仅仅是我理解之后的简述)。
4、实现函数
...{
...
ret->real = a.real + b.real; 嗯,说不上想不通的问题在哪里,但之前就是不会写,大神写完之后,
ret->i = a.i + b.i; 却能理解,唉,就这样吧。
return ret;
}
5、 主函数
不多说了,看看上面写的吧