C++语法基础课 && Week1

[toc]

Week1 变量、表达式与顺序语句



1. AcWing 604. 圆的面积

【简单】顺序结构

一、题目描述

计算圆的面积的公式定义为 A=πR^2。
请利用这个公式计算所给圆的面积。
π 的取值为 3.14159。

输入格式
输入包含一个浮点数,为圆的半径 R。

输出格式
输出格式为 A=X,其中 X 为圆的面积,用浮点数表示,保留四位小数。

数据范围
0<R<10000.00

输入样例:

2.00

输出样例:

A=12.5664

二、代码示例

第一种

传统的 C 写法,不过在 C++ 中该怎么写?

#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
double R;

scanf("%lf", &R);
printf("A=%.4lf\n", 3.14159*R*R);

return 0;
}

第二种

在 C++ 中使用 fixed<<setprecision( ) 来控制小数位,需要引入头文件 <iomanip>
用法:

cout << fixed() << setprecision( 保留的位数 ) << 变量 << endl;
/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-06 20:30:36
**/
#include<iostream>
#include<iomanip> //运用fixed<<setprecision()
#define PI 3.14159

using namespace std;

int main()
{
double R, A;
cin>>R;
A = PI * R * R;
cout<<"A="<<fixed<<setprecision(4)<<A<<endl;
/*
需要运用头文件<iomanip>
“fixed<<setprecision(4)”,括号中的数字表示为输出保留小数点后几位,
具体格式为:cout<<fixed<<setprecision(保留位数)<<变量<<endl;
*/
return 0;
}


2. AcWing 605. 简单乘积

【简单】顺序结构

一、题目描述

读取两个整数值。
在此之后,计算它们的乘积并将结果存储在名为 PROD 的变量中。
输出结果如下例所示。

输入格式
共两行,每行包含一个整数。

输出格式
输出格式为 PROD = X,其中 X 为乘积结果。

数据范围
输入的两个整数的绝对值均不超过 10000。

输入样例:

3
9

输出样例:

PROD = 27

二、代码示例

简单题,没什么好说的。

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-06 20:31:10
**/
#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
int a, b, PROD;

cin >> a >> b;
PROD = a*b;
cout << "PROD = " << PROD << endl;

return 0;
}


3. AcWing 606. 平均数1

【简单】顺序结构

一、题目描述

读取两个浮点数 A 和 B 的值,对应于两个学生的成绩。
请你计算学生的平均分,其中 A 的成绩的权重为 3.5,B 的成绩的权重为 7.5。
成绩的取值范围在 0 到 10 之间,且均保留一位小数。

输入格式
输入占两行,每行包含一个浮点数,第一行表示 A,第二行表示 B。

输出格式
输出格式为 MEDIA = X,其中 X 为平均分,结果保留五位小数。

数据范围
0≤A,B≤10.0

输入样例:

5.0
7.1

输出样例:

MEDIA = 6.43182

二、代码示例

唯一需要注意的是权重的计算方法······
权重的计算:(A*3.5 + B*7.5) / (3.5 + 7.5)

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-06 20:36:51
**/
#include <iostream>
#include <iomanip>
using namespace std;

int main(void)
{
double A, B, MEDIA = 0;

cin >> A >> B;
MEDIA = (A*3.5 + B*7.5) / 11;
cout << "MEDIA = " << fixed << setprecision(5) << MEDIA;
// 权重的计算:(A*3.5 + B*7.5) / (3.5 + 7.5)

return 0;
}


4. AcWing 607. 平均数2

【简单】顺序结构

一、题目描述

读取三个浮点数 A,B 和 C 的值,对应于三个学生的成绩。
请你计算学生的平均分,其中 A 的成绩的权重为 2,B 的成绩的权重为 3,C 的成绩的权值为 5。
成绩的取值范围在 0 到 10 之间,且均保留一位小数。

输入格式
输入共三行,每行包含一个浮点数,第一行表示 A,第二行表示 B,第三行表示 C。

输出格式
输出格式为 MEDIA = X,其中 X 为平均分,结果保留一位小数。

数据范围
0≤A,B,C≤10.0,

输入样例:

5.0
6.0
7.0

输出样例:

MEDIA = 6.3

二、代码示例

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-06 20:48:53
**/
#include <iostream>
#include <iomanip>
using namespace std;

