C++ 速查表
这份C++ 编程速查表非常方便易用,可在短时间内提供关键信息。它专为想要了解重要主题并进入C++编程世界的人士量身定制。它涵盖了所有可能需要了解的要点和细节,并包含示例和代码片段,指导人们如何实际使用这门语言。
第一个程序 - Hello World
任何编程语言的基础都是其开发过程。任何初学者学习编程语言都是从学习其语法开始的。那么,让我们从用 C++ 编写第一个程序开始,例如:打印 Hello World −
示例
#include <bits/stdc++.h>
using namespace std;
// main() 是程序执行的起点。
int main() {
cout<<"Hello World"<<endl;
// 这是你编写代码的地方
return 0;
}
输出
Hello World
注释
C++ 中的注释 用于添加对程序员有用的额外信息。C 支持单行注释,// 用于指示单行注释,/* 用于启动多行注释,*/ 用于结束多行注释。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
/* 这是多行注释。
以下语句将仅打印 Hello World*/
cout<<"Hello World"<<endl;
// 这是单行注释
return 0;
}
输出
Hello World
输入和输出语句
这里,"cin"是输入语句,伴随">>",而"cout"是输出语句,伴随">>"。
另请参阅: C++ 基本输入/输出
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
//整数变量的声明
int age;
cout << "Enter your age: "<<endl;
cin >> age;
cout << "Your age is: " << age << endl;
return 0;
}
变量
变量是存储不同类型数据的存储空间。C++ 中的变量必须在使用前声明,变量名称必须以字母开头,可以包含字母、数字和下划线 (_)。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
// 声明多个变量
int a, b, c;
char ch;
string s;
return 0;
}
关键字
关键字是特定语言编译器保留的特殊类型的词,程序员无法明确使用。其中一些关键字如下:
| asm | else | new | this |
| auto | enum | operator | throw |
| bool | explicit | private | true |
| break | export | protected | try |
| case | extern | public | typedef |
| catch | false | register | typeid |
| char | float | reinterpret_cast | typename |
| class | for | return | union |
| const | friend | short | unsigned |
| const_cast | goto | signed | using |
| continue | if | sizeof | virtual |
| default | inline | static | void |
| delete | int | static_cast | volatile |
| do | long | struct | wchar_t |
| double | mutable | switch | while |
| dynamic_cast | namespace | template |
数据类型
数据类型是指变量存储在内存中的可用存储类型。数据类型可分为三类:
1. 原始数据类型
原始数据类型已存在于C++ 语言库中。这些库无需修改即可使用。
1.1. Int
整数数据类型的关键字是 int。整数通常需要 4 个字节的内存空间,取值范围从 -2147483648 到 2147483647。
1.2.浮点型
浮点数据类型用于存储单精度浮点值或小数。浮点数据类型的关键字是 float。浮点型变量通常需要 4 个字节的内存空间。
1.3. 字符型
字符数据类型用于存储字符。字符数据类型的关键字是 char。字符通常需要 1 个字节的内存空间,取值范围是 -128 到 127 或 0 到 255。
1.4. 双精度型
双精度浮点数据类型用于存储双精度浮点值或小数。双精度浮点数据类型的关键字是 double。
1.5.字符串
字符串数据类型用于在单个变量中存储多个字符。
1.6. 布尔值
布尔值数据类型用于存储布尔值或逻辑值。布尔值变量可以存储"真"或"假"。布尔值数据类型使用的关键字是 bool。
示例
int main() {
int age=12;
// 仅接受整数,大小为 4 个字节
float weight=70.4;
// 接受十进制数值,大小为 4 个字节
char alpha='a';
// 接受 ASCII 码中的单个字符,大小为 1 个字节
string s="hey siri";
// 接受多个字符,大小可变
double d=2.2222;
// 接受更精确的浮点数,大小为 8 个字节
bool k=true;
// 仅接受 true 或 false 值(或 0/1)
return 0;
}
2. 派生数据类型
这些数据类型源自原始数据类型,称为派生数据类型。它们可以分为四种类型:函数
这些将在后面的章节中简要讨论。
3.用户自定义数据类型
这些数据类型由用户自行定义,并可根据用户的意愿进行自定义。主要有以下五种类型:
3.1. 类
类和对象的概念在本速查表的面向对象编程 (OOPS) 部分进行了解释。示例可在此处参考。
示例
#include <bits/stdc++.h>
using namespace std;
class MyClass {
public:
int myNum;
string myString;
};
int main() {
MyClass myObj;
myObj.myNum = 1234567;
myObj.myString = "Helloooo";
cout << myObj.myNum << "";
cout << myObj.myString;
return 0;
}
输出
1234567 Hellooooo
3.2. 结构
定义结构体的语法如下。
struct structName{
char varName[size];
int varName;
};
3.3. 联合
定义联合的语法如下。
Union_Name{
// 数据成员声明
}; union_variables;
3.4. 枚举
定义枚举变量的语法如下。
enum nameOfEnum {
varName1 = 1, varName2 = 0
};
3.5. Typedef
定义 typedef 的语法如下。
typedef typeName;
示例
#include <bits/stdc++.h>
using namespace std;
typedef unsigned char BYTE;
int main() {
BYTE b1, b2;
b1 = 'c';
cout << " " << b1;
return 0;
}
输出
c
条件语句
条件语句控制程序流程,可用于定义不同的情况和条件。在这种情况下,可以使用原语"if"、"else"、"else if"、"switch"和三元运算符。
- if 语句
- if-else 语句
- if-else-if 语句
- 嵌套 if-else 语句
- switch 语句
- 三元运算符
1. If 语句
If 语句当且仅当给定条件为真时,才执行代码块。
2. if-else 语句
如果 if 语句中的条件为真,则执行 if 块中的代码,否则执行 else 块中的代码。
3. if-else-if 语句
else if 语句允许您按顺序检查多个条件。
4. 嵌套 if 语句
多个 if 语句可以嵌套使用,根据需要构成不同的 case。
5. 三元运算符
它用作条件语句,接受一个条件语句并返回第一个语句或第二个语句。
6. Switch Case 语句
如果有多个条件,我们可以简单地使用 switch case 语句来更轻松地处理这些条件。
示例
#include <iostream>
using namespace std;
int main() {
//程序解释 if、else if 和 else 条件
int age=12;
if(age<12) cout<<"YES"<<endl;
else if(age>24) cout<<"NO"<<endl;
else cout<<"MAYBE"<<endl;
//解释三元运算符的程序
bool x=true;
x==1 ? cout<<"true"<<endl : cout<<"false"<<endl;
//程序解释带有 break 和 default 的 switch case
switch (x & x){
case 0 :
cout<<"false"<<endl;
break;
case 1 :
cout<<"true"<<endl;
break;
default:
cout<<"invalid"<<endl;
break;
}
return 0;
}
输出
MAYBE true true
运算符
C++ 中的运算符可分为 6 类 -
1. 算术运算符
这些运算符用于对操作数执行算术或数学运算。例如,+ 用于加法,- 用于减法,* 用于乘法等等。
示例
#include <iostream>
using namespace std;
int main() {
int a = 8, b = 3;
// 加法运算符
cout << "a + b = " << (a + b) << endl;
// 减法运算符
cout << "a - b = " << (a - b) << endl;
// 乘法运算符
cout << "a * b = " << (a * b) << endl;
// 除法运算符
cout << "a / b = " << (a / b) << endl;
// 模运算符
cout << "a % b = " << (a % b) << endl;
// 一元运算符
a++;
cout<<a<<endl;
a--;
cout<<a<<endl;
int k=++a + ++b;
cout<<k<<endl;
k=++a - --b;
cout<<k<<endl;
return 0;
}
输出
a + b = 11 a - b = 5 a * b = 24 a / b = 2 a % b = 2 9 8 13 7
2. 关系运算符
这些运算符用于比较两个操作数的值。例如,> 检查一个操作数是否大于另一个操作数等等。结果返回布尔值,即 true 或 false。
示例
#include <iostream>
using namespace std;
int main() {
int a = 6, b = 4;
// 等于运算符
cout << "a == b is " << (a == b) << endl;
// 大于运算符
cout << "a > b is " << (a > b) << endl;
// 大于或等于运算符
cout << "a >= b is " << (a >= b) << endl;
// 小于运算符
cout << "a < b is " << (a < b) << endl;
// 小于或等于运算符
cout << "a <= b is " << (a <= b) << endl;
// 真
cout << "a != b is " << (a != b) << endl;
return 0;
}
输出
a == b is 0 a > b is 1 a >= b is 1 a < b is 0 a <= b is 0 a != b is 1
3. 逻辑运算符
这些运算符用于组合两个或多个条件或约束,或补充考虑的原始条件的评估。结果返回布尔值,即 true 或 false。
示例
#include <iostream>
using namespace std;
int main() {
int a = 6, b = 4;
// 逻辑与运算符
cout << "a && b 为 " << (a && b) << endl;
// 逻辑或运算符
cout << "a || b 为 " << (a || b) << endl;
// 逻辑非运算符
cout << "!b 为 " << (!b) << endl;
return 0;
}
输出
a && b 为 1 a || b 为 1 !b 为 0
4. 位运算符
这些运算符用于对操作数执行位级运算。运算符首先转换为位级,然后对操作数执行计算。诸如加法、减法、乘法等数学运算可以在位级执行,以便更快地进行处理。
示例
#include <iostream>
using namespace std;
int main() {
int a = 6, b = 4;
// 二进制与运算符
cout << "a & b 为 " << (a & b) << endl;
// 二进制或运算符
cout << "a | b 为 " << (a | b) << endl;
// 二进制异或运算符
cout << "a ^ b 为 " << (a ^ b) << endl;
// 左移运算符
cout << "a<<1 为 " << (a << 1) << endl;
// 右移运算符
cout << "a>>1 为 " << (a >> 1) << endl;
// 一的补码运算符
cout << "~(a) 为 " << ~(a) << endl;
return 0;
}
输出
a & b 为 4 a | b 为 6 a ^ b 为 2 a<<1 为 12 a>>1 为 3 ~(a) 为 -7
5. 赋值运算符
这些运算符用于为变量赋值。赋值运算符左侧的操作数是变量,右侧的操作数是值。右侧的值必须与左侧的变量属于相同的数据类型,否则编译器会报错。
示例
#include <iostream>
using namespace std;
int main() {
int a = 6, b = 4;
// 赋值运算符
cout << "a = " << a << endl;
// 加法和赋值运算符
cout << "a += b is " << (a += b) << endl;
// 减法和赋值运算符
cout << "a -= b is " << (a -= b) << endl;
// 乘法和赋值运算符
cout << "a *= b is " << (a *= b) << endl;
// 除法和赋值运算符
cout << "a /= b is " << (a /= b) << endl;
return 0;
}
输出
a = 6 a += b is 10 a -= b is 6 a *= b is 24 a /= b is 6
循环
循环语句用于以连续的方式遍历某些数据。循环广泛应用于数据结构,例如数组、链表、图、树等等。这些是递归、动态规划和图论等高级概念的基石。循环语句主要有三种类型 -
1. For 循环
For 循环用于在满足结束条件之前,按特定次数遍历某个数据结构。
示例
#include <iostream>
using namespace std;
int main() {
for(int i=0;i<6;i++){
cout<<"hello"<<endl;
}
return 0;
}
输出
hello hello hello hello hello hello
2. While 循环
While 循环用于运行循环语句,直到指定条件变为 false,否则循环将持续运行。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
int i=0;
while(i<6){
cout<<"hello"<<endl;
i++;
}
return 0;
}
输出
hello hello hello hello hello hello
3. Do-while 循环
在 do-while 循环中,循环首先在给定条件下运行,然后检查 while 语句是否继续运行。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
int i=0;
do{
cout<<"hello"<<endl;
i++;
}while(i<6);
return 0;
}
输出
hello hello hello hello hello hello
引用和指针
1. 引用
引用用于为同一内存位置及其存储的值创建新的名称。我们可以在变量名称旁边使用"与"符号 ($) 来创建对任何变量的引用。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
int i=3;
int &k=i;
cout<<i<<k<<endl;
return 0;
}
输出
33
2. 指针
指针是用于存储其指向变量地址的变量,* 用于声明指向任何变量的指针。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
int a=4;
int *ptr=&a;
cout<<a<<ptr<<*ptr<<endl;
return 0;
}
输出
40x7ffeb2bcfb0c4
数组
数组是由相同数据类型的元素组成的序列,这些元素存储在存储空间中连续的内存位置。数组声明时可以指定元素数量,也可以不指定。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
int arr1[]={1,2,3,4,4,3,2,1};
int arr2[8]={0};
for(int i=0;i<8;i++){
cout<<arr1[i]<<arr2[i]<<endl;
}
return 0;
}
输出
10 20 30 40 40 30 20 10
多维数组
数组也可以定义在多个维度中,并且所有元素都属于同一数据类型。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
int arr[2][3]={{1,2,3},{4,4,3}};
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
cout<<arr[i][j]<<endl;
}
}
return 0;
}
输出
1 2 3 4 4 3
函数
函数是代码的一部分,如果之前定义过,可以调用,有助于使代码简洁易读。函数可以作为程序的一部分创建,也可以在类主体中创建。
函数具有名称、返回类型(也可以为 void)、输入变量和方法主体。以下示例展示了如何在 C++ 中定义和使用函数。
C++ 中的函数有两种类型 -
- 原始函数,它们已经在 C++ 库中定义。 原始函数的示例包括 sin()、cos()、min()、max() 等数学函数。
- 用户定义函数,根据用户需求定义,并可进行相应定制。
示例
#include <bits/stdc++.h>
using namespace std;
void sum1(int &a, int &b){
b+=a;
}
int main(){
int a=10, b=12;
sum1(a,b);
cout<<b<<a<<endl;
return 0;
}
输出
2210
数学函数
C++ 作为 C 语言的超集,支持大量实用的数学函数。这些函数在标准 C++ 中可用,支持各种数学计算。
无需关注具体实现,这些函数可以直接使用,从而简化代码和程序。要使用这些函数,您需要包含头文件 - <math.h> 或 <cmath>。
以下示例展示了许多此类数学函数的用法,这些函数可以直接用于复杂的计算。
示例
#include <bits/stdc++.h>
using namespace std;
int main() {
double x = 2.3;
cout << "Sine value of x=2.3 : " << sin(x) << endl;
cout << "Cosine value of x=2.3 : " << cos(x) << endl;
cout << "Tangent value of x=2.3 : " << tan(x) << endl;
double y = 0.25;
cout << "Square root value of y=0.25 : " << sqrt(y)
<< endl;
int z = -10;
cout << "Absolute value of z=-10 : " << abs(z) << endl;
cout << "Power value: x^y = (2.3^0.25) : " << pow(x, y)
<< endl;
x = 3.0;
y = 4.0;
cout << "Hypotenuse having other two sides as x=3.0 and"
<< " y=4.0 : " << hypot(x, y) << endl;
x = 4.56;
cout << "Floor value of x=4.56 is : " << floor(x)
<< endl;
x = -4.57;
cout << "Absolute value of x=-4.57 is : " << fabs(x)
<< endl;
x = 1.0;
cout << "Arc Cosine value of x=1.0 : " << acos(x)
<< endl;
cout << "Arc Sine value of x=1.0 : " << asin(x) << endl;
cout << "Arc Tangent value of x=1.0 : " << atan(x)
<< endl;
y = 12.3;
cout << "Ceiling value of y=12.3 : " << ceil(y) << endl;
x = 57.3; // in radians
cout << "Hyperbolic Cosine of x=57.3 : " << cosh(x)
<< endl;
cout << "Hyperbolic tangent of x=57.3 : " << tanh(x)
<< endl;
y = 100.0;
// Natural base with 'e'
cout << "Log value of y=100.0 is : " << log(y) << endl;
return 0;
}
输出
Sine value of x=2.3 : 0.745705 Cosine value of x=2.3 : -0.666276 Tangent value of x=2.3 : -1.11921 Square root value of y=0.25 : 0.5 Absolute value of z=-10 : 10 Power value: x^y = (2.3^0.25) : 1.23149 Hypotenuse having other two sides as x=3.0 and y=4.0 : 5 Floor value of x=4.56 is : 4 Absolute value of x=-4.57 is : 4.57 Arc Cosine value of x=1.0 : 0 Arc Sine value of x=1.0 : 1.5708 Arc Tangent value of x=1.0 : 0.785398 Ceiling value of y=12.3 : 13 Hyperbolic Cosine of x=57.3 : 3.83746e+24 Hyperbolic tangent of x=57.3 : 1 Log value of y=100.0 is : 4.60517
面向对象编程
面向对象编程 (OOPS) 概念 也存在于 C++ 中。这意味着程序可以细分为类和对象。
1. 类
类是一种用户定义的数据类型,包含两个组成部分:变量和方法。类可以使用构造函数
进行初始化。2. 对象
对象是类的实例或变量。对象占用存储空间。
3. 封装
封装是将数据和方法封装在一个类或类别中。为此,我们使用了类。
4. 抽象
这包括使用一定级别的安全性来隐藏细节。
5. 多态性
使用相同的名称和主体创建对象或方法的多个实例称为多态性。
多态性有以下几种类型:
1. 编译时多态性
编译时多态性可以通过以下方式实现:
2.运行时多态性
运行时多态性可以通过以下方式实现:-
- 函数重载
- 病毒函数
6.继承
将一个类(父类)的属性派生到另一个类(子类)称为继承。
文件处理
文件处理中的不同操作如下:-
- 打开文件 - 要打开文件,请使用 ofstream 类的 open() 方法。
- 读取文件 - 要读取文件,请使用 ifstream 类的 getline() 方法。
- 写入文件 - 使用"<<"运算符在文件打开时写入内容。
示例
#include <bits/stdc++.h>
using namespace std;
int main(){
ofstream outputFile("file1.txt");
// 打开文件进行写入
outputFile.open("file1.txt");
if (outputFile.is_open()) {
// 将数据写入文件
outputFile << "Hello, World!" << endl;
outputFile << 1333113 << endl;
outputFile.close(); // 关闭文件
}else {
// 无法打开文件
cout << "Error"<< endl;
return 1;
}
// 从文件读取
ifstream inputFile("file1.txt");
if (inputFile.is_open()) {
string line;
while (getline(inputFile, line)) {
// 打印每一行
cout << line << endl;
}
// 关闭文件
inputFile.close();
}else {
// 无法打开文件
cout << "Error"<< endl;
return 1;
}
return 0;
}
异常处理
使用类和对象时,可能会出现各种错误和异常,这些错误和异常可能是由于用户编写的程序本身存在错误,也可能是由于某些机器故障(例如内存或执行错误)造成的。这些错误可能对程序的顺利执行造成致命影响,因此需要使用 try 和 catch 块进行处理。
当发生错误时,C++ 通常会停止运行并生成错误消息。用专业术语来说:C++ 会抛出异常(抛出错误)。
- Try 块 − try 语句允许您定义一个代码块,以便在执行过程中测试错误。
- Throw − throw 关键字在检测到问题时抛出异常,这让我们可以创建自定义错误。
- Catch 块 − catch 语句允许您定义一个代码块,如果 try 块中发生错误,则执行该代码块。
Try-Catch 异常处理的语法
try {
// 尝试的代码块
throw exception; // 出现问题时抛出异常
}
catch () {
// 用于处理错误的代码块
}
Example
#include <bits/stdc++.h>
using namespace std;
try {
int bmi=30;
if (bmi>28) {
cout << "You are overweight.";
} else {
throw (bmi);
}
}
catch (int x) {
cout << "You are underweight.";
cout << "Weight is: " << x;
}
预处理器
预处理器是一些关键字,用于指示编译器在实际编译开始之前处理指令。它们以 # 开头,末尾不需要任何 ;,因为它们不是语句。
预处理器的示例包括 #include、#define 等等。
让我们来看看 C++ 库中重要的预处理器 -
- #include
- #define
1. #include
它用于包含执行程序中使用的方法和函数所需的头文件和库。如前所述,该方法的实际实现并未展示,而是显示最终结果。
示例
#include <math.h>
#include <iostream>
using namespace std;
//iostream 用于数据输入和输出流
//math.h 用于包含数学函数,例如 pow(x,y)
int main(void){
cout<<pow(2,3);
return 0;
}
输出
8
2. #define
#define 预处理器指令用于创建符号常量。该符号常量称为宏,该指令的一般形式为符号 #,后跟 Define 语句以及需要定义的常量的定义。当文件中出现此格式时,该文件中所有后续出现的宏都将在程序编译前被替换为替换文本。
示例
#include <bits/stdc++.h>
using namespace std;
#define A 45
//将 A 的值定义为 45
int main(void){
int a= A;
cout<<a;
return 0;
}
输出
45
命名空间
命名空间用于在程序中定义两个同名函数。这样,编译器在调用函数时就知道应该使用哪个方法。使用命名空间,您可以定义定义名称的上下文。本质上,命名空间定义了作用域。
定义命名空间很简单。您只需在方法内写入 namespace 后跟代码即可。在程序内部使用此函数,只需提及它所在的命名空间,并在两者之间加上 :: 符号即可。
示例 1
#include <bits/stdc++.h>
using namespace std;
// 第一个名称空间
namespace first_space {
void func() {
cout << "Inside first_space" << endl;
}
}
// 第二个命名空间
namespace second_space {
void func() {
cout << "Inside second_space" << endl;
}
}
int main () {
// 从第一个命名空间调用函数。
first_space::func();
// 从第二个命名空间调用函数。
second_space::func();
return 0;
}
输出
Inside first_space Inside second_space
using 关键字可以以指令的形式使用,指示后续代码遵循上述命名空间。std 关键字类似地用于指示所有代码都将遵循标准命名空间。
要了解有关命名空间的更多信息,请参阅本文 C++ 中的命名空间
示例 2
#include <bits/stdc++.h>
using namespace std;
// 第一个命名空间
namespace first_space {
void func() {
cout << "Inside first_space" << endl;
}
}
// 第二个命名空间
namespace second_space {
void func() {
cout << "Inside second_space" << endl;
}
}
using namespace first_space;
int main () {
// 从名字空间调用函数。
func();
return 0;
}
输出
Inside first_space
模板
模板是创建通用类或函数的蓝图或公式。迭代器和算法等库容器都是使用模板概念开发的。
C++ 中有两种类型的模板 -
- 类模板
- 函数模板
1. 类模板
类模板可用于定义不同的数据结构,例如链表、堆栈、队列、优先级队列、树等。类模板可以通过以下方式定义 -
语法
template <class type> class class-name {
.
.
.
}
示例
#include <bits/stdc++.h>
using namespace std;
template <typename T> class Array {
T* pointer;
int size;
public:
Array(T a[], int s);
void show();
};
template <typename T> Array<T>::Array(T a[], int s){
pointer = new T[s];
size = s;
for (int i = 0; i < size; i++)
pointer[i] = a[i];
}
template <typename T> void Array<T>::show(){
for (int i = 0; i < size; i++)
cout << *(pointer + i)<<endl;
cout << endl;
}
int main(){
int size=7;
int a[size] = { 12, 21, 45, 34, 19, 55, 66 };
Array<int> a1(a, 7);
a1.show();
return 0;
}
输出
12 21 45 34 19 55 66
2. 函数模板
这些模板可用于使用模板库创建具有内置功能的通用函数。函数模板的一些示例包括 max()、min()、sin()、floor() 等。
示例
#include <bits/stdc++.h>
using namespace std;
template <typename T> T minof3(T x, T y, T z){
if(x<y && x<z) return x;
if(y<x && y<z) return y;
if(z<x && z<y) return z;
// else return "Not applicable !!!";
}
int main(){
// 对 int 类型调用 minof3
cout << minof3<int>(32,58,97) << endl;
// 对 double 类型调用 minof3
cout << minof3<double>(13.0,12.0, 17.0) << endl;
// 为 char 调用 minof3
cout << minof3<char>('g', 'e', 't') << endl;
// 对 string 调用 minof3
cout << minof3<string>("apple", "ball", "cat")<<endl;
return 0;
}
输出
32 12 e apple
动态内存
C++ 中的内存分为两部分 -
- 栈内存 - 函数内声明的所有变量都会占用栈内存。
- 堆内存 - 这是程序中未使用的内存,可用于在程序运行时动态分配内存。
编写程序时,有时可能会出现无法预先知道所需内存的情况,因此运行时需要从堆内存中分配额外的空间。这就是动态内存分配,可以使用 new 关键字来实现。使用完这些空间后,可以使用 delete 关键字释放数据。
C 语言中的 malloc() 函数在 C++ 中仍然存在,但建议避免使用 malloc() 函数。 new 相对于 malloc() 的主要优势在于,new 不仅仅分配内存,还能构造对象,这正是 C++ 的主要用途。
示例
#include <bits/stdc++.h>
using namespace std;
int main () {
int *ptr = NULL; // 指针初始化为 null
ptr = new int; // 为变量申请内存
*ptr = 31; // 将值存储在分配的地址处
cout << "Value of pointer : " << *ptr << endl;
delete ptr; // 释放内存。
return 0;
}
输出
Value of pointer : 31
同样,在实现数组和类时也可以分配动态内存。有关动态内存分配的更多信息,请参阅这篇关于动态内存分配的文章。
信号处理
信号处理是控制程序执行期间发出的中断信号的过程。中断种类繁多,它们可以提前结束程序并生成不同的响应。例如,在 Linux/Unix 命令行界面 (CLI) 中,CTRL+C 命令会生成结束程序中断。同样,C++ 编程语言中也存在许多中断。这些中断定义在 <csignal> 库中。
| Sr.No | 信号 &描述 |
|---|---|
| 1 | SIGABRT 程序异常终止,例如调用abort。 |
| 2 | SIGFPE 错误的算术运算,例如除以零或导致溢出的运算。 |
| 3 | SIGILL 检测到非法指令。 |
| 4 | SIGINT 收到交互式注意信号。 |
| 5 | SIGSEGV 无效的存储访问。 |
| 6 | SIGTERM 向程序发送终止请求。 |
1. signal() 函数
signal 函数由 <csignal> 库提供,用于一次性捕获不需要的或错误的中断。以下是 signal() 函数的用法,它接受两个输入:第一个是信号编号,第二个是信号处理函数。
示例
#include <csignal>
#include <iostream>
using namespace std;
void handler_func(int signal_num){
cout << endl<<"You have interrupted: (" << signal_num
<< "). ";
//使用 exit 终止
exit(signal_num);
}
int main(){
//初始化信号
signal(SIGABRT, handler_func);
while (true) {
cout << "You can't stop me !!!" << endl;
this_thread::sleep_for(chrono::seconds(1));
//这是用来延迟的
}
return 0;
//按 ctrl+c 中断程序执行!!!
}
2. raise() 函数
signal 函数由 <csignal> 库提供,用于生成中断及其编号。以下是 raise() 函数的用法,该函数的输入为信号编号。
示例
#include <csignal>
#include <iostream>
using namespace std;
void signal_handler(int signum){
cout << "You generated this interrupt: (" << signum << ").";
// 终止程序
exit(signum);
}
int main(){
int i = 0;
signal(SIGABRT, signal_handler);
while (++i) {
cout << "You can't stop me !!!" << endl;
if (i == 10)
raise(SIGABRT);
}
return 0;
}
多线程
多线程是操作系统中处理器多任务处理概念的一部分。多任务处理通常分为两类:基于进程和基于线程。
在基于进程的多任务处理中,两个或多个进程或程序在处理器上并发执行,并且完全依赖于处理器的处理能力。
在基于线程的多任务处理中,每个程序被划分为多个线程,这些线程可以被认为是在处理器上并发运行并共同生成响应的较小子程序。因此,多个线程组合在一起形成一个程序。这就是所谓的多线程。
在 C++ 11 发布之前,C++ 中没有内置多线程支持。C++ 使用 POSIX 线程或 Pthreads,它们在许多类 Unix POSIX 系统上都可用。可以在 pthreads 上执行以下操作:
- 创建线程
- 终止线程
- 向线程传递参数
- 加入和分离线程
创建线程
可以使用 <pthread.h> 库中的例程 pthread_create 创建线程。这些线程可以在程序内部的任何位置创建。
语法
#include <pthread.h> pthread_create (thread, attr, start_routine, arg);
| 序号 | 参数 &描述 |
|---|---|
| 1 |
thread 子例程返回的新线程的不透明唯一标识符。 |
| 2 |
attr 可用于设置线程属性的不透明属性对象。您可以指定一个线程属性对象,或使用 NULL 作为默认值。 |
| 3 |
start_routine 线程创建后将执行的 C++ 例程。 |
| 4 |
arg 可以传递给 start_routine 的单个参数。它必须通过引用传递,并转换为 void 类型的指针。如果不传递参数,可以使用 NULL。 |
终止线程
pthread_exit() 用于在线程完成执行且程序不再需要时终止该线程。这有助于首先清除分配给线程的空间。
语法
#include <pthread.h> pthread_exit (status);
示例
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 5
void *PrintHello(void *threadid) {
long tid;
tid = (long)threadid;
cout << "Hello World! Thread ID, " << tid << endl;
pthread_exit(NULL);
}
int main () {
pthread_t threads[NUM_THREADS];
int rc;
int i;
for( i = 0; i < NUM_THREADS; i++ ) {
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
输出
main() : creating thread, 0 main() : creating thread, 1 Hello World! Thread ID, 0 main() : creating thread, 2 Hello World! Thread ID, 1 main() : creating thread, 3 Hello World! Thread ID, 2 main() : creating thread, 4 Hello World! Thread ID, 3 Hello World! Thread ID, 4
连接和断开线程
以下例程用于连接和断开程序中的线程 -
语法
pthread_join (threadid, status) pthread_detach (threadid)
示例
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
using namespace std;
#define NUM_THREADS 5
void *wait(void *t) {
int i;
long tid;
tid = (long)t;
sleep(1);
cout << "Sleeping in thread " << endl;
cout << "Thread with id : " << tid << " ...exiting " << endl;
pthread_exit(NULL);
}
int main () {
int rc;
int i;
pthread_t threads[NUM_THREADS];
pthread_attr_t attr;
void *status;
// 初始化并设置线程可连接
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for( i = 0; i < NUM_THREADS; i++ ) {
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], &attr, wait, (void *)i );
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
// 释放属性并等待其他线程
pthread_attr_destroy(&attr);
for( i = 0; i < NUM_THREADS; i++ ) {
rc = pthread_join(threads[i], &status);
if (rc) {
cout << "Error:unable to join," << rc << endl;
exit(-1);
}
cout << "Main: completed thread id :" << i ;
cout << " exiting with status :" << status << endl;
}
cout << "Main: program exiting." << endl;
pthread_exit(NULL);
}
输出
main() : creating thread, 0 main() : creating thread, 1 main() : creating thread, 2 main() : creating thread, 3 main() : creating thread, 4 Sleeping in thread Thread with id : 0 ...exiting Sleeping in thread Thread with id : 2 ...exiting Sleeping in thread Thread with id : 1 ...exiting Main: completed thread id :0 exiting with status :0 Sleeping in thread Main: completed thread id :1 exiting with status :0 Main: completed thread id :2 exiting with status :0 Thread with id : 4 ...exiting Sleeping in thread Thread with id : 3 ...exiting Main: completed thread id :3 exiting with status :0 Main: completed thread id :4 exiting with status :0 Main: program exiting.
向线程传递参数
以下程序演示了如何使用多线程在线程内传递参数和语句。
示例
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 5
struct thread_data {
int thread_id;
char *message;
};
void *PrintHello(void *threadarg) {
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
cout << "Thread ID : " << my_data->thread_id ;
cout << " Message : " << my_data->message << endl;
pthread_exit(NULL);
}
int main () {
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc;
int i;
for( i = 0; i < NUM_THREADS; i++ ) {
cout <<"main() : creating thread, " << i << endl;
td[i].thread_id = i;
td[i].message = "This is message";
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
输出
main() : creating thread, 0 main() : creating thread, 1 main() : creating thread, 2 Thread ID : 0 Message : This is message Thread ID : 1 Message : This is message main() : creating thread, 3 Thread ID : 2 Message : This is message main() : creating thread, 4 Thread ID : 3 Message : This is message Thread ID : 4 Message : This is message
自 C++ 编程诞生以来,世界发生了翻天覆地的变化,了解不断引入的新语法也变得越来越重要。本文概述了 C++ 中最流行的语法,旨在为编程新手讲解所有基础知识。对于经验丰富的开发者,本文将概述 C++ 领域的最新动态。

