作业描述 | 详情 |
---|---|
这个作业属于哪个课程 | 2020福大数计面向对象程序设计 |
这个作业要求在哪里 | 面向对象程序设计寒假作业1 |
1. 安装C++开发环境。 | |
这个作业的目标 | 2. 完成问答题、实践题及编程题 |
3. 发布博客 | |
作业正文 | 2020面向对象程序设计寒假作业1 题解 |
C语言的不足之处 | |
c语言的优缺点 | |
C语言的优点和缺点 | |
其他参考文献 | C语言 符号的不同意义 |
C语言编译过程 | |
c语言编译过程详解,预处理,编译,汇编,链接(干货满满) | |
gcc的使用简介与命令行参数说明 |
问答题:
- 如果你不了解C++请回答以下问题:你认为C语言有什么缺陷(你觉得哪里用的不顺手)。
如果你已经了解C++请回答以下问题:你觉得C++和C语言比有什么优点。
我不了解c++,因此我是想说说C语言。
C语言的有代码量小、运行速度快、功能强大三个优点,它也有许多缺陷。
(1) 危险性高
C语言的语法限制不太严格,程序设计自由度大。这个特点使得程序设计更主动、灵活,但也埋藏了许多危险。例如:C语言中可以将一个浮点型数据赋给一个整型数据,会丢失精度但不影响程序运行;C语言对数组下标越界不检查,容易造成数据在内存中的混乱等。
对于这些细小的问题,不仅要求使用者对程序设计更熟练,而且制造了许多小漏洞,容易被利用,引起程序的安全问题。
(2) 运算符多样,易混淆
C语言具有多种运算符,如果运用熟练,能充分体现C语言表达灵活和效率高等特点,但这也增加了使用难度,多样的运算符和优先级可能会混浠造成错误。
(3) 许多运算符具有不同意义
例如C语言中static在函数内部,表达该变量的值在各个调用间一直保持延续性,类似于全局变量;在函数外部,表达该函数或者变量只对本文件可见。多重意义的还有extern,void,*,&等。这对于初学者程序设计时造成了许多麻烦和困扰。
我是个初学者,经常饱受C语言语法限制不严格的恶意,正如C语言浮点型可以赋给整型,且不会提示错误,这在我前期的程序设计和作业考试中带给我不少的麻烦。多样的运算符也带给我不少的困扰,最深刻的还是学习scanf函数时,经常忘记加&以致于错误。 - 查阅相关资料,简述一下C语言/C++的编译过程。
C语言编译过程:源文件->预编译->编译->链接
第一步:编辑源文件
第二步:预处理
(1) 将所有的#define删除,并且展开所有的宏定义
(2) 处理所有的条件编译指令(带#的指令)
(3) 处理#include,将#include指向的文件插入到该行处
(4) 删除所有注释
(5) 添加行号和文件标示,这样在调试和编译出错的时候才知道是哪个文件的哪一行
(6) 保留#pragma编译器指令
第三步:编译 从高级语言->汇编语言->机器语言
(1) 词法分析
(2) 语法分析
(3) 语义分析
(4) 优化后生成相应的汇编代码
(5) 汇编代码转换为机器码
编译的过程就是把源文件翻译成二进制文件
第四步:链接
将源文件中用到的库函数与汇编生成的目标文件合并生成可执行文件
这个过程,就是将源文件从.c变成.exe的过程。
实践题:
如果是Devc++的gcc编译器的话,可以通过在命令行中打入gcc –v查看版本
如图:
但是这两个都需要设置环境变量,方法如下:在我的电脑->属性->高级系统设置->环境变量->系统变量的Path中输入编译器地址。例如Devc++的gcc编译器,本人的地址是D:\办公\Dev-Cpp\MinGW64\bin,因此Path中也需如此输入。
如图:
- 使用命令行编译一份C语言/C++代码。
编写一个程序,输入满足以下语法要求的一段文字,输出运行后的结果。
变量定义:整数 钱包 等于 零
运算(加法):钱包 增加 四
运算(减法):钱包 减少 四
输出:看看 钱包
注:数值只会出现零一二三四五六七八九十
(1)提取题目要去:由题可得,我需要输入一段文字,得到文字描述的答案
首先我需要进行一次变量定义,随后是n次的代数运算,最后是输出运算后的结果。
特别注意的是单次数值只会在0到10 中出现。
(2)模块化:我将问题分为一个主模块和三个副模块
主模块main中,我首先将变量定义设置了四个数组啊a,b,c,d,分别输入数据类型、变量名、符号、数值。其中变量名并不是很重要,就像钱包只是个皮囊包装,无关紧要,重要的还是里面的money(数值),因此我在随后的运算中使用同个变量名coin。之后,在运算部分,我设置一个一个以“看看”字符串结尾的while循环,循环中反复输入变量名、符号、数值。
第一副模块num负责返回d数组即数值数组中数值字符对应的数字,但只能是零到十,其他字符将会返回-1,在接下来的判断中提示错误。
int num(char d[])
{
if(!strcmp(d,"零")) return 0;
else if(!strcmp(d,"一")) return 1;
else if(!strcmp(d,"二")) return 2;
else if(!strcmp(d,"三")) return 3;
else if(!strcmp(d,"四")) return 4;
else if(!strcmp(d,"五")) return 5;
else if(!strcmp(d,"六")) return 6;
else if(!strcmp(d,"七")) return 7;
else if(!strcmp(d,"八")) return 8;
else if(!strcmp(d,"九")) return 9;
else if(!strcmp(d,"十")) return 10;
else return -1;
}
第二副模块judge,块如其名,是用来判断c符号数组对应的运算符号并与num模块顺便运算,返回运算值。judge模块主要出没于主模块的while循环中。如果出现加减乘除之外的字符,这个模块会毫不客气的指出你的错误(我愚蠢的阿豆豆哟!)
int judge(int n ,char c[],char d[])
{
if(!strcmp(c,"增加")) return n+num(d);
else if(!strcmp(c,"减少")) return n-num(d);
else if(!strcmp(c,"乘以")) return n*num(d);
else if(!strcmp(c,"除以")) return n/num(d);
else printf("输入错误");
}
第三副模块sum,最终模块,负责对n次运算结束后的最终数值进行数字转中文字符的转化。考虑钱包有可能有十元、百元、千元等情况,综合我的钱包情况,得出结论:钱包是没有百元以上的。再考虑两位数的称呼问题,我统一两位数为x十x,如二十四。
此模块中,我首先制定了零到九的十位字符数组,再将得到的最终数值分解成十位和个位,一一对应在中间加字符“十”输出,即得结果。
void sum(int n)
{
char nums[10][4]={"零","一","二","三","四","五","六","七","八","九"};
if(n<10) printf("%s",nums[n]);
else
{
int m=n%10;
n=n/10;
printf("%s十%s",nums[n],nums[m]);
}
}
(3)全体分析
我的代码中,将输入的字符串分解成几个部分是因为由题输入中每个词语都是用空格间隔的,在多个数组输入时,因为有空格会将每个词语分割到对应的数组中。
接着,代码中大量运用strcmp函数对比两个字符串,是因为中文字符占了两个以上的字符位,我想到的遍历方法是不能输出单个中文字符的,因此用strcmp对比判断。
(4)命令行编译
最让我头疼的部分来了!我经常使用的是Devc++,vs还是昨天下载的。在查看vs编译器版本并亲自用命令行和cl.exe编译了一个helloworld后,我膨胀了,然后喜闻乐见的事情,C语言很多函数我在vs上提示错=错误……然后我改用DevC++。
代码敲完之后,使用命令行编译,
首先我在记事本中写入代码,另存为gcc所在目录下并保存为text.c格式,然后需要在命令行中找到gcc编译器,并按照gcc text.c –o text.exe的格式,将源文件变为可执行文件,这个格式我找了很久……关于gcc可以参考网址
https://www.cnblogs.com/fengliu-/p/10219850.html
如图操作:
(5)完整代码
include
include
int num(char d[])
{
if(!strcmp(d,"零")) return 0;
else if(!strcmp(d,"一")) return 1;
else if(!strcmp(d,"二")) return 2;
else if(!strcmp(d,"三")) return 3;
else if(!strcmp(d,"四")) return 4;
else if(!strcmp(d,"五")) return 5;
else if(!strcmp(d,"六")) return 6;
else if(!strcmp(d,"七")) return 7;
else if(!strcmp(d,"八")) return 8;
else if(!strcmp(d,"九")) return 9;
else if(!strcmp(d,"十")) return 10;
else return -1;
}
int judge(int n ,char c[],char d[])
{
if(!strcmp(c,"增加")) return n+num(d);
else if(!strcmp(c,"减少")) return n-num(d);
else if(!strcmp(c,"乘以")) return n*num(d);
else if(!strcmp(c,"除以")) return n/num(d);
else printf("输入错误");
}
void sum(int n)
{
char nums[10][4]={"零","一","二","三","四","五","六","七","八","九"};
if(n<10) printf("%s",nums[n]);
else
{
int m=n%10;
n=n/10;
printf("%s十%s",nums[n],nums[m]);
}
}
int main()
{
char a[10], b[10], c[10], d[10];
int coin;
scanf("%s%s%s%s",a,b,c,d);
getchar();
if(!strcmp(a,"整数"))
{
if(num(d)==-1) printf("输入错误\n");
else coin += num(d);
}
while(2)
{
scanf("%s",b);
if(!strcmp(b,"看看"))
{
if(coin>99) printf("我真的没那么多钱");
else sum(coin);
break;
}
scanf("%s%s",c,d);
coin = judge(coin,c,d);
}
}
(6) 样例展示
本萌新能力有限,博客不太会弄,排版不行,如对我的题解有问题,欢迎各位向我指出,一起学习!QAQ