int main(void)
{
double A, B, C, MEDIA;

cin >> A >> B >> C;
MEDIA = ( A*2 + B*3 + C*5 ) / 10;
cout << "MEDIA = " << fixed << setprecision(1) << MEDIA << endl;

return 0;
}


5. AcWing 608. 差

【简单】顺序结构

一、题目描述

读取四个整数 A,B,C,D,并计算 (A×B−C×D) 的值。

输入格式
输入共四行,第一行包含整数 A,第二行包含整数 B,第三行包含整数 C,第四行包含整数 D。

输出格式
输出格式为 DIFERENCA = X,其中 X 为 (A×B−C×D) 的结果。

数据范围
−10000≤A,B,C,D≤10000

输入样例:

5
6
7
8

输出样例:

DIFERENCA = -26

二、代码示例

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-06 20:54:04
**/
#include <iostream>
using namespace std;

int main(void)
{
int A, B, C, D, DIFERENCA = 0;
cin >> A >> B >> C >> D;
DIFERENCA = ( A*B - C*D );
cout << "DIFERENCA = " << DIFERENCA << endl;

return 0;
}


6. AcWing 609. 工资

【简单】顺序结构

一、题目描述

请编写一个程序,可以读取一名员工的员工编号,本月工作总时长(小时)以及时薪,并输出他的工资条,工资条中包括员工编号和员工月收入。

输入格式
输入包含两个整数和一个浮点数,分别代表员工编号,工作时长以及时薪。
每个数占一行。

输出格式
输出共两行,第一行格式为 NUMBER = X,其中 X 为员工编号。
第二行格式为 SALARY = U$ Y,其中 Y 为该员工月收入,保留两位小数。

数据范围
1≤员工编号≤100,
1≤总工作时长≤200,
1≤时薪≤50

输入样例:

25
100
5.50

输出样例:

NUMBER = 25
SALARY = U$ 550.00

二、代码示例

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-06 20:59:13
**/
#include <iostream>
#include <iomanip>
using namespace std;

int main(void)
{
int NUMBER, HOUR;
double SALARY;

cin >> NUMBER >> HOUR >> SALARY;
SALARY = HOUR*SALARY;
cout << "NUMBER = " << NUMBER << endl;
cout << "SALARY = U$ " << fixed << setprecision(2) << SALARY << endl;

return 0;
}


7. AcWing 610. 工资和奖金

【简单】顺序结构

一、题目描述

请你编写一个程序,给定你一个销售人员的名字,底薪以及月销售额。
请你计算他的月收入是多少。
已知月收入等于底薪加 15% 的月销售额。
所有数据保留两位小数。

输入格式
输入第一行包含一个由大写字母构成的长度不超过 10 的字符串,表示销售人员的名字。
第二行包含一个浮点数,表示该人员的底薪。
第三行包含一个浮点数,表示该人员的月销售额。

输出格式
输出格式为 TOTAL = R$ X,X 为该人员月收入。

数据范围
0≤底薪,月销售额≤10000.00

输入样例:

JOAO
500.00
1000.00

输出样例:

TOTAL = R$ 650.00

二、错误代码

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-06 21:03:52
**/
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

int main(void)
{
string NAME[10];
double a, b, TOTAL = 0;
cin >> NAME[10] >> a >> b;

TOTAL = a + b*0.15;
cout << "TOTAL = R$ " << fixed << setprecision(2) << TOTAL << endl;

return 0;
}

错误提示:

Segmentation Fault   

在第9行,使用 cin 读取了 NAME[10],但是数组只有 10 个元素,从 0 到 9,所以应该用 NAME[9] 而不是 NAME[10]。

另外,在输入a和b之前,没有检查是否成功读取到了字符串,如果用户没有输入任何内容就直接按回车键,可能会导致 cin 流进入异常状态,需要使用 cin.clear() 和 cin.ignore() 来清除错误状态并跳过当前行的剩余字符。

三、代码示例

(1)在 错误代码 的基础上修改

虽然 Accepted 了,但是这种写法也是错的!!!,详情见总结。

#include <iostream>
#include <iomanip>
using namespace std;

int main(void)
{
string NAME[10];
double a, b, TOTAL = 0;

cin >> NAME[9]; // 修改为NAME[9]
if (!cin) { // 检查是否成功读取到字符串
cout << "Error: failed to read name." << endl;
return 1;
}
cin >> a >> b;
if (!cin) {
cout << "Error: failed to read values for a and b." << endl;
return 1;
}
TOTAL = a + b*0.15;
cout << "TOTAL = R$ " << fixed << setprecision(2) << TOTAL << endl;

return 0;
}

Segmentation fault(段错误)通常是因为 程序试图访问不属于自己的内存区域,或者试图执行非法操作导致的。 C++中,可能的原因包括但不限于:

  • 访问数组越界
  • 使用未初始化的指针
  • 动态分配内存失败

这样可以避免出现Segmentation Fault的问题,并且增加了对输入错误的处理。

(2)把 [10] 给去掉

#include <iostream>
#include <iomanip>

using namespace std;

int main(void)
{
string NAME;
double a, b, TOTAL = 0;
cin >> NAME >> a >> b; // cin 输入字符串方便

TOTAL = a + b*0.15;
cout << "TOTAL = R$ " << fixed << setprecision(2) << TOTAL << endl;

return 0;
}

(3)使用字符数组 char a[10]

#include <cstdio>

using namespace std;

int main()
{
char a[10];
double b, c;

scanf("%s %lf %lf", a, &b, &c);
printf("TOTAL = R$ %.2lf", b + c * 0.15);
return 0;
}

四、总结

(1)关于使用 NAME[10] 会Segmentation fault(段错误)

string NAME[10];
double a, b, TOTAL = 0;
cin >> NAME[10] >> a >> b;

先来复习一下段错误:

Segmentation fault(段错误)通常是因为 程序试图访问不属于自己的内存区域,或者试图执行非法操作导致的。 C++中,可能的原因包括但不限于:

  • 访问数组越界
  • 使用未初始化的指针
  • 动态分配内存失败

string NAME[10]; 声明了一个包含 10 个字符串的数组,而 cin >> NAME[10] >> a >> b; 尝试读取输入到 NAME[10],这是数组的第11个元素(在C++中,数组是从零开始索引的),这是错误的!

(2)关于第一种修改也是错误的原因

string NAME[10];
double a, b, TOTAL = 0;
cin >> NAME[9] >> a >> b;

1. 关于 Accepted 的原因

string NAME[10] 声明了一个包含 10 个字符串的的数组(不是字符数组),每一个都可以存储字符串;而cin >> NAME[9] 是把输入的字符串存到数组的第 10 个元素中,即 NAME[9] —— 是有效的。

2. 关于这种写法为什么是错的原因

这种做法可能会导致代码的可读性降低,因为此题中 NAME 是一个单一的字符串而不是一个字符串数组。通常情况下,如果只需要一个字符串,直接声明一个 string 类型的变量会更清晰。

(3)C++中 string 的一些用法

  1. 在C++中,使用 string 类型时,不需要指定大小——因为 string 类会根据实际存储的字符动态调整大小。这是 string 类的一个优势,因为它能够自动处理字符串的大小变化,无需手动管理内存。
  2. 当在C++中声明 string name[10]; 时,声明的是一个包含 10 个 string 对象的数组,而不是字符数组。数组中的每个元素(name[0]name[9])都是一个独立的 string 对象,可以容纳一系列字符。
  3. 在C++中,string 是标准库提供的一个类,表示一系列字符,与传统的字符数组不同。string 类提供了更多的功能,通常比传统的字符数组更方便和安全。
    因此,通常的做法是直接声明一个 string 变量,而不是一个固定大小的字符串数组。

(4)C++中关于数组和单一变量的声明的区别

  1. string name[10];
string name[10];  // 定义一个包含10个字符串的数组
  • 这是一个包含 10 个字符串的数组的声明。数组的每个元素都可以存储一个独立的字符串。
  • 数组的索引是从0到9,因此有效的访问范围是 name[0] 到 name[9]。
  • 适用于需要存储多个字符串的情况,每个字符串对应一个数组元素。
  1. string name;
string name;  // 定义一个单一字符串变量
  • 一个单一的字符串变量的声明。只能存储一个字符串。
  • 适用于只需要存储一个字符串的情况。
  • 相同点:

两者都是用来存储字符串的。
在编写代码时,可以使用相似的语法来操作,例如使用 cin 读取输入,或者使用 cout 打印输出。

  • 区别:

string name[10]; 是一个包含多个字符串的数组,每个元素都是一个独立的字符串。
string name; 是一个单一的字符串变量,只能存储一个字符串。

根据需求,选择数组或者单一变量取决于是需要处理多个字符串还是单一字符串。

(5)常用头文件

头文件:

  • #include <iostream> 包括cin / cout / scanf / printf
  • #inlcude <cstdio> 包括scanf / printf
    其中,cstdio编译速度比iostream快
  • #include <cmath> 包括常用数学公式,如
    • double sqrt(double x);
    • double pow(double x, double y);
    • long int abs(long int x);
    • double fabs(double x);
  • 万能头文件 #include <bits/stdc++.h>


8. AcWing 611. 简单计算

【简单】顺序结构

一、题目描述

给定你两个产品的产品编号,产品数量以及产品单价。
请你计算买下两种产品一共需要花费多少钱。

输入格式
输入共两行。
每行包含两个整数以及一个浮点数,表示其中一件产品的产品编号,产品数量以及产品单价。

输出格式
输出格式为 VALOR A PAGAR: R$ X,其中 X 为产品总价值,保留两位小数。

数据范围
1≤产品编号,产品数量≤10000,
1.00≤产品单价≤10000.00

输入样例:

12 1 5.30
16 2 5.10

输出样例:

VALOR A PAGAR: R$ 15.50

二、代码示例

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-07 13:41:15
**/
# include <iostream>
using namespace std;

int main(void)
{
int a1, b1, a2, b2;
double c1, c2;

cin >> a1 >> b1 >> c1;
cin >> a2 >> b2 >> c2;

double sum = b1*c1 + b2*c2;
printf("VALOR A PAGAR: R$ %.2lf\n", sum);

return 0;
}


9. AcWing 612. 球的体积

【简单】顺序结构

一、题目描述

给定你一个球体的半径 R,请你计算球体的体积。
计算球体的公式为 V=(4/3)∗π∗R^3。
π 取 3.14159。

注意:有些语言中 (4/3) 无法得到 1.3333…,建议在公式中使用 (4/3.0)。

输入格式
输入一个整数 R。

输出格式
输出格式为 VOLUME = X,其中 X 为球体的体积,结果保留三位小数。

数据范围
1≤R≤2000

输入样例:

3

输出样例:

VOLUME = 113.097

二、代码示例

需要注意一点:(4 / 3) 得不到1.333333···,要使用 (4 / 3.0)

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-07 13:48:30
**/

#include <iostream>
#define PI 3.14159
using namespace std;

int main(void)
{
int r;
cin >> r;

double v = 4 / 3.0 * PI * r * r * r;
printf("VOLUME = %.3lf\n", v);

return 0;
}


10. AcWing 613. 面积

【简单】顺序结构

一、题目描述

给定三个浮点数 A,B 和 C。
然后,计算如下图形的面积:

底边为 A,高为 C 的三角形。
半径 C 的圆。(π=3.14159)
底边为 A 和 B,高为 C 的梯形。
边长为 B 的正方形。
边长为 A 和 B 的长方形。

输入格式
输入共一行,包含三个保留一位小数的浮点数 A,B,C。

输出格式
输出共五行,形式如下所示:

第一行,格式为 TRIANGULO: X,其中 X 为所求三角形面积。
第二行,格式为 CIRCULO: X,其中 X 为所求圆形面积。
第三行,格式为 TRAPEZIO: X,其中 X 为所求梯形面积。
第四行,格式为 QUADRADO: X,其中 X 为所求正方形面积。
第五行,格式为 RETANGULO: X,其中 X 为所求长方形面积。

所有答案保留三位小数。

数据范围:

0≤A,B,C≤10000.0

输入样例:

3.0 4.0 5.2

输出样例:

TRIANGULO: 7.800
CIRCULO: 84.949
TRAPEZIO: 18.200
QUADRADO: 16.000
RETANGULO: 12.000

二、代码示例

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-09 20:57:32
**/
#include <iostream>
#define PI 3.14159
using namespace std;

int main(void)
{
double a, b, c;

cin >> a >> b >> c;

double ans1 = a * c *0.5;
double ans2 = PI * c * c;
double ans3 = (a + b) * c * 0.5;
double ans4 = b * b;
double ans5 = a *b;

printf("TRIANGULO: %.3lf\n", ans1);
printf("CIRCULO: %.3lf\n", ans2);
printf("TRAPEZIO: %.3lf\n", ans3);
printf("QUADRADO: %.3lf\n", ans4);
printf("RETANGULO: %.3lf\n", ans5);

return 0;
}


11. AcWing 614. 最大值

【中等】顺序结构

一、题目描述

给定三个整数,请你找出它们中的最大值。
下列公式可能对你有所帮助:
max(a,b) = ( a + b + abs( a − b ) ) / 2

输入格式
输入占一行,包含三个整数。

输出格式
输出格式为 X eh o maior,其中 X 为三个数中的最大值。

数据范围
1≤给定整数≤109

输入样例:

7 14 106

输出样例:

106 eh o maior

二、代码示例

求两个数的最大值:max(a,b)=(a+b+abs(a−b))/2

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-09 21:09:45
**/

// max(a,b)=(a+b+abs(a−b))/2

#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
int a, b, c;

cin >> a >> b >> c;
int max = (a + b + abs(a - b)) / 2;
max = (max + c + abs(max - c)) / 2;
cout << max << " eh o maior" <<endl;

return 0;
}


12. AcWing 615. 油耗

【简单】顺序结构

一、题目描述

给定一个汽车行驶的总路程(km)和消耗的油量(l),请你求出汽车每消耗 1 升汽油可行驶多少公里路程。

输入格式
输入共两行,第一行包含整数 X,表示行驶总路程。
第二行包含保留一位小数的浮点数 Y,表示消耗的油量。

输出格式
输出格式为 M km/l,其中 M 为计算结果,保留三位小数。

数据范围
1≤X,Y≤109

输入样例:

500
35.0

输出样例:

14.286 km/l

二、代码示例

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-09 21:15:11
**/
#include <iostream>
using namespace std;

int main(void)
{
int x;
double y;

cin >> x >> y;
double m = x / y;
printf("%.3lf km/l\n", m);

return 0;
}


13. AcWing 616. 两点间的距离

【简单】顺序结构

一、题目描述

给定两个点 P1 和 P2,其中 P1 的坐标为 (x1,y1),P2 的坐标为 (x2,y2),请你计算两点间的距离是多少。
100

输入格式
输入共两行,每行包含两个双精度浮点数 xi,yi,表示其中一个点的坐标。
输入数值均保留一位小数。

输出格式
输出你的结果,保留四位小数。

数据范围
−109≤xi,yi≤109

输入样例:

1.0 7.0
5.0 9.0

输出样例:

4.4721

二、代码示例

/**
* @brief:
* @version:
* @author: @Shiel
* @date: 2023-12-09 21:18:06
**/
#include <iostream>
#include <cmath>
using namespace std;

int main(void)
{
double x1, y1, x2, y2;

cin >> x1 >> y1 >> x2 >> y2;
double d = sqrt( ( (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) ) );
printf("%.4lf\n", d);

return 0;
}


14. 617. 距离

【中等】顺序结构

一、题目描述

两辆汽车在同一地点,同时,沿同一方向前进。
一辆车的速度为 60 km/h,另一辆车的速度为 90 km/h。
显然,快车与慢车的距离会不断拉开,每过一个小时(60 分钟),两车的距离就拉开 30 公里。
现在,告诉你两车之间的距离为 L 公里,请你求出两车已经行驶了多长时间?

输入格式
输入包含一个整数 L,表示两车之间的距离。

输出格式
输出格式为 X minutos,其中 X 为已经行驶的时间,单位为分钟。

数据范围
1≤L≤109

输入样例:

30

输出样例:

60 minutos

二、错误代码

题目并没有直接说 x 的变量类型

(1)int x = (l / 30) * 60;

下面这种和第(2)种一样,因为向下取整 + 整个表达式 都是整数,所以int 和 double 一样

#include <iostream>
using namespace std;

int main(void)
{
int l;

cin >> l;
int x = (l / 30) * 60;
cout << x << " minutos" << endl;

return 0;
}

代码提交状态: Wrong Answer
代码运行状态: 错误数据如下所示

输入

489

输出

960 minutos

标准答案

978 minutos

运行时间:2ms

(2)double x = (l / 30) * 60;

同第(1)种错误

代码提交状态: Wrong Answer
代码运行状态: 错误数据如下所示

输入

489

输出

960 minutos

标准答案

978 minutos

运行时间:2ms

(3)double x = (l / 30.0) * 60;

可以看出,题目输出是整数,即没有小数,所以小数位设置为 0 即可。

代码提交状态: Wrong Answer
代码运行状态: 错误数据如下所示

输入

596933032

输出

1.19387e+09 minutos

标准答案

1193866064 minutos

运行时间:2ms

三、代码示例

1. 把小数位改为0

C++ 中控制小数位还可以:

cout.setf(ios_base::fixed);
cout.precision(0);

这样子只需要改一个数字就好,不过感觉还是 printf 方便?>······

#include <iostream>
using namespace std;

int main(void)
{
int l;

cin >> l;
double x = (l / 30.0) * 60;
cout.setf(ios_base::fixed);
cout.precision(0);
cout << x << " minutos" << endl;

return 0;
}

2. 使用位运算 n << 1

位运算效率超高的~

  • 仔细观察题目数据:30 km → 60 minutes
  • 也就是说:乘2 就完事了!

所以使用位运算是比较好的一种方法。

左移运算(<<)是一种位运算,用于将一个二进制数的所有位向左移动指定的位数。在左移运算中,右侧用零填充。

对于一个二进制数 x,左移运算 x << n 表示将 x 的所有位向左移动 n 位。每一位都向左移动,而右侧用 0 填充。左移操作实际上相当于将原数乘以 2 的 n 次方。

#include <bits/stdc++.h>
using namespace std;
int n;
int main() {
scanf("%d", &n);
printf("%d minutos", n << 1);
return 0;
}

3. 直接 n / 0.5

#include<iostream>
using namespace std;
int main()
{
//快车与慢车拉开的距离 0.5公里/min
int n;

cin>>n;
cout.setf(ios_base::fixed);
cout.precision(0);
cout<<n/0.5<<" minutos";
return 0;
}

四、小结

1. 仔细观察数据

就跟数学题一样,仔细观察数据之间的关系。


2. 位运算

位运算是一种在计算机中操作二进制位的技术。它使用位(0和1)来执行各种操作,如移位、与、或、异或等。位运算通常用于处理底层的数据存储和操作,例如在嵌入式系统、图形处理、密码学等领域。

  • 常见的位运算操作:

    1. 与运算(&)
      对应位都为1时,结果为1;否则,结果为0。
      例如:1010 & 1100 = 1000

    2. 或运算(|)
      对应位有一个为1时,结果为1;否则,结果为0。
      例如:1010 | 1100 = 1110

    3. 异或运算(^)
      对应位相异时,结果为1;否则,结果为0。
      例如:1010 ^ 1100 = 0110

    4. 取反运算(~)
      对每个位取反,即0变为1,1变为0。
      例如:~1010 = 0101

    5. 左移运算(<<)
      将二进制数左移指定位数,右侧补0。
      例如:1010 << 2 = 1000

    6. 右移运算(>>)
      将二进制数右移指定位数,左侧根据符号位补0或补1。
      例如:1010 >> 2 = 0010

    • 位运算可以在某些情况下提高代码的效率,尤其是对于一些需要高性能的场景。在使用位运算时,需要了解二进制数的表示和运算规则,并谨慎处理符号位(对于有符号整数)。

    • 这些位运算符可以用于整数类型(如int、long等)的操作。要特别注意在使用右移运算符时,对于有符号整数,可能会根据实现方式产生符号位的填充,这可能导致不同的结果。因此,在使用右移运算时,要确保理解底层实现和符号位的影响。

  • 位运算的优势

  1. 效率: 位运算是在硬件层面上进行的操作,通常比算术运算更快。对于一些对性能要求较高的应用,如嵌入式系统、图形处理、密码学等领域,使用位运算可以提高代码的执行效率。

  2. 节省空间: 位运算可以用较少的位数表示信息,从而减小数据占用的空间。这在存储大量二进制数据时尤为重要。例如,使用位掩码可以将多个布尔值压缩到一个整数中,从而减少内存占用。

  3. 逻辑清晰: 在一些算法和数据结构中,使用位运算可以使代码更加简洁和直观。例如,使用位运算来检查某个数是否是2的幂次方,可以用一行代码完成,而不需要使用乘法或除法等运算。

  4. 位掩码和标志位: 位运算常用于创建位掩码(bitmask)和处理标志位(flags)。通过位掩码,可以使用一个整数来表示多个布尔状态,从而减小存储和传输开销。

  5. 加密和哈希算法: 位运算在密码学和哈希算法中经常用到,因为它们能够以比较底层的方式处理二进制数据,提供高效的加密和哈希操作。

尽管位运算在某些场景下具有优势,但在编写代码时,也要注意代码的可读性和可维护性。过度使用位运算可能会导致代码难以理解,从而降低代码的质量。因此,在选择是否使用位运算时,需要权衡代码的性能需求和代码的清晰度。