面向对象程序设计寒假作业1

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2020OOP
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/2020OOP/homework/10224
这个作业的目标 1.安装C++开发环境(见附录) 2.完成问答题、实践题及编程题 3.发布博客
作业正文 问答题、实践题、编程题
其他参考文献 均已在问答题、实践题中标出

问答题:

1.如果你不了解C++请回答以下问题:你认为C语言有什么缺陷(你觉得哪里用的不顺手)。

1.运算符和运算优先级太多,不利于记忆。在一个表达式中可能包含多个有不同运算符连接起来的、具有不同数据类型的数据对象,由于表达式有多种运算,不同的运算顺序可能得出不同结果,因为当表达式中含多种运算时,必须按一定顺序进行结合,才能保证运算的合理性和结果的正确性、唯一性,c语言优先级多不易记忆和自如运用。
2.语法定义不严格,编程自由度大。C语言的语法限制不太严格,对变量的类型约束不严格,影响程序的安全性,对数组下标越界不作检查等。
3.占用资源较多,C语言最大的缺点就是相比Pascal编译速度太慢,原因是头文件预处理占用了太多时间,
4.指针运算太灵活,难以掌握和使用自如。

2.查阅相关资料,简述一下C语言/C++的编译过程。

1.编辑.c文件
2.预处理
预处理过程实质上是处理“#”,将#include包含的头文件直接拷贝到hell.c当中;将#define定义的宏进行替换,同时将代码中没用的注释部分删除等
具体如下:
(1)将所有的#define删除,并展开所有的宏定义。
(2)处理所有的条件编译指令,#ifdef #ifndef #endif等,就是带#的那些
(3)处理#include,将#include指向的文件插入到该行处
(4)删除所有注释
(5)添加行号和文件标示,这样的在调试和编译出错的时候才知道是是哪个文件的哪一行
(6)保留#pragma编译器指令,因为编译器需要使用它们。
3.编译
编译的过程实质上是把高级语言翻译成机器语言的过程,即进行词法分析,语法分析,语义分析,优化后生成相应的汇编代码。(高级语言->汇编语言->机器语言(二进制))
4.链接
编译过程只是把源文件翻译成二进制,而这个二进制还不能直接执行,这时就需要将翻译成的二进制与需要用到库绑定在一块。

实践题:

自己动手,完成以下任务:

1.查看自己的C++编译器版本。

打开visual studio中工具中的命令行,输入cl.exe即可查看c++编译器版本。

2.使用命令行编译一份C语言/C++代码。

在visual studio中按下win+R,输入cmd打开命令行,打开相应磁盘,输入D:(打开D盘),输入相对应的路径,即可运行程序。

编程题:

中国文化博大精深,从仓颉造字开始,汉字一直流传到了今天。我们在感叹汉字的源远流长时,也不禁感慨,为什么没有一门使用汉字编程的语言?
汉字真的不能编程吗?最近文言文编程火了一把,吾有一數。曰三。名之曰「甲」。这朴实无华的变量定义无疑不是几千年来中华文化的发展中一朵奇葩。
今天小王同学想,文言文能编程那白话文呢?他找到了你,让你帮帮他。

编程要求
编写一个程序,输入满足以下语法要求的一段文字,输出运行后的结果。
变量定义:整数 钱包 等于 零
运算(加法):钱包 增加 四
运算(减法):钱包 减少 四
输出:看看 钱包

样例
输入:

整数 钱包 等于 零
钱包 增加 四
钱包 减少 三
看看 钱包

输出:

注意:

输入输出用例均为GBK编码,推荐使用vscode把文本切换为GBK编码。
数字只会出现以下 零一二三四五六七八九十 。

1.题目要求:

白话文编程要满足变量的定义,能够根据输入的白话文进行加减运算,且能输出正确结果

2.分解需求:

(1)编写初始化函数,将“零”、“一”等白话文转换为数字形式
(2)编写两个能够进行加运算和减运算的函数使其能够根据输入内容进行加减运算
(3)编写当遇到“看看 钱包”时能够得到输出结果的输出函数
(4)编写主函数

3.思考过程:

通过观察题目所给输入内容,应该先将“钱包”中的初始数额初始化转为数字形式

疑问:如何将初始数额的白话文转换为数字?通过询问他人后得知,可以运用strcmp函数对字符串进行判断,进而对变量进行运算。

(1)编写以下初始化函数:

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

(2)编写加减运算函数

