您的位置:首页 > 其它

蓝桥杯P1103 复数运算问题

2016-02-07 11:31 375 查看
//编程实现两个复数的运算。设有两个复数 和 ,则他们的运算公式为:

//

//  要求:(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、 主函数

    不多说了,看看上面写的吧

   

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: