题解 B2001 【入门测试题目】
Update
Content
给定
数据范围:
Solution & Code
本题解仅适用于 C++ 选手。
这道题可谓是 C++ 中最基础的题目之一,先上两份代码:
1
#include <cstdio>
using namespace std;
int main() {
long long a, b;
scanf("%lld%lld", &a, &b);
printf("%lld", a + b);
return 0;
}
2
#include <iostream>
using namespace std;
int main() {
long long a, b;
cin >> a >> b;
cout << a + b;
return 0;
}
那么这一行行语句都代表着什么呢?这两个程序如何达到相同的效果呢?接下来就对此进行详细讲解。当然,初学者如果看不懂这些东西其实也无关紧要,因为这些都将在我们今后的学习中逐渐了解。
Part 1 基础语言知识
首先我们要知道程序最开始的 #include <xx> 是什么意思,其实就是把 C++ 中的一些头文件库给包括进来,这里给几个常见的头文件库:
<cstdio> //输入/输出(这是注释)
<iostream> //输入/输出流
<string> //字符串类
<cstring> //同上
<cmath> //包含了许多实用的数学函数,例如 sin(),cos(),tan(),sqrt(),pow() 等
<algorithm> //STL 通用算法
<stack> //STL 栈容器
<queue> //STL 队列容器
<deque> //STL 双端队列容器
<map> //STL 映射容器
<vector> //STL 动态数组容器
/*
这是多行注释。
STL 可以很方便的简化我们的代码,但是常数很大,
有时运行起来很慢,所以建议知道如何手写。
这将是我们以后学习的内容,现在不知道并无大碍。
*/
对于这道基础题目,我们只需要包含 cstdio 库或者 iostream 库,因为这道题目只需要我们输出
然后就是数据类型的问题。我们先不妨认识一些常用的数据类型。下图的这些数据类型(C++ 其他常用数据类型除外)统称为预定义类型,也就是说,这些数据类型是 C++ 已经为你准备好的。
另外,我们还将学到数组、结构体 struct 联合体 union、枚举 enum 等其他比较灵活的类型,这些数据类型统称为自定义数据类型。
那我们如何选择数据类型呢?这得要从数据范围来决定。以下给出了常用数据类型在通常情况下的范围(建议去题解页面查看),对于今后做题时变量应该如何选择数据类型有很大的作用:
| 数据类型 | 范围 |
|---|---|
| char | |
| unsigned char | |
| signed char | |
| int/long (int) | 通常情况下为 |
| unsigned int | |
| signed int | 同 int |
| short int | 至少 |
| unsigned short int | |
| signed short int | 同 short int |
| long long (int) | 通常情况下为 |
| signed long long (int) | 同 long long (int) |
| unsigned long long (int) | |
| float | |
| double | |
| long double |
关于 long double 的一些说明:long double 是一种扩展精度浮点类型,不一定映射到 IEEE-754 所强制的类型。在 x86 和 x86-64 架构上通常为 80 位 x87 浮点类型。表格中采取的 long double 的数据范围来源于这篇文章。
然后就是函数了,函数有头文件库里面自带的,也有你需要在程序中自己写出来的。比如说 sin()、sort() 这些就是 C++ 的头文件库里面自带的,而通常程序中有些函数需要你自己写出来。在需要自己写出来的函数中,最重要也是最必不可少的就是 main() 函数。一般在算法竞赛中,它的类型通常是 int,而且最后通常会要求你写 return 0;,具体的意义不做赘述。除了 main() 函数和头文件库里面自带的函数外,你也可以自己写一些其他的函数,达到精简代码的效果。
然后就是输入和输出了,如果你调用的是 cstdio 库的话,它里头包含的最常用的输入函数就是 scanf()。
scanf() 函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回 EOF(End of file,即文件结尾)。例如,对于这道题,我们需要读入 scanf("%d%d", &a, &b),其中 %d 是 int 这个数据类型在 scanf() 函数中的格式,其它的格式还有 %f float、%lf double、%lld long long 等。另外,scanf() 函数还有一个强大的功能,就是你可以用 scanf() 按照某一个特定的格式读入数据,例如,你想要按照 hh:mm 的个数读入 scanf("%d:%d", &hh, &mm)。注意,如果是整形类型的话,变量前的 & 必不可少。
为什么要加一个 & 号?这里不多做讲述,感兴趣的各位可以去看这个剪贴板。
如果你调用的是 iostream 库的话,它里头包含的输入流(注意!并不是函数)是 cin。你就把输入流想象成一条河流,源源不断地输入数据就行,这里就不给出严格定义了。在 cin 中,每一个输入的数据以 >> 号连接,前面并不需要加 &。
然后就是输出了,输出其实和输入很类似,所以这里仅作简略讲解。
scanf() 函数对应的是 printf() 函数,返回成功输出的数据项数。按照和 scanf() 一样的格式,同样也可以按照某个特定格式输出数据,例如 %8d 就可以讲一个整数按以 %02d 就可以将一个整数输出,并且如果不足两位的话会向前补前导零。例如 printf("%8d, %02d", 2, 2) 对应的输出结果就是:
2, 02
另外如果题目要求保留一位小数或者你的输出应与答案的相对误差不超过 %.xlf或者 %.xf 输出(其中 x 里面是数字),例如保留一位小数就可以写成 printf("%.1lf", x);。
输入流 cin 自然也就对应输出流 cout,你同样也可以将其想象成一条源源不断地输出数据的河流。但请注意,在 cout 中,每一个输出的数据以 << 连接!!!除了这个地方和 cin 不同之外,其他的都和 cin 并无差异。
那么 cout 是否也可以做到按位输出或者按某个特定宽度右对齐输出呢?答案是肯定的,但由于版面原因,这里并不做介绍,感兴趣的各位可以直接上网查询。
Part 2 本题你需要了解的一些东西
对于这道题目来说,
接下来就是如何表示 +、-、*、/,但请注意,/ 在 C++ 中的定义并不完全等同于我们平常的四则运算中的除法,如果两边都是整型变量,在 C++ 中,/ 默认为整除。那么有没有办法可以让它变成我们平常的除法呢?答案是肯定的,让 / 两边中的一个或者两个数变成浮点型变量(/ 的结果变为实际结果而不是整除后的结果了。例如,() 罢了。
那么我们对于程序做了深入的剖析,想必大家都已经领会到 C++ 的语言魅力了。
Notice
本文章引用了一些网络上的内容,由于作者能力有限,可能仍不免有诸多错误,欢迎各位在评论区指出,作者将定期订正这些错误。
同时,如果您认为这篇文章侵犯了你的著作权,请及时和作者联系换下。
另外,这篇文章期间也经过了一些不小的修改,感谢 WYXkk、XYY1411、Implicit 等各路神仙对这篇文章提出的宝贵的修改建议,才使得这篇文章经过不断完善变得更加充实和严谨!
祝各位的信息之路愉快而又充实!