C++算法语法基础一遍过(用于算法学习)
1. C++输入与输出
在C++中,可以使用cin
和cout
来进行输入和输出。这些函数定义在头文件<iostream>
中。例如:
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
cout << "x = " << x << endl;
return 0;
}
在这个例子中,我们使用cin
从标准输入读入一个整数,并将其存储在变量x
中。然后,我们使用cout
将字符串和变量的值输出到标准输出。注意,我们使用endl
来结束一行并刷新输出缓冲区。
2. C++基础语法与数据类型
C++是一种静态类型的编程语言,需要在使用变量之前定义其数据类型。常见的基本数据类型有整型、浮点型、字符型、布尔型等。除了基本数据类型之外,还有指针类型和引用类型,用于操作内存地址。
#include <iostream>
using namespace std;
int main() {
// 声明并初始化变量
int a = 10;
float b = 3.14;
char c = 'A';
bool d = true;
// 输出变量的值
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
cout << "d = " << d << endl;
// 指针和引用
int *ptr = &a; // 指向a的指针
int &ref = a; // a的引用
cout << "ptr = " << ptr << ", *ptr = " << *ptr << endl;
cout << "ref = " << ref << endl;
return 0;
}
2.1 变量定义
在C++中,可以使用不同的方式来定义变量,如下所示:
int x; // 声明一个名为x的整型变量
double y = 3.14; // 声明一个名为y的双精度浮点型变量并初始化为3.14
char c = 'a'; // 声明一个名为c的字符型变量并初始化为字符a
bool b = true; // 声明一个名为b的布尔型变量并初始化为true
这些变量的类型分别为整型、双精度浮点型、字符型和布尔型。变量可以在声明时初始化,也可以在之后的任何时候初始化。例如:
int x; // 声明一个名为x的整型变量
x = 42; // 初始化x为42
2.2 常量定义
在C++中,可以使用const
关键字来定义常量。例如:
const int N = 100; // 声明一个名为N的整型常量并初始化为100
const double PI = 3.14159; // 声明一个名为PI的双精度浮点型常量并初始化为3.14159
常量不能在之后修改,因此它们必须在声明时初始化。
2.3 运算符
C++中的运算符与其他编程语言类似,如加、减、乘、除、取余、比较等等。例如:
int x = 2 + 3; // x的值为5
int y = 5 - 2; // y的值为3
int z = 2 * 3; // z的值为6
int w = 5 / 2; // w的值为2(整数除法)
int r = 5 % 2; // r的值为1(取余)
bool b1 = 2 < 3; // b1的值为true
bool b2 = 2 > 3; // b2的值为false
2.4 输入输出
在C++中,可以使用cin
和cout
来进行输入和输出。这些函数定义在头文件<iostream>
中。例如:
#include <iostream>
using namespace std;
int main() {
int x;
cin >> x;
cout << "x = " << x << endl;
return 0;
}
在这个例子中,我们使用cin
从标准输入读入一个整数,并将其存储在变量x
中。然后,我们使用cout
将字符串和变量的值输出到标准输出。注意,我们使用endl
来结束一行并刷新输出缓冲区。
2.5 变量定义
在C++中,可以使用不同的方式来定义变量,如下所示:
int x; // 声明一个名为x的整型变量
double y = 3.14; // 声明一个名为y的双精度浮点型变量并初始化为3.14
char c = 'a'; // 声明一个名为c的字符型变量并初始化为字符a
bool b = true; // 声明一个名为b的布尔型变量并初始化为true
这些变量的类型分别为整型、双精度浮点型、字符型和布尔型。变量可以在声明时初始化,也可以在之后的任何时候初始化。例如:
int x; // 声明一个名为x的整型变量
x = 42; // 初始化x为42
2.6 常量定义
在C++中,可以使用const
关键字来定义常量。例如:
const int N = 100; // 声明一个名为N的整型常量并初始化为100
const double PI = 3.14159; // 声明一个名为PI的双精度浮点型常量并初始化为3.14159
常量不能在之后修改,因此它们必须在声明时初始化。
2.7 运算符
C++中的运算符与其他编程语言类似,如加、减、乘、除、取余、比较等等。例如:
int x = 2 + 3; // x的值为5
int y = 5 - 2; // y的值为3
int z = 2 * 3; // z的值为6
int w = 5 / 2; // w的值为2(整数除法)
int r = 5 % 2; // r的值为1(取余)
bool b1 = 2 < 3; // b1的值为true
bool b2 = 2 > 3; // b2的值为false
2.8 控制流语句
C++中的控制流语句与其他编程语言类似,如条件语句、循环语句等等。例如:
2.8.1 循环语句
C++中有三种循环语句:for
、while
和do-while
// for循环
for (int i = 0; i < n; i++) {
// 循环体
}
// while循环
while (condition) {
// 循环体
}
// do-while循环
do {
// 循环体
} while (condition);
#include <iostream>
using namespace std;
int main(){
// for循环
for (int i = 0; i < 10; i++) {
cout << i << endl;
}
// while循环
int i = 0;
while (i <= 10){
cout << i << endl;
i ++;
}
int i1 = 0;
// do-while循环
do {
// 循环体
cout << i << endl;
i1 ++;
} while (i <= 10);
}
2.8.2 条件控制语句
2.8.2.1 if语句
if语句可以根据条件的真假执行不同的语句。if语句的一般形式如下:
if (condition) {
// 如果条件为真,则执行这里的语句
}
其中,condition
是一个返回值为bool
类型的表达式,当该表达式的值为true
时,if语句中的代码块将被执行。下面是一个示例代码:
#include <iostream>
using namespace std;
int main() {
int x = 5;
if (x > 0) {
cout << "x is positive" << endl;
}
}
2.8.2.2 if-else语句
if-else语句可以在条件为真时执行一组语句,在条件为假时执行另一组语句。if-else语句的一般形式如下:
if (condition) {
// 如果条件为真,则执行这里的语句
} else {
// 如果条件为假,则执行这里的语句
}
#include <iostream>
using namespace std;
int main() {
int x = 5;
if (x > 0) {
cout << "x is positive" << endl;
} else {
cout << "x is non-positive" << endl;
}
}
2.8.2.3 switch语句
switch语句可以根据一个变量的值执行不同的语句。switch语句的一般形式如下:
switch (expression) {
case constant1:
// 如果expression等于constant1,则执行这里的语句
break;
case constant2:
// 如果expression等于constant2,则执行这里的语句
break;
// ...
default:
// 如果expression不等于任何一个常量,则执行这里的语句
break;
}
其中,expression
是一个可以计算出整数值的表达式,常量必须是整数常量,每个case语句结束时要加上break
语句以避免执行其他的case语句。下面是一个示例代码:
#include <iostream>
using namespace std;
int main() {
int day = 1;
switch (day) {
case 1:
cout << "Monday" << endl;
break;
case 2:
cout << "Tuesday" << endl;
break;
// ...
default:
cout << "Invalid day" << endl;
break;
}
}
3. C++的指针和引用
3.1 指针
指针是一个变量,其值为另一个变量的地址,即指向该变量所在的内存地址。通过指针可以直接访问该地址中存储的值。在C++中,可以使用&
符号获取变量的地址,使用*
符号定义指针,使用new
和delete
来动态地分配和释放内存空间。
#include <iostream>
using namespace std;
int main() {
// 指针的基本语法
int var = 10; // 定义一个整形的变量
int *ptr; // 定义一个指向整形变量的指针
ptr = &var; // 获取变量var的地址并将其赋值给指针ptr
cout << "var 的值为 " << var << endl;
cout << "ptr 指向的值为 " << *ptr << endl;
cout << "ptr 储存的内存地址为 " << ptr << endl;
return 0;
}
3.1.1 动态分配内存
在C++中,动态内存分配是通过使用 new
和 delete
运算符实现的。使用 new
运算符可以分配一段动态内存,而 delete
运算符可以释放已经分配的内存。
下面是一个简单的示例程序,演示了如何使用 new
和 delete
运算符来分配和释放动态内存:
// 动态分配内存
# include <iostream>
using namespace std;
int main() {
int size;
cout << "输入数组的大小:";
cin >> size;
// 分配一个大小为 size 的 int 类型数组
int *arr = new int[size];
// 对数组进行赋值操作
for (int i = 0; i < size; i++) {
arr[i] = i;
}
// 输出数组中的元素
for(int i = 0; i < size; i++) {
arr[i] = i;
}
cout << endl;
// 释放已分配的内存
delete[] arr;
return 0;
}
在这个示例程序中,用户输入了一个数组的大小,然后使用 new
运算符分配了一个大小为 size
的 int
数组。接着,程序对数组进行了赋值,并输出了数组中的元素。最后,使用 delete
运算符释放了已经分配的内存。
需要注意的是,在使用 new
运算符分配内存时,如果分配失败,它会抛出一个 std::bad_alloc
异常。因此,在实际应用中,需要在程序中使用异常处理机制来处理这种异常。同时,还需要注意使用 delete
运算符释放内存时,需要使用 delete[]
运算符来释放动态数组。
3.2 引用
引用是变量的别名,通过引用可以使用原始变量的名称来访问其值,因此引用可以看作是指向变量的指针的另一种表达方式。在C++中,使用&
符号定义引用。
#include <iostream>
using namespace std;
// 引用作为函数参数
void swap(int &a, int &b) {
// 定义一个交换函数,参数为两个整数的引用
int temp = a;
a = b;
b = temp;
}
int main() {
// 引用的基本语法
int var = 10; // 定义一个整形变量
int &ref = var; // 定义一个引用,ref是var的别名
cout << "var的值为 " << var << endl;
cout << "ref的值为 " << ref << endl; // 输出引用ref所绑定变量的值
// 修改引用所绑定的变量的值
ref = 20;
cout << "var 的值为 " << var << endl;
cout << "ref 的值为 " << ref << endl;
int a = 10, b = 20;
swap(a, b);
cout << "a 的值为 " << a << endl; // 输出 20
cout << "b 的值为 " << b << endl; // 输出 10
}
需要注意的是,指针和引用虽然可以用于修改原始变量的值,但是它们的使用也有一些限制和注意事项。例如,指针需要确保指向的内存地址是有效的,避免出现空指针和野指针等问题;引用在绑定时必须要初始化,否则会产生编译错误;还需要注意引用的作用
4. C++的数组,字符串和向量
数组是一组具有相同数据类型的变量的集合,可以使用下标访问每个元素。字符串是字符数组,可以使用字符串函数处理。向量是可以动态增长的数组,可以使用迭代器访问元素。
#include <iostream>
#include <string>
using namespace std;
int main() {
// 数组
int arr[3] = {1, 2, 3};
cout << "arr[0] = " << arr[0] << endl;
// 字符串
string str = "hello";
cout << "str.length() = " << str.length() << endl;
cout << "str[0] = " << str[0] << endl;
return 0;
}
4.1 向量详解
在 C++ 中,向量是一种动态数组,也被称为动态数组或可变大小数组。向量可以自动调整大小,可以根据需要在运行时添加或删除元素。向量是在标准模板库(STL)中定义的,需要包含头文件<vector>
才能使用。
定义向量的语法如下:
vector<数据类型> 变量名;
例如,定义一个整数向量:
vector<int> myVector;
向量有许多常用的方法,以下是一些常见的方法:
push_back(value)
:在向量的末尾添加一个值。pop_back()
:删除向量的末尾值。size()
:返回向量的大小。empty()
:检查向量是否为空。clear()
:清空向量中的所有值。at(index)
:返回向量中指定索引处的值。front()
:返回向量的第一个值。back()
:返回向量的最后一个值。insert(iterator, value)
:在指定位置插入一个值。erase(iterator)
:从向量中删除指定位置的值。
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 创建一个整数向量
vector<int> myVector;
// 在向量中添加元素
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
// 遍历向量并输出每个元素的值
for (int i = 0; i < myVector.size(); i++) {
cout << myVector[i] << " ";
}
// 输出向量的大小和第一个元素的值
cout << "\nSize of myVactor: " << myVector.size() << endl;
cout << "First element of myVactor: " << myVector.front() << endl;
// 删除向量的最后一个元素
myVector.pop_back();
// 输出修改后的向量
for (int i = 0; i < myVector.size(); i++) {
cout << myVector[i] << " ";
}
// 清空向量
myVector.clear();
// 输出清空后的向量大小
cout << "\nSize of myVector after clearing: " << myVector.size() << endl;
return 0;
}
在此示例程序中,我们使用了push_back()
方法向向量中添加元素,使用了size()
方法获取向量的大小,使用了front()
方法获取向量的第一个元素,使用了pop_back()
方法删除向量的最后一个元素,并使用了clear()
方法清空向量中的所有元素。
5. 函数的定义与使用
函数是一种将任务分解为可重用代码块的方法,它接受一些输入(称为参数),并根据这些输入执行一些操作,最后返回一些输出(称为返回值)。C++中函数的定义和使用非常简单,以下是一个基本的函数定义示例:
#include <iostream>
using namespace std;
// 定义一个函数,参数为两个整数,返回值为整数
int add(int a, int b) {
return a + b;
}
int main() {
int sum = add(2, 3);
cout << sum << endl;
return 0;
}
在上面的示例中,add
函数接受两个整数作为参数,并返回它们的和。在主函数中,我们调用add
函数,并将结果赋值给一个名为sum
的整数变量。
函数的参数和返回值可以是任何数据类型,也可以没有参数或返回值。以下是一些示例:
#include <iostream>
using namespace std;
// 函数没有参数和返回值
void sayHello() {
cout << "Hello, world" << endl;
}
// 函数接受一个字符串参数并返回一个整数
int countChars(string str) {
return str.length();
}
// 函数接受两个指针参数,没有返回值
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
// 函数接受一个整数参数,并返回一个指向整数数组的指针
int* createArray(int size) {
int* arr = new int[size];
for (int i = 0; i < size; i++){
arr[i] = i;
}
return arr;
}
在C++中,函数也可以重载,即定义具有相同名称但参数类型或数量不同的多个函数。以下是一个重载函数的示例:
// 函数接受两个整数参数并返回它们的和
int add(int a, int b){
return a + b;
}
// 函数接受两个浮点数参数并返回它们的和
float add(float a, float b) {
return a + b;
}
在调用重载函数时,编译器会根据提供的参数类型和数量来选择正确的函数。
总之,C++中函数是一种非常有用的工具,它可以帮助我们组织代码并将任务分解为可重用的代码块。函数可以接受任何数据类型的参数并返回任何数据类型的值,还可以重载以支持不同的参数类型和数量。
5.1 函数参数传递问题
在C++中,函数参数可以通过值传递或引用传递两种方式进行传递。使用值传递时,函数将创建参数的副本并使用该副本。这意味着,在函数内部对参数进行的任何更改都不会影响原始变量。而使用引用传递时,函数将使用原始变量本身,而不是其副本。
使用引用传递有以下几个好处:
- 可以节省内存,因为不需要为参数创建副本。
- 使得函数能够修改原始变量,而不仅仅是参数的副本。
- 可以增加程序的效率,因为不需要在函数中复制大量的数据。
以下是一个使用值传递和引用传递的示例程序:
#include <iostream>
using namespace std;
void valueSwap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
void referenceSwap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 5, y = 10;
cout << "Before value swap: x = " << x << ", y = " << y << endl;
valueSwap(x, y);
cout << "After value swap: x = " << x << ", y = " << y << endl;
x = 5, y = 10;
cout << "Before reference swap: x = " << x << ", y = " << y << endl;
referenceSwap(x, y);
cout << "After reference swap: x = " << x << ", y = " << y << endl;
return 0;
}
输出结果为:
Before value swap: x = 5, y = 10
After value swap: x = 5, y = 10
Before reference swap: x = 5, y = 10
After reference swap: x = 10, y = 5
可以看到,使用值传递时,函数valueSwap
并没有交换原始变量的值,而使用引用传递时,函数referenceSwap
成功地交换了原始变量的值。
结束语:
本篇只是一个用于算法学习的C++基础知识点的简单汇总,并不全面但具有代表性,其中C++的核心特征例如:面向对象编程并没有涉及,有兴趣可以再去了解,关于学习算法过程中还可能用到的C++基础知识还有一个STL容器,因为涉及的内容太多,建议将此篇完全 搞透之后再进行进一步的学习,我们下篇着重讲解STL容器相关知识点。
拓展:C++中的头文件
除了基本的输入和输出之外,C++ 还提供了许多有用的头文件和库,可以帮助你更轻松地处理输入输出以及其他一些常见任务。
头文件
头文件是 C++ 程序中包含其他库和组件的一种方式。头文件中包含了这些库和组件的声明,这使得你可以在程序中使用这些库和组件的函数、类型和变量。
除了基本的输入和输出之外,C++ 还提供了许多有用的头文件和库,可以帮助你更轻松地处理输入输出以及其他一些常见任务。
头文件
头文件是 C++ 程序中包含其他库和组件的一种方式。头文件中包含了这些库和组件的声明,这使得你可以在程序中使用这些库和组件的函数、类型和变量。
一些常用的头文件包括:
<iostream>
:输入和输出的头文件,包含了std::cin
、std::cout
、std::cerr
和std::clog
等对象,以及其他一些有用的函数和类型。<cstdio>
:输入和输出的头文件,包含了printf
、scanf
、puts
、gets
等函数,以及其他一些有用的函数和类型。<cstring>
:字符串操作的头文件,包含了strlen
、strcpy
、strcat
、strcmp
等函数,以及其他一些有用的函数和类型。<cmath>
:数学函数的头文件,包含了各种常见的数学函数,例如 sin、cos、tan、exp、log 等函数。<algorithm>
:算法库的头文件,包含了许多有用的算法,例如排序、查找、复制、删除、计数、最大值/最小值等。<vector>
:动态数组的头文件,包含了std::vector
类型和相关的函数和操作。<string>
:字符串类型的头文件,包含了std::string
类型和相关的函数和操作。<queue>
:队列类型的头文件,包含了std::queue
类型和相关的函数和操作。<stack>
:栈类型的头文件,包含了std::stack
类型和相关的函数和操作。<map>
:映射类型的头文件,包含了std::map
类型和相关的函数和操作。<set>
:集合类型的头文件,包含了std::set
类型和相关的函数和操作。<ctime>
:日期和时间的头文件,包含了std::time
函数和相关的类型和操作。<cstdlib>
:常用的函数和类型,例如rand
、srand
、malloc
、calloc
等函数和类型。