zoukankan      html  css  js  c++  java
  • 面向对象程序设计寒假作业3

    这个作业属于哪个课程 2020年面向对象程序设计 (福州大学 - 数学与计算机科学学院)
    这个作业要求在哪里 面向对象程序设计寒假作业3
    这个作业的目标 1.继续完成编程题。
    2.发布博客。
    作业正文 面向对象程序设计寒假作业2编程题
    面向对象程序设计寒假作业3
    其他参考文献 如何优化C语言代码
    C与C++的区别;面向过程与面向对象的区别;

    编程题

    1.题目要求:

    (1)继续完成作业二的编程题,解决作业2留下的问题。
    (2)优化架构,思考代码的拓展性,比如我需要增加其他功能,如选择,循环语句怎么办。
    (3)思考:可以参考现有的编程语言,把这些语言的内容加入。如选择、循环语句、函数、或者扩大数字范围,支持负数等。

    2.分解需求:

    (1)对代码进行进一步优化,解决作业2留下的问题(着重解决输入如“二十二”、“三十”的功能等实现):

    由于我的代码中change函数是直接对字符串d使用strcmp函数,然后进行“零”-“十”的一一比对,如下:

    int change(int wallet,char d[]){
          if(strcmp(d,"零")==0) return 0;
          else if(strcmp(d,"一")==0) return 1;
          else if(strcmp(d,"二")==0) return 2;
          else if(strcmp(d,"三")==0) return 3;
          else if(strcmp(d,"四")==0) return 4;
          else if(strcmp(d,"五")==0) return 5;
          else if(strcmp(d,"六")==0) return 6;
          else if(strcmp(d,"七")==0) return 7;
          else if(strcmp(d,"八")==0) return 8;
          else if(strcmp(d,"九")==0) return 9;
          else if(strcmp(d,"十")==0) return 10;
          else return -1;
    }
    

    因此,如果想要扩大我的输入范围,首先我想到的是使用strlen函数,对输入的字符串长度大小,从而分成不同的情况判断函数的调用,但是很快就遇到了问题:
    首先我写了一个测试代码:

    #include <stdio.h>
    #include <string.h>
    int main(){
        int len;
        char w[10000];
        scanf("%s",w);
        len=(int)strlen(w);
        printf("%d
    ",len);
        return 0;
    }
    

    然后尝试输入不同的汉字,看看字符串的长度,情况如下:






    对于汉字储存在字符串中,其字符串的长度并不是和字母、数字相同,查阅资料明白:中文字符长度是大于1的,而且不同中文字符的长度是不同的,所以显然不能用这个方法来区别并调用函数处理。
    所以,要想扩大输入范围,我应该改变我的输入方式,不采用“%s”字符串的读入方式,而采用“%c”逐个字符的读入,然后对读入“ ”后进行应该判断,然后在调用函数,对输入的字符所代表的数字大小进行累加,可实现我的想法。(灵感来自我前几天在洛谷做过的一题:P1022 计算器的改良),但是由于要实现的话,就要将我之前写的函数完全改变,也便失去了优化的目的,故在作业中就不继续更改,如果有什么更好的更改意见,希望能私信我,进行进一步的讨论。具体优化,已在作业2的编程题给出,见文章开头表格作业正文已给出。

    (2)优化架构,思考代码的拓展性:

    首先,我们要知道如何对C语言进行优化,查阅资料(已在表格中标出)后明白,首先最重要的是选择合适的算法和数据结构。比如,对于排序,不同情况应该采用不同的方法如:将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序法用快速排序、合并排序或根排序代替,都可以大大提高程序执行的效率。因为在本题中并不需要什么特别的排序等算法,只是对字符串进行简单对操作,因此这一步不再考虑。
    第二,就是使用尽量小的数据类型目的是为了是程序执行速度提高。对于这题编程题所使用数组,我可以适当缩小大小,从而缩小内存。因为有了第一步到测试,所以我将原代码中

    char a[100],b[100],c[100],d[100];
    

    改为

    char a[30],b[30],c[30],d[30];
    

    其次,就是使用自加、自减指令,比如在最初代码练习中,我常常使用:
    a=a+1;等方法进行对变量数值大小对自增或自减。而现在我常常使用自增或自减指令,这点,在上次代码优化中可以看出,下面只给出几个例子:

    if(strcmp(c,"增加")==0) wallet+=change(wallet,d);
     a=wallet/10;
    

    以前,我觉得这样书写只是为了书写对时候更加方便。但是,现在明白了这样使用是为了生成高质量的程序代码,同时也是是代码更加对简练,比如我前几天做的一题中代码:

    while(i<=n){ 
    a[k].s=v[i].s; 
    a[k].num=v[i].num; 
    k++; 
    i++; }
    

    我可以采用以上的写法,但是同时我可以采用以下的写法,是代码更加简练:

    while(i<=n){ 
    a[k].s=v[i].s; 
    a[k++].num=v[i++].num; 
    }
    

    当然,这里要特别注意++ii++区别,因此在使用其使代码更简练的同时,也要注意是否造成错误。
    以上就是对于优化架构的思考与解决办法。
    接下来是对代码的拓展性的思考,说真的,这一题的要求刚刚开始我是很不理解的,什么是代码的拓展性,对我来说这个概念很抽象。但是后来我请教了一个学长,终于对这个概念有了进一步对理解。
    对于代码对拓展性,举个简单的例子就是比如对于选择语句,switch语句,else if(这点在我的原代码中就已经体现了),就比用多层的if else拓展性好。而拓展性高,就会使当我们在对代码功能进一步细化要求时,能够方便我们对代码本身进行相应对增减,从而达到我们对预期。再比如循环语句最好一步步干什么,分工明确。当然,还有最重要的一点,同时也是我认为对我的代码的拓展性优化的最核心的一点,就是增加代码的模块化(多用函数),在本次作业中,我一共是四个函数,change函数控制钱包总额的增减,num函数是将钱包总额从数字转化为汉字,printf_sum函数是通过调用num函数对钱包总额进行1-99范围内的输出。而main函数就是对这些函数的调用,是代码能够执行。总代码如下:

    include <stdio.h>
    #include <string.h>
    int change(int wallet,char d[]){
          if(strcmp(d,"零")==0) return 0;
          else if(strcmp(d,"一")==0) return 1;
          else if(strcmp(d,"二")==0) return 2;
          else if(strcmp(d,"三")==0) return 3;
          else if(strcmp(d,"四")==0) return 4;
          else if(strcmp(d,"五")==0) return 5;
          else if(strcmp(d,"六")==0) return 6;
          else if(strcmp(d,"七")==0) return 7;
          else if(strcmp(d,"八")==0) return 8;
          else if(strcmp(d,"九")==0) return 9;
          else if(strcmp(d,"十")==0) return 10;
          return -1;
        }
    void num(int i){
        if(i==0) printf("零");
        else if(i==1) printf("一");
        else if(i==2) printf("二");
        else if(i==3) printf("三");
        else if(i==4) printf("四");
        else if(i==5) printf("五");
        else if(i==6) printf("六");
        else if(i==7) printf("七");
        else if(i==8) printf("八");
        else if(i==9) printf("九");
        else if(i==10) printf("十");
    }
    void printf_sum(int wallet){
        int a,b;
        if(wallet<=10) num(wallet);
        else{
            a=wallet/10;
            b=wallet%10;
            if(a!=1) num(a);
            printf("十");
            if(b!=0) num(b);
        }
    }
    int main() {
        char a[30],b[30],c[30],d[30];
        int wallet=0,i,flag=0;
        scanf("%s %s %s %s",a,b,c,d);
        if(strcmp(a,"整数")!=0||strcmp(c,"等于")!=0) flag=1;//判断输入格式是否正确
        for(i=1;flag==0;i++){
            if(i==1) wallet=change(wallet,d);
            else {
                scanf("%s",a);
                if(strcmp(a,b)!=0&&strcmp(a,"看看")!=0) break;
                scanf("%s",c);
                if(strcmp(a,"看看")==0){
                    printf_sum(wallet);//这里重新命名函数,使代码更加易读
                    break;}
                scanf("%s",d);
             if(strcmp(c,"增加")==0) wallet+=change(wallet,d);
             if(strcmp(c,"减少")==0) wallet-=change(wallet,d);
            }
        }
       return 0;
    }
    

    但是,尽管分了几个函数,但是我发现其实我的主函数仍然不够简洁而易懂,而这也是我下一点将谈到的。

    (3)思考:可以参考现有的编程语言,把这些语言的内容加入。如选择、循环语句、函数、或者扩大数字范围,支持负数等:

    就像刚刚第二点所谈到的,使代码模块化,我就此写一下我的思考。首先就输入而言,我的原代码中是,定义了四个字符数组,然后使用scanf函数进行输入。我是否可以写一个专门用于输入的函数如scanf_wallet,控制对钱包总额对输入。(实现多位输入,具体在第一点中就已提到)
    而原代码中我是采用flag变量,根据其的数值大小来判断在输入过程中数据是否有错误,那我在这一点上,能不能写一个判断的函数如judge_true_or_false,来进行判断,就不需要再定义一个状态变量,从而对数据正误进行判断。
    然后是对钱包总额大小的变化进行变化,在我的代码中我是通过以下两个语句,对其大小进行增减:

     if(strcmp(c,"增加")==0) wallet+=change(wallet,d);
    if(strcmp(c,"减少")==0) wallet-=change(wallet,d);
    

    借助上面的思路,我是否可以分别编写一个加减乘除的函数,从而对钱包总额进行变化,进一步细化函数的功能,在不同情况采用不同函数,而不是减加减乘除都运用一个函数,然后在主函数中根据情况判断,该使变量wallet使用”+””-””*””/”的符号,我觉得这一点可以进一步增加代码的拓展性。
    当然还可以扩大数字范围,不是简单的“零”到“九十九”,还可以达到“百”,“千”甚至“万”。这些都可以编写一个函数。
    还有,比如对于我的代码中,在输入“看看 钱包”的命令后,我的程序就结束了,我还可以进一步优化多次使用“看看 钱包”多次查看钱包的总额。
    还可以比如“钱包 增加 负一”对于负数的加减乘除写一个函数,然后使这条指令可行。
    以上就是我的相关思考,希望在接下来的学习中,能够进一步实现。

    3.三次寒假作业的收获:

    • 首先在第一次作业中,第一次接触终端,然后使用命令行编译C语言,这个实践题收获真的很大,比如:如果使用终端,然后进入对应的目录,然后直接建立我需要的文件类型,这个操作方便了很多。
    • 然后是编程题,初步明白了对于一个汉字计算如何将它转化成代码形式,特别是对strcmp函数对使用以及其对返回值,说真的在老师讲字符串对时候,对于这个函数我并没有什么理解与使用,而这次编程题加深了我的印象,也在洛谷解决字符串的一些问题中提供了很大的帮助。
    • 第二次作业中我接触了github,使用git将文件上传,说真的,这个操作,我折腾了两三个小时才明白,过程很辛苦,但是成功上传的那一刻,真的巨happy。
    • 还有第二次作业编程题中编译脚本,我接触了shell这一门脚本语言,这个真的很便利,原因并不只是为了解决作业二,还有为了我现在正在学的swift这一门语言,打了一定的基础,因为在一些方面,这两者语言有一定的共通性。
    • 当然还明白了什么是单元测试,编译脚本,测试脚本。最不能忘的是,增加一个功能通过命令行读取一个文件,然后运行。这个让我明白了如何使用C语言对文件进行操作。(这一点是上《高级语言程序设计》时候老师所忽略的知识。
    • 然后就是本次作业了,本次作业主要是对代码进行进一步优化和思考代码的拓展性,这个刚刚开始对我来说很陌生,平时我只会根据题目去打相应的代码,什么都尽量对往main函数中去套,但是并没有思考过这样一个问题。我们平常所解决的问题都是根据一个小情景然后去解决相应的问题,这样可适用范围仅限于这一题,但是如果当我们在设计一个软件的这样一个大环境中,我们就不得不将我们所需要的功能,逐步细化,然后逐层实现,由一块块小的函数,从而融合成一个整体,实现多种复杂功能,这也是今后学习中需要培养的,使代码的拓展性更高,同时也是一种思维能力的锻炼。
    • 最后我思考了我们这门课中将学到什么,我觉得最主要的就是几个字“面向对象”这也是我们课程名称中所包含的。明明学的是C++那为什么不直接用C++程序设计之类的,所以我查了资料,明白了什么是面向对象,而什么是面向过程(已在开头的表格标出)一个简单的例子:
      把大象放入冰箱里面。
      C++是这么做的:涉及到两个对象:冰箱和大象。三个动作:打开冰箱,放置大象,关闭冰箱。首先定义一个冰箱类,他有打开的方法,放置的方法,关闭的方法。然后再定义一个大象类。接下来构建冰箱和大象的对象,然后冰箱对象调用打开门的方法,冰箱对象再调用放置大象对象的方法,最后冰箱对象关门。
      而当C是这么做的:首先打开冰箱门,然后把大象放入进去,最后关闭冰箱门。
      这样便是这两者的主要区别。同时我也认为,C++能使代码的拓展性更高,因为对于C来说,比如上面的例子。我是针对过程来进行编写代码,那假如现在我将对象换成其他动物,比如猫,那我就是重新写猫放进冰箱的过程,而对于C++我可以再编写一个猫类,然后套用之前的代码,这样使代码的拓展性更高。(当然,这只是我个人的初步理解,在接下来的学习中将进一步学习C++)。
  • 相关阅读:
    C语言函数sscanf()的用法(转)
    GDB基本命令(整合)(转)
    单元命中率与字节命中率
    rpm安装找不到.so库文件(linux动态库连接的相关知识)(转)
    Linux下的tar压缩解压缩命令详解(转)
    Linux系统如何查看版本信息
    Linux /bin, /sbin, /usr/bin, /usr/sbin 区别(转)
    rsync问题-connection refused(111)、Unknown module
    转: 浅析Fusion-IO和Intel SSD
    转: 从0到1的电商架构应该怎么做?
  • 原文地址:https://www.cnblogs.com/lvhang/p/12296712.html
Copyright © 2011-2022 走看看