第2章 C/C++快速入门

  1. 对于让C++使用者觉得麻烦的 scanf 函数和 printf 函数,虽然必须承认 cin 和 cout 可以不指定输入输出格式 较方便,但是 cin 和 cout 消耗的时间比 scanf 和 printf 多得多,很多题目可能输入还没结束就超时了。当然,读者可以在某次使用 cin 和 cout 超时,改成 scanf 和 printf 后通过的时候,痛下决心以后使用 scanf 和 printf。
    顺便指出,请不要同时在一个程序中使用 cout 和 printf,有时候会出问题
  2. 记住绝对值在109范围以内的整数都可以定义成int型。
  3. %f 是 float 和 double 型的输出格式。
  4. 因此,对浮点型来说,只需要记住一点,不要使用float, 碰到浮点型的数据都应该用double来存储。
  5. typedef long long ll;
  6. 常用的math函数
fabs(double x)  用于对double类型的变量取绝对值
floor(double x)   向下取整
ceil(double x)   向上取整
pow(double r, double p)  求r的p次幂
sqrt(double x)  用于返回double型变量的算术平方根
log(double x)  用于返回double型变量的以自然对数为底的对数    /*换底公式*/
sin(double x)
cos(double x)
tan(double x)
asin(double x)  反正弦
acos(double x)  反余弦
atan(double x)  反正切
round(double x)  用于将double变量四舍五入,返回类型也是double类型,需要进行取整
  1. 数组大小必须是整数常量,不能是变量。
  2. 特别提醒:如果数组大小较大(大概106级别),则需要将其定义在主函数外面,否则会使程序异常退出,原因是函数内部申请的局部变量来自系统栈,允许申请的空间较小;而函数外部申请的全局变量来自静态存储区,允许申请的空间较大。
  3. 建议初学者使用 memset 赋0或-1。这是因为 memset 使用的是按字节赋值,即对每个字节赋同样的值,这样组成 int 型的4个字节就会被赋成相同的值。而由于0的二进制补码为全0, -1的二进制补码为全1,不容易弄错。
    如果要对数组赋其他数字,那么请使用 fill 函数(但memset的执行速度快)。
  4. 指针是一个 unsigned 类型的整数
  5. 如果想要读入一整行,则需要使用 getline 函数,例如下面的代码就把一整行都读入char型数组str[100]中:
char str[100];
cin.getline(str, 100);

如果是string容器,则需要用下面的方式输入:

string str;
getline(cin, str);
  1. 事实上,对考试而言,并不推荐读者使用 cin 跟 cout 来进行输入和输出,因为它们在输入输出大量数据的情况下表现得非常糟糕,有时候题目的数据还没有输入完毕就已经超时。因此还是推荐读者使用C语言的 scanf 与 printf 函数进行输入输出,只有在十分必要的时候才使用 cin 与 cout (例如string)

一、sscanf 与 sprintf

  • sscanf 与 sprintf是处理字符串问题的利器,读者很有必要学会它们 (sscanf从单词上可以理解为string + scanf,sprintf 则可以理解为 string + printf,均在stdio.h头文件下)。
  • 回顾一下,事实上,其实可以表示成下面的样子,其中screen表示屏幕:
scanf (screen, "%d”, &n);
printf (screen, "%d", n);
  • 可以发现,scanf 的输入其实是把 screen 的内容以"%d"的格式传输到n中**(即从左至右),而printf的输出则是把n以"%d"的格式传输到screen上(即从右至左)**。
  • sscanf 与 sprintf 与上面的格式是相同的,只不过把screen换成了字符数组(假设定义了一个char数组str[00]),如下所示:
sscanf(str, "%d", &n);
printf("%d", n);
  • 上面 sscanf 写法的作用是把字符数组str 中的内容以"%d"的格式写到n中,从左至右
sprintf(str, "%d", &n);
printf("%s", str);
  • 而 sprintf 写法的作用是把n以"%d"的格式写到str字符数组中,从右至左
  • 复杂一些,使用 sscanf 将字符数组str 中的内容按 "%d:%lf, %s"的格式写到 int型变量n、double 型变量db、char 型数组str2中。
sscanf(str, "%d:%lf, %s", &n, &db, str2);
  • 使用 sprintf 将int型变量n、double 型变量db、char 型数组str2 按"%d:%.2f, %s"的格式写到字符数组str中。
sprintf(str, "%d:%.2f, %s", n, db, str2);
  • 最后指出,sscanf 还支持正则表达式,如果配合正则表达式来进行字符串的处理,那么很多字符串的题目都将迎刃而解。(正则表达式在此不作深入探讨,有兴趣的读者可以自己去了解)。

二、浮点数的比较

由于计算机中采用有限位的二进制编码,因此浮点数在计算机中的存储并不总是精确的。
例如在经过大量计算后,一个浮点型的数 3.14 在计算机中就可能存储成 3.10000000001 ,也有可能存储成 3.13999999999 ,这种情况下会对比较操作带来极大的干扰 (因为C/C++中的 == 操作是完全相同才能判定为true),于是需要引入一个极小数eps来对这种误差进行修正。

那么eps应当取多少呢?经验表明,eps 取10-8是一个合适的数字,对大多数的情况既不会漏判,也不会误判。因此可以将 eps 定义为常量1e-8:

const double eps = 1e-8;

1、等于运算符

#define Equ(a, b) ((fabs((a) - (b)))<(eps))

2、大于运算符

#define More(a,b) (((a)-(b))>(eps))

3、小于运算符

#define Less(a,b) (((a)-(b))<(-eps))

4、大于等于

#define MoreEqu(a,b) (((a)-(b))>(-eps))

5、小于等于

#define LessEqu(a,b) (((a)-(b))<(eps))

6、圆周率

const double PI = acos(-1.0);

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/88782229
今日推荐