蓝桥杯P1103 复数运算问题

//编程实现两个复数的运算。设有两个复数 和 ,则他们的运算公式为:
//
//  要求:(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、 主函数

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

   

 

 


  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值