c++学习

vector:可(扩展)变数据类型

输入输出

cin:c in 输入 cout:c out 输出

流操作符

<<输出流操作符 >>输入流操作符

转义符的使用

\n 换行 等同于 std::endl(end line) \t tab键 \转义符

头文件

include 引入

<iostream>

input | output :io 输入输出 stream:流(类比“水流”,字符流|字节流|文件流”)

变量

变量只是一个名称,它代表 计算机内存的特定位置,供用户 存储 、检索 和 使用 数据。

数据类型

  • int :整数(整型)
  • double :浮点数 | float(实型)
  • char :字符
  • string :字符串
  • bool :布尔值(真/假值)

复习并总结 C++ - 图1

变量的声明

在一个变量可以使用之前,我们需要事先声明(创建)变量。要声明一个变量,我们需要确定两个内容:

  • 变量的类型
  • 变量的名称

复习并总结 C++ - 图2

  1. int score = 0;
  2. //等效于
  3. int score;
  4. score =0

算术运算符

  • + 加法
  • - 减法
  • * 乘法
  • / 除法
  • %求余(获得整数除法后的余数)

头文件

.h(head)c语言的头文件以.h结尾

iostream c++的头文件

C++中的输出:cout

C++中,输出操作使用对象cout,需要包含头文件。以下是cout的主要特点和用法:

  • cout是一个对象,不是关键字或函数。
  • 可以输出常量和变量,根据需要连续输出。
  • 相对于printfcout能够自动识别变量的类型,无需指定格式符。
  • 输出控制使用特定的控制符,如endl\n

C语言中的输出:printf

在C语言中,输出操作使用函数printf,需要包含头文件。以下是printf的主要特点和用法:

  • printf是一个函数。
  • 需要指定格式符来输出变量的类型,如%c%d%s等。
  • 可以根据需要连续输出,但需要为每个变量指定相应的格式符。

向量与循环结构

向量

创建向量格式:

  1. std::vector<type>name;
  2. //列如:
  3. std::vector<int>grades(3);

它只能存储同类型的元素

所需的头文件:

  1. #include <vector>

向量初始化

方法1:创建时直接初始化

  1. std::vector<double>location = {121.674849,31.14839};

大括号之间的两个double数据,就是向量locaton的初始值(经度、纬度)

方法2:

  1. std::vector<double>location;
  2. location = {121.674849,31.14839};

方法3: 先声明,后对成员内容赋值

  1. std::vector<douvle>location;
  2. location[0] = 121.674849;
  3. location[1] = 31.14839;

添加与删除向量中的元素

.push_back() 压人一个元素

如果需要在向量的末尾(也就是最后一个元素之后)添加一个新元素 可以使用.push_back()

.pop_back() 弹出一个元素

如果我们想把向量的最后一个元素 移除,我们要使用的方法就是.pop_back()

英文字母

复习并总结 C++ - 图3

char类型 是一种存储字符的变量。

计算:M在字母表中是第几位。

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a ;
  6. a = 'M'-'A'+ 1;
  7. cout<<a<<endl;
  8. }

计算:第18位是什么字母

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a ;
  6. a = 'M'-'A'+ 1;
  7. cout<<a<<endl;
  8. char b;
  9. b = 'A' + (18- - 1);
  10. cout<<b<<endl;
  11. }

字符 要用''单引号进行括起来。

数字反转

复习并总结 C++ - 图4

方法1

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. double p;
  5. int a, b, c, d, q;
  6. cin >> p;
  7. q = int(p * 10);
  8. a = q / 1000;
  9. b = q / 100 % 10;
  10. c = q / 10 % 10;
  11. d = q % 10;
  12. cout << d << "." << c << b << a << endl;
  13. return 0;

方法2

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. char a, b ,c ,dot , d;
  5. cin>>a>>b>>c>>dot>>d;
  6. cout<<d<<dot<<c<<b<<a;
  7. }

scanf | printf 占位符

用于 格式化输入输出 数据的方法之一。 可以指定不同格式,如保留多少位浮点数、输出的数据占多宽的空间,等等。 这些占位符常用于 C 语言风格的输入输出方式,即scanf/printf 。 这些占位符,都以百分号%为开头。 复习并总结 C++ - 图5

其它格式化输出 复习并总结 C++ - 图6

方法3:使用scanf与printf实现数字反转(p5705)。

  1. #include <cstdio>
  2. int main() {
  3. char a,b,c,d;
  4. scanf("%c%c%c.%c",&a,&b,&c,&d);
  5. printf("%c.%c%c%c",d,c,b,a);
  6. }

再分肥宅水

这道题需要使用浮点数进行运算,输出时指定了精度。 可以使用占位符 %lf 输入, %.3f 输出。

  1. #include<cstdio>
  2. using namespace std;
  3. int main() {
  4. double t;
  5. int n;
  6. scanf("%lf%d", &t, &n);
  7. printf("%.3f\n%d", t / n, n * 2);
  8. return 0;
  9. }

顺序结构程序设计案例

交换变量

交换变量 例 2.9 定义两个变量 a 和 b 并输入两个数字存储进它们。 交换这两个变量并输出。

a=b;b=a;行不行呢?

假设给你一杯可乐,一杯雪碧,要如何把这两个杯子中的饮料进行交换呢? 复习并总结 C++ - 图7 t = a;a = b;b = t;

一组相关的短语句也可以写在一行内

算法竞赛的基本格式

一般来讲,对于输入的内容,每个数字之间以空格或者回车隔开。 如图,是洛谷题目 P1425 的输入样例。

请仔细阅读输入格式和输出格式,了解如何输入输出。 复习并总结 C++ - 图8

分支结构

apples

复习并总结 C++ - 图9

x为1输出apple。x > 1 输出 apples

方法1:

  1. #include <iostream>
  2. using namespace std;
  3. int main(){
  4. int x ;
  5. cin >> x;
  6. if(x== 1){
  7. cout << "Today,I ate 1 apple " << endl;}
  8. else{
  9. cout << "Today,I ate " << x << " apples ";
  10. }
  11. }

方法2:

  1. include <iostream>
  2. using namespace std;
  3. int main(){
  4. int x ;
  5. cin >> x;
  6. cout << "Today,I ate " << x << " apple";
  7. if(x > 1){
  8. cout << "s";
  9. }
  10. }

小洛机器人

复习并总结 C++ - 图10

  1. #include <iostream>
  2. using namespace std;
  3. int main(){
  4. char ch;
  5. cin >> ch;
  6. switch (ch) {
  7. case 'G':
  8. cout << "Hello, my master!" << endl;
  9. // cout << "I'm Xiaoluo." << endl;
  10. // break;
  11. case 'N':
  12. cout << "I'm Xiaoluo." << endl;
  13. break;
  14. case 'S':
  15. cout << "Teinei teinei teinei~"<< endl;
  16. break;
  17. case 'B':
  18. case 'Q':
  19. cout << "Bye bye!" << endl;
  20. break;
  21. default:
  22. cout << "Sorry..." << endl;
  23. }

关系表达式与逻辑表达式

复习并总结 C++ - 图11

运算优先级

复习并总结 C++ - 图12

浮点数精度误差

浮点数可能会产生精度误差 所以一般不用== 来判断两个浮点数是否相等 正确的方式:比较这两个数的差值是否小于一定程度 假设fabs(a-b)<1e-6 成立,就可以认为浮点数a 和b 相等。注意要用<cmath> 头文件

  1. double a, b;
  2. ......
  3. if (a == b) // 这么写是错误的!会造成浮点数误差!
  4. if (fabs(a - b) < 1e-6) // 正确的写法,注意 <cmath>

数的性质 (p5710)

例3.2(洛谷P5710)

一些数字可能拥有以下的性质:

  • 性质1:是偶数;
  • 性质2:大于4 且不大于12。

小A 喜欢这两个性质同时成立的数字;Uim喜欢这至少符合其中 一种性质的数字;八尾勇喜欢刚好有符合其中一个性质的数字; 正妹喜欢不符合这两个性质的数字。

现在输入一个数字x(0≤x≤100),要求输出这4 个人是否喜欢这 个数字,如果喜欢则输出1,否则输出0,用空格分隔。

闰年判断

例3.3(洛谷P5711)

输入一个年份(大于1582 的整数),判断这一年是否为闰年,如 果是输出1,否则输出0。

  • 被4 整除(p1)是闰年,除非
  • 被100 整除(p2)不是闰年,除非
  • 被400 整除(p3)又是闰年
  1. #include <iostream>
  2. using namespace std;
  3. int main(){
  4. int n ;
  5. cin >> n;
  6. bool p1,p2,p3;
  7. p1 = (n % 4) == 0;
  8. p2 = (n % 100 ) == 0; // 成立是平年 不成立是闰年
  9. p3 = (n % 400 ) == 0;
  10. if(p3 || (p1 && !p2) ){
  11. cout << "闰年" << endl;
  12. }

复习并总结 C++ - 图13

复习1:

顺序结构与条件结构:

小鱼的游游泳时间(p1425)

复习并总结 C++ - 图14

成绩

复习并总结 C++ - 图15

使用 分数计算,避免触及 浮点运算:

printf("%d", a * 2/10 + b * 3/10 + c * 5 /10);

解法 1: 注意“A,B,C 都是 10 的整数倍”。 每一小项经过加权,即使有乘上一个小数,但是结果一定是整数。 可以把 0.2 变成 2/10, 使程序不接触浮点数,不必考虑浮点误差。

*2 / 10 ,整个运算中都中整型运算, /运算,自动舍去小数部分。

解法2:

  1. int a, b, c;
  2. scanf("%d%d%d", &a, &b, &c);
  3. printf("%d", int(a * 0.2 + b * 0.3 + c * 0.5 + 0.5)); return 0;

直接加权计算。

int(……) 是指不是整数的内容 强制转换 为 int 类型,舍掉小数位数 只保留整数 。double(……) 可以强制转换为 double 。

为什么最后加上了一个 0.5?是因为浮点误差(例如 89.9999)。

小玉买文具

复习并总结 C++ - 图16

总结

  • double: 用于存放小数的变量类型。
  • char: 用于存放字符的变量类型。 ASCII将每个字母和数字对应。
  • cin>>a: 用于读入输入的信息给表示变量 a 。 一道题目如果按照题意不好解决,不妨想想能不能换一种数据处 理的方式,比如把数字当成字符

嵌套条件

if …… else if …… else ……

短路判断

计算表达式时,如果只计算部分内容就可以确保一个表达式的结 果,那么剩余部分计算机就不会继续运算下去了。 例如:

  • a||(b&&!c),当a 为真,表达式肯定也是真,不用继续算
  • a&&(b||c||d||e||f),当a 为假,表达式肯定为假
  • x>0&&sqrt(x)-round(sqrt(x))<1e-6,当x是负数时,后面的就不 会继续运算,也不会造成RE。

体重BMI

复习并总结 C++ - 图17

  1. double m, h, BMI;
  2. cin >> m >> h;
  3. BMI = m / h / h;
  4. if (BMI < 18.5)
  5. cout << "Underweight";
  6. else if (BMI < 24)
  7. cout << "Normal";
  8. else {
  9. cout << BMI << endl;
  10. cout << "Overweight" << endl;
  11. }

for循环

复习并总结 C++ - 图18

找最小值

复习并总结 C++ - 图19

  • 头文件algorithm的max(),min(),和abs()
  • max() min()参数为两个,可以是整型或浮点型,返回最大值和最小值
  • 适用于个数不多的比较时
  • abs()返回绝对值,整数
  • math的fabs(),进行浮点数的取绝对值功能

解法1:使用minnum

  1. #include <algorithm>
  2. int n;
  3. cin << n;
  4. //int tmp = 2147483647;
  5. int tmp, minnum =2100000000;
  6. for(int i = 1; i <= n ; i++){
  7. cin << tmp;
  8. minnum = min(minnum , tmp)
  9. }
  10. cout << minnum;

解法2:使用if

  1. int n;
  2. cin << n;
  3. //int tmp = 2147483647;
  4. int tmp, minnum =2100000000;
  5. for(int i = 1; i <= n ; i++){
  6. cin << tmp;
  7. // 比较 最新输入的值是不是比当前最小值还小
  8. if(tmp < minnum){
  9. minnum = tmp;
  10. }
  11. }
  12. cout << minnum;

while循环

复习并总结 C++ - 图20

一尺之棰

复习并总结 C++ - 图21

注意,从第二天开始,所以定义days 默认为1;

  1. include using namespace std;
  2. int main() { int a; int days = 1;
  3. // a = 1 cin >> a;
  4. while (a > 1) {
  5. days++;
  6. a = a / 2;
  7. cout << days: << days << a: << a << endl; }
  8. cout << days; }

多重循环

循环语句也能互相嵌套。如果需要循环的“大操作”中有好几个重复 的小操作,就可以进行循环嵌套。 如果超过一个语句,或者需要调整层级,则必须要大括号,建议 全部加上括号。

注意内层循环变量名不能和外层循环变量名冲突。

  1. for (;;) {
  2. for (;;) {
  3. for (;;) {
  4. // 内层循环体
  5. }
  6. }
  7. for (;;)
  8. while (...) {
  9. // 内层循环体
  10. }
  11. }

数字直角三角形

复习并总结 C++ - 图22

我们可以把这个任务分成两个层级

  1. 大任务:输出每一行。需要一个外层循环,其循环体就是输出 一行的内容。循环变量从 1 到 n (也可以 0 到 n-1)。
  2. 小任务:输出一行中的每一个数字。需要一个内层循环,用于 输出一行中的每一个数字。共需要打出 n 行,所当处理第 i 行时, 需要输出 n-i+1 个数字。

定义变量 cnt 来记录输出到那个数字

  1. #include <cstdio>
  2. #include <iostream>
  3. using namespace std;
  4. int main() {
  5. int cnt = 0,n;
  6. scanf("%d",&n);
  7. for ( int i = 0;i <= n ; i++){
  8. for ( int j = 1; j <= n - i ; j++){
  9. ++cnt;
  10. printf("%02d",cnt);
  11. }
  12. cout << endl;
  13. }
  14. }

求阶乘之和

long long n ; 有效值为 9 * 10^18 ;

例 4.7 (洛谷 P1009,有改动)

计算 S = 1! + 2! + 3! + ⋯ + n! (n ≤ 20) 的值,其中 i! 是指 i 的阶乘,即 i! = 1 × 2 × ⋯ × i 。

分析: 按计算器可发现, 20 的阶乘大约 2.4 × 1018,所以可以使用 long long 类型存下。

long long 是一种整数类型,可以放下 9 × 1018的数字,但是比 int 又大又慢。

,逗号表达式

将两个不同的表达式写在了一起,变成了一条语句,变成了逗号表达式。 有时可以使语句变得精炼。

  1. //正确写法 1 使用大括号包括多个语句
  2. if (t1 + t2 > maxtime) {
  3. maxtime = t1 + t2; maxday = 1;
  4. }
  5. //正确写法2使用逗号表达式链接多个语句成为一个语句
  6. if (t1 + t2 > maxtime)
  7. maxtime = t1 + t2, maxday = 1;
  8. //错误写法,第二个语句不在if管辖范围内
  9. if (t1 + t2 > maxtime)
  10. maxtime = t1 + t2; maxday = 1;

通常用于类似 “变量交换”

三位数排序(p5715)

复习并总结 C++ - 图23 方法一: 排列组合进行穷举(列举)所有的可能。

  1. int a, b, c;
  2. scanf("%d%d%d", &a, &b, &c);
  3. if (a <= b && b <= c) printf("%d %d %d\n", a, b, c);
  4. else if (a <= c && c <= b) printf("%d %d %d\n", a, c, b);
  5. else if (b <= a && a <= c) printf("%d %d %d\n", b, a, c);
  6. else if (b <= c && c <= a) printf("%d %d %d\n", b, c, a);
  7. else if (c <= a && a <= b) printf("%d %d %d\n", c, a, b);
  8. else /*if (c <= b && b <= a)*/ printf("%d %d %d\n", c, b, a);

方法二: 求出某个最大值,再对别两个值进行判断

  1. int a, b, c;
  2. scanf("%d%d%d", &a, &b, &c);
  3. if (a >= b && a >= c)
  4. if (b >= c)
  5. printf("%d %d %d\n", c, b, a);
  6. else
  7. printf("%d %d %d\n", b, c, a); // 这个else搭配哪个if呢?
  8. else if (b >= a && b >= c)
  9. if (a >= c)
  10. printf("%d %d %d\n", c, a, b);
  11. else
  12. printf("%d %d %d\n", a, c, b);
  13. else // if (c >= a && c >= b) 本句可加可不加
  14. if (a >= b)
  15. printf("%d %d %d\n", b, a, c);
  16. else
  17. printf("%d %d %d\n", a, b, c);
  1. int a = 8, b =6, tmp;
  2. // 交换 a,b
  3. tmp = a, a = b, b = tmp;

方法三: 三次交换

  1. int a, b, c, p;
  2. scanf("%d%d%d", &a, &b, &c);
  3. if (a > b)
  4. p = a, a = b, b = p;
  5. if (a > c)
  6. p = a, a = c, c = p;
  7. if (b > c)
  8. p = b, b = c, c = p;
  9. printf("%d %d %d", a, b, c);

?问号表达式

问号表达式与叫“三目表达式”

问号表达式的形式是 S1?S2:S3 如果S1条件成立,那么这个表达式的值是S2,否则是S3。 例如: 意思是b= (a==1) ? 2 : 3 也就是当a==1 成立时,(a==1) ? 2 : 3 的值是2,即b 赋2;否 则(a==1) ? 2 : 3 的值是3,b 赋值3. b=a==1?2:3

  1. cout << status == 1 ? "已阅读" : "未读";

icode大师赛中第18题:

复习并总结 C++ - 图24

  1. for i in range(8):
  2. obj = Dev if i < 4 else Spaceship
  3. obj . step(8-i)
  4. obj . turnRight()

7,26总结

  • if 语句、if-else 语句

    • 如果给定的表达式为真,那么执行指定语句
    • 否则(else)执行另外的语句
  • switch-case 分支语句

    • 判断某个表达式的值在几个常量的值
    • 每个分支要加break 退出,default 其余情况
  • 条件语句嵌套

    • 可以多个else 多个分支,或者分支中还有分支
    • 注意复杂的分支语句,以及大括号的用法
  • 缩进、逗号表达式、注释、问号表达式

    • 让编程更容易的一些窍门
  • 关系表达式

    • 真(1)假(0)
    • 大于小于等于不等于,注意优先级
  • 逻辑表达式

    • 与(&&):同时为真则为真
    • 或(||):至少有一个为真则为真
    • 异或(^):刚好有一个为真则为真
    • 非(!):颠倒黑白
  • 浮点数精度误差、短路判断

数组

定义:

  1. int a[5]; // 定义变量a,长度为5

// 定义了变量名为a,长度为5

  1. a[0] = 1;
  2. a[1] = 2;
  3. ……
  4. a[4] = 5;
  5. //下标越界
  6. a[5] = 0;
  1. //获取数组内容
  2. cout << a[1] << endl;
  3. cout << a[2] << endl;
  4. cout << a;// 输出数组a的指针(内存地址)
  5. cout << *a;
  6. scanf("%d",&b)

一维数组

数组元素查找

例子

给出 n 个(不超过 100 个)正整数,请输出 x 第一次出现的位置。 复习并总结 C++ - 图25

数组元素查找

例子 给出 n 个(不超过 100 个)正整数,请输出 x 第一次出现的位置。 复习并总结 C++ - 图26

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int n ;
  5. cin >> n;
  6. int a[101] ;
  7. // int a[100] = {12, 23, 44, 8, 36, 3, 1};
  8. for(int i = 1;i <= n;i++){
  9. cin >> a[i];
  10. }
  11. int x;
  12. cin >> x;
  13. for (int i = 1; i <= n; i++) {
  14. if (a[i] == x) {
  15. cout << i ;
  16. break;
  17. }
  18. }
  19. }

小鱼比可爱 (p1428)

复习并总结 C++ - 图27

题意理解与转换:

有n个同学,不超过100个站成一排,大家都向前,每个同学身高为整数。 请计算,每位同学前面有几个同学比自己矮.

  1. #include <iostream>
  2. using namespace std;
  3. int main(){
  4. int a[101],n;
  5. cin >> n;
  6. // 存储小鱼的可爱值
  7. for(int i = 0; i < n; i++){
  8. cin >> a[i];
  9. }
  10. for(int i = 0; i < n ; i++){
  11. int cnt = 0;
  12. for(int j = i -1; j > 0; j--){
  13. if(a[j] < a [i]){
  14. cnt ++;
  15. }
  16. }
  17. cout << cnt << " ";
  18. }
  19. // for(int i = 0; i < n ; i++){
  20. // // 开始计数
  21. // int cnt = 0;
  22. // for(int j = 0 ; j < i -1; j ++){
  23. // if(a[j] < a[i]){
  24. // cnt ++;
  25. // }
  26. // }
  27. // cout << cnt << " ";
  28. // }
  29. }

数组的定义与操作

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int a[5];
  5. // a[0] = 1;
  6. // a[1] = 2;
  7. // a[2] = 3;
  8. // a[3] = 4;
  9. // a[4] = 5;
  10. // 在c语言中,& 符表示 :取地址; * 符表示:取值
  11. cout << "数组a的值??: " << *a << endl;
  12. cout << "数组a的地址: " << a << endl;
  13. // cout a 表示输出数组a所在内存地址,其值为数组第一项的值
  14. // cout *a 表示输出当前地址(数组a的地址)所存储的值。
  15. cout << "数组a0的地址:" << &a[0] << endl;
  16. cout << "数组a1的地址:" << &a[1] << endl;
  17. cout << "数组a2的地址:" << &a[2] << endl;
  18. // 声明时初始化
  19. int b = 0;
  20. int c[5] = {1, 2, 3, 4, 5};
  21. cout << "数组c的内容:" << c[0] << c[1] << c[2] << c[3] << c[4] << endl;
  22. for(int i =0;i < 5 ; i++){
  23. cout << c[i];
  24. }
  25. cout << endl << "---------" << endl;
  26. // 只初始一部分内容
  27. int d[9] = {1,2,3,4,5};
  28. for(int i = 0 ; i < 9 ; i++){
  29. cout << d[i] ;
  30. }
  31. cout << endl << "---------" << endl;
  32. char s[7] = {'a','b','c','d','e','f'};
  33. cout << s << endl;
  34. }

小鱼的数字游戏

复习并总结 C++ - 图28

自己维护计数器N,统计cin录入个数。

  1. #include <iostream>
  2. using namespace std;
  3. int main(){
  4. int a[110] ;
  5. int tmp,n =0;
  6. do{
  7. cin >> tmp;
  8. a[n++] = tmp;
  9. }while(tmp != 0);
  10. for(int i = n-1; i >= 1;i--){
  11. cout << a[i] << " ";
  12. }
  13. }

方法二:

  1. #include <iostream>
  2. using namespace std;
  3. int main(){
  4. int a[110] ;
  5. int tmp,n =0;
  6. do{
  7. cin >> tmp;
  8. a[n++] = tmp;
  9. }while(tmp != 0);
  10. while(n--){
  11. cout << a[n] << " ";
  12. }
  13. }

冰雹猜想

复习并总结 C++ - 图29

  1. #include <iostream>
  2. using namespace std;
  3. int main() {
  4. int n, a[200];
  5. int i = 1;
  6. cin >> n;
  7. a[0] = n;
  8. while (n != 1) {
  9. if (n % 2 == 0) {
  10. n = n / 2;
  11. } else {
  12. n = 3 * n + 1;
  13. }
  14. a[i++] = n;
  15. // cout << n << " ";
  16. }
  17. while (i--) {
  18. cout << a[i] << " ";
  19. }
  20. }

数组长度:

可以使用函数sizeof()来得到数组对应的长度。

使用memset()来进行数组统一初始化,这比用for循环要更简洁。

  1. #include <cstring>
  2. int a[10000] = {0};// 推荐,初始化时初始化
  3. memset(a,0,sizeof(a));
  4. for(int i = 0; i < sizeof(a); i++){
  5. a[i] = 0;
  6. }

数组如果不初始化就可能存有其他数值,因此我们在使用前必须 初始化,可以使用 for 循环依次赋初值,也可以在定义时直接初 始化。