这里同样可以运用strcmp函数对字符串进行判断,将白话文的加减多少的运算通过一个个枚举来判断进行什么样的运算及加减多少,并将其转换为代码形式。
疑问:除了通过一个个枚举,是否有更好的实现方法?个个枚举虽然通俗易懂,但代码比较冗长,由于该题的加减运算仅仅限制在10以内,枚举可以有效解决。但假设题目的加减运算的量增大,显然枚举的方法就不那么适用了。

a.加运算函数编写:

void add(char str[]){
    if(strcmp(" 增加 一",str)==0)sum+=1;
    if(strcmp(" 增加 二",str)==0)sum+=2;
    if(strcmp(" 增加 三",str)==0)sum+=3;
    if(strcmp(" 增加 四",str)==0)sum+=4;
    if(strcmp(" 增加 五",str)==0)sum+=5;
    if(strcmp(" 增加 六",str)==0)sum+=6;
    if(strcmp(" 增加 七",str)==0)sum+=7;
    if(strcmp(" 增加 八",str)==0)sum+=8;
    if(strcmp(" 增加 九",str)==0)sum+=9;
    if(strcmp(" 增加 十",str)==0)sum+=10;
}

b.减运算函数编写:

void minus(char str[]){
    if(strcmp(" 减少 一",str)==0)sum-=1;
    if(strcmp(" 减少 二",str)==0)sum-=2;
    if(strcmp(" 减少 三",str)==0)sum-=3;
    if(strcmp(" 减少 四",str)==0)sum-=4;
    if(strcmp(" 减少 五",str)==0)sum-=5;
    if(strcmp(" 减少 六",str)==0)sum-=6;
    if(strcmp(" 减少 七",str)==0)sum-=7;
    if(strcmp(" 减少 八",str)==0)sum-=8;
    if(strcmp(" 减少 九",str)==0)sum-=9;
    if(strcmp(" 减少 十",str)==0)sum-=10;
}

(3)编写输出函数:由于数字只会出现以下 零一二三四五六七八九十 ,所以都可以通过一个个枚举来输出“看看 钱包”中的数值

void look_wallet(int x){
    if(x==0)printf("零");
    if(x==1)printf("一");
    if(x==2)printf("二");
    if(x==3)printf("三");
    if(x==4)printf("四");
    if(x==5)printf("五");
    if(x==6)printf("六");
    if(x==7)printf("七");
    if(x==8)printf("八");
    if(x==9)printf("九");
    if(x==10)printf("十");
}

(4)编写主函数:

int main(){
    char a[100],b[100],c[100],d[100];
    scanf("%s %s %s %s",a,b,c,d);
    char m[100],n[100],s[100],t[100];
    sum=transform(d);getchar();
    for(;;){
        scanf("%s",m);
        if(strcmp("看看",m)==0) break;
        scanf("%s",n);
        scanf("%s",s);
        if(strcmp("增加",n)==0) sum+=transform(s);
        if(strcmp("减少",n)==0) sum-=transform(s);
    } 
    scanf("%s",t);
    result(sum);
    return 0;
}  



通过测试的几组数据最后发现只有小于等于10的结果可以正确输出,因此我将主函数做了以下修改:添加判断条件,若sum小于等于10,直接调用result函数输出结果:若sum大于10,先调用result输出十位上的数,再输出“十”,再次调用result函数输出个位上的数字。

int main(){
    char a[100],b[100],c[100],d[100];
    scanf("%s %s %s %s",a,b,c,d);
    char m[100],n[100],s[100],t[100];
    sum=transform(d);getchar();
    for(;;){
        scanf("%s",m);
        if(strcmp("看看",m)==0) break;
        scanf("%s",n);
        scanf("%s",s);
        if(strcmp("增加",n)==0) sum+=transform(s);
        if(strcmp("减少",n)==0) sum-=transform(s);
    } 
    scanf("%s",t);
    if(sum<=10) result(sum);
    if(sum>10){
        int a;//a为十位上的数 
		a=sum/10;
        if(a==1) printf("十");
        else{
            result(a);
            printf("十");
        }
        result(sum%10);
    }
    return 0;
} 


经过测试,前一次的数据可输出正确答案,但再测试另一组数据,出现了“二十零”的情况,说明前面考虑时忽略了该特殊情况,因此需要增加新的判断条件,判断个位是否为零,若非零则调用result函数输出个位。

二次修改后的主函数代码如下:

int main(){
    char a[100],b[100],c[100],d[100];
    scanf("%s %s %s %s",a,b,c,d);
    char m[100],n[100],s[100],t[100];
    sum=transform(d);getchar();
    for(;;){
        scanf("%s",m);
        if(strcmp("看看",m)==0) break;
        scanf("%s",n);
        scanf("%s",s);
        if(strcmp("增加",n)==0) sum+=transform(s);
        if(strcmp("减少",n)==0) sum-=transform(s);
    } 
    scanf("%s",t);
    if(sum<=10) result(sum);
    if(sum>10){
        int a;//a为十位上的数 
		a=sum/10;
        if(a==1) printf("十");
        else{
            result(a);
            printf("十");
        }
        int b; 
        b=sum%10;
        if(b!=0) result(b);
    }
    return 0;
}  

最终测试结果正确且代码满足各种情况

4.最终完整代码:

#include<bits/stdc++.h>//万能头文件
using namespace std;
int sum;
char name[100],ini[20],cal[100];//变量名,变量初始化,运算
int transform(char str[]){
    if(strcmp("零",str)==0)return 0;
    if(strcmp("一",str)==0)return 1;
    if(strcmp("二",str)==0)return 2;
    if(strcmp("三",str)==0)return 3;
    if(strcmp("四",str)==0)return 4;
    if(strcmp("五",str)==0)return 5;
    if(strcmp("六",str)==0)return 6;
    if(strcmp("七",str)==0)return 7;
    if(strcmp("八",str)==0)return 8;
    if(strcmp("九",str)==0)return 9;
    if(strcmp("十",str)==0)return 10;
}
void add(char str[]){
    if(strcmp(" 增加 一",str)==0)sum+=1;
    if(strcmp(" 增加 二",str)==0)sum+=2;
    if(strcmp(" 增加 三",str)==0)sum+=3;
    if(strcmp(" 增加 四",str)==0)sum+=4;
    if(strcmp(" 增加 五",str)==0)sum+=5;
    if(strcmp(" 增加 六",str)==0)sum+=6;
    if(strcmp(" 增加 七",str)==0)sum+=7;
    if(strcmp(" 增加 八",str)==0)sum+=8;
    if(strcmp(" 增加 九",str)==0)sum+=9;
    if(strcmp(" 增加 十",str)==0)sum+=10;
}
void minus(char str[]){
    if(strcmp(" 减少 一",str)==0)sum-=1;
    if(strcmp(" 减少 二",str)==0)sum-=2;
    if(strcmp(" 减少 三",str)==0)sum-=3;
    if(strcmp(" 减少 四",str)==0)sum-=4;
    if(strcmp(" 减少 五",str)==0)sum-=5;
    if(strcmp(" 减少 六",str)==0)sum-=6;
    if(strcmp(" 减少 七",str)==0)sum-=7;
    if(strcmp(" 减少 八",str)==0)sum-=8;
    if(strcmp(" 减少 九",str)==0)sum-=9;
    if(strcmp(" 减少 十",str)==0)sum-=10;
}
void result(int x){
    if(x==0) printf("零");
    if(x==1) printf("一");
    if(x==2) printf("二");
    if(x==3) printf("三");
    if(x==4) printf("四");
    if(x==5) printf("五");
    if(x==6) printf("六");
    if(x==7) printf("七");
    if(x==8) printf("八");
    if(x==9) printf("九");
    if(x==10) printf("十");
}
int main(){
    char a[100],b[100],c[100],d[100];
    scanf("%s %s %s %s",a,b,c,d);
    char m[100],n[100],s[100],t[100];
    sum=transform(d);getchar();
    for(;;){
        scanf("%s",m);
        if(strcmp("看看",m)==0) break;
        scanf("%s",n);
        scanf("%s",s);
        if(strcmp("增加",n)==0) sum+=transform(s);
        if(strcmp("减少",n)==0) sum-=transform(s);
    } 
    scanf("%s",t);
    if(sum<=10) result(sum);
    if(sum>10){
        int a;//a为十位上的数 
		a=sum/10;
        if(a==1) printf("十");
        else{
            result(a);
            printf("十");
        }
        int b; //b为余数 
        b=sum%10;   
        if(b!=0) result(b); //若余数不为零才调用result函数,否则就会出现二十零这种情况 
    }
    return 0;
}

5.疑惑点及思考解决

1.这道题我用了一一枚举的方法,代码十分冗长,不知道是否有更好的方法优化一下代码;
2.GBK编码转换实在是没搞懂,所以就用了dev.c++,发现也能输入中文且可以正常输出;
3.这道题实质上是字符的处理,处理方式在询问他人后得到启发;
4.测试代码时有些情况无法输出正确答案,通过多测试几组数据就能发现代码存在的缺陷,增加判断条件,最后完善代码。
原文地址:https://www.cnblogs.com/Sweetxinxin/p/12236651.html