数组 数组声明
数组初始化 1 2 3 4 double balance[5 ] = {1.0 , 2.0 , 3.4 , 5.0 , 9.0 }; double balance[] = {1000.0 , 2.0 , 3.4 , 7.0 };
数组访问 数组元素通过数据名加索引进行访问。元素索引放在方括号内,跟在数组名称后面。如:
1 2 3 4 double balance[5 ] = {1.0 , 2.0 , 3.4 , 5.0 , 9.0 };double num3 = balance[2 ]
数组传递及函数返回 方式一: 形参是已经定义大小的数组
1 2 3 void myFunction (int param[10 ]) { code_block }
方式二: 形参是没有定义大小的数组
1 2 3 void myFunction (int param[]) { code_block }
方式三: 形参是指针(不在该处详细介绍)
1 2 3 void myFunction (int *param) { code_block }
实例: 传递数组到函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> using namespace std;double getAverage (int arr[], int size) ;int main () { int balance[5 ] = { 1000 , 2 , 3 , 17 , 50 }; double avg; avg = getAverage (balance, 5 ); cout << "平均值是:" << avg << endl; return 0 ; } double getAverage (int arr[], int size) { int i, sum = 0 ; double avg; for (i = 0 ; i < size; ++i) { sum += arr[i]; } avg = double (sum) / size; return avg; }
从函数返回数组 不在此处详解,需要先学习指针
数组扩展 多维数组:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int a[3 ][3 ] = { {0 , 1 , 2 }, {3 , 4 , 5 }, {6 , 7 , 8 } }; int a[3 ][3 ] = {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };int val = a[0 ][2 ];
同理,多维数组也可以进行函数传递及返回。
字符串 C风格字符串(c++也能用) 字符串初始化
1 2 3 4 5 6 7 8 9 10 11 char mystring[6 ] = {'h' , 'e' , 'l' , 'l' , 'o' , '\0' };char mystring[6 ] = {'h' , 'e' , 'l' , 'l' , 'o' }; char mystring[5 ] = {'h' , 'e' , 'l' , 'l' , 'o' }; char mystring[] = "hello" ;
C++中操作null结尾的字符串(C风格)的常用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 strcpy (s1, s2) strcpy_s (s1, s2);strcat (s1, s2); strcat_s (s1, s2); strcmp (s1, s2)strchr (s1, 'a' ); strstr (s1, s2);
C++中的高级字符串 C++ 标准库提供了 string 类类型,支持上述所有的操作,另外还增加了其他更多的功能。 使用相关操作需要引入标准库#include <string>
上述方法在c++中的对应方法
C 语言函数
C++ std::string 等价写法
strcpy_s(dest, size, src);
std::string str = src; 或 str = src;
strcat_s(dest, size, src);
str += src; 或 str.append(src);
strlen(str);
str.length(); 或 str.size();
strcmp(str1, str2);
str1.compare(str2);
strchr(str, ch);
str.find(ch);(返回索引)或 str.find_first_of(ch); 找不到返回std::string::npos
strstr(str, substr);
str.find(substr);(返回索引)找不到返回std::string::npos 或 str.contains(substr);(C++23支持)
除了对应方法之外,还有更多强大的操作,可以查看该文档 对新手友好的总结,可以查看这篇文章
引用 引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。
1 2 int a = 10 ;int &ref = a;
引用和指针对比(可以学习完指针后再过来进行对比)
不存在空引用,引用必须连接到一块合法的内存。 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。 引用必须在创建时被初始化。指针可以在任何时间被初始化。 引用的对象必须是一个变量,而指针必须是一个地址。
更详细的对比,参考文章
引用作为传参(经典交换两数问题): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <iostream> using namespace std;void swap (int & x, int & y) ;int main () { int a = 100 ; int b = 200 ; cout << "交换前,a 的值:" << a << endl; cout << "交换前,b 的值:" << b << endl; swap (a, b); cout << "交换后,a 的值:" << a << endl; cout << "交换后,b 的值:" << b << endl; return 0 ; } void swap (int & x, int & y) { int temp; temp = x; x = y; y = temp; return ; }
引用作为函数返回值 此处不做更多介绍,学习完指针后遇到再学习。感兴趣的可以提前自行查阅文章
基本输入输出 常用输入输出 标准输入流 引入标准库#include <iostream>
该文件定义了如下常用对象,对应关系如下:
流对象
作用
缓冲
示例
cin
标准输入流(从键盘读取数据)
有缓冲
std::cin >> x;
cout
标准输出流(向控制台打印)
有缓冲
std::cout << “Hello”;
cerr
标准错误流(输出错误信息)
无缓冲(实时输出)
std::cerr << “Error!”;
clog
标准日志流(输出日志信息)
有缓冲(不会实时输出)
std::clog << “Logging…”;
有缓冲(Buffered) 和 无缓冲(Unbuffered) 的主要区别在于 数据何时被写入目标(如屏幕或文件)。
有缓冲(Buffered) 数据会先存入缓冲区,等到缓冲区满了或者遇到刷新操作时,才真正输出到目标设备(如屏幕、文件等)。 提高性能,减少 I/O 操作的次数,提高程序效率。 适用于一般输出,如 std::cout 和 std::clog。
无缓冲(Unbuffered) 数据直接输出到目标设备,不会存入缓冲区,每次调用都立刻生效。 适用于紧急信息输出,如 std::cerr(用于错误信息)。 可能会 降低性能,因为每次调用 cerr 都会触发 I/O 操作。
流状态检查: 可以检查输入输出流状态,以确定操作是否成功。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream> int main () { int num; std::cout << "Enter a number: " ; std::cin >> num; if (std::cin.fail ()) { std::cerr << "Invalid input!" << std::endl; } else { std::cout << "You entered: " << num << std::endl; } return 0 ; }
格式化输入输出 引入标注库:#include <iomanip>
常用: 使用std::getline
函数可以读取包含空格的整行输入。
1 2 3 4 5 6 7 8 9 10 11 #include <iostream> #include <string> int main () { std::string fullName; std::cout << "Enter your full name: " ; std::getline (std::cin, fullName); std::cout << "Hello, " << fullName << "!" << std::endl; return 0 ; }
使用std::setprecision
设置输出精度 使用std::setw
设置输出宽度 使用std::left
/std::right
设置对其方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> #include <iomanip> int main () { double pi = 3.14159 ; std::cout << std::setprecision (3 ) << pi << std::endl; std::cout << std::setw (10 ) << std::left << pi << std::endl; std::cout << std::setw (10 ) << std::right << pi << std::endl; return 0 ; }
其他扩展,用到现学,不在此处介绍,感兴趣自行学习,参考文档
文件输入输出 引入标注库:#include <fstream>
基本代码结构如下:
1 2 3 4 5 6 7 8 9 #include <fstream> int main() { std::fstream file; // 创建fstream对象 file.open("filename", mode); // 打开文件, mode为打开模式,详情见下方表格 // 进行文件操作 file.close(); // 关闭文件 return 0; }
mode
描述
std::ios::in
以输入模式打开文件。(读取文件)
std::ios::out
以输出模式打开文件。(写入文件)
std::ios::app
以追加模式打开文件。(追加写入文件)
std::ios::ate
打开文件并定位到文件末尾。
std::ios::trunc
打开文件并截断文件,即清空文件内容。
创建文件 实例: 在当前目录下创建一个名为example.txt
的文件,文件内容为: Hello, World!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <fstream> #include <iostream> int main () { std::fstream file; file.open ("example.txt" , std::ios::out); if (!file) { std::cerr << "Unable to open file!" << std::endl; return 1 ; } file << "Hello, World!" << std::endl; file.close (); return 0 ; }
读取文件 实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <fstream> #include <iostream> #include <string> int main () { std::fstream file; file.open ("example.txt" , std::ios::in); if (!file) { std::cerr << "Unable to open file!" << std::endl; return 1 ; } std::string line; while (getline (file, line)) { std::cout << line << std::endl; } file.close (); return 0 ; }
追加文本内容 实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <fstream> #include <iostream> int main () { std::fstream file; file.open ("example.txt" , std::ios::app); if (!file) { std::cerr << "Unable to open file!" << std::endl; return 1 ; } file << "我是追加的文本." << std::endl; file.close (); return 0 ; }
vector容器 引入标准库#include <vector>
描述:P.S.:可以简单理解为,差不多类似python的列表,c/c++数组的升级版
C++ 中的 vector 是一种序列容器,它允许你在运行时动态地插入和删除元素。 vector 是基于数组的数据结构,但它可以自动管理内存,这意味着你不需要手动分配和释放内存。 与 C++ 数组相比,vector 具有更多的灵活性和功能,使其成为 C++ 中常用的数据结构之一。 vector 是 C++ 标准模板库(STL)的一部分,提供了灵活的接口和高效的操作。
基本特性: 动态大小:vector 的大小可以根据需要自动增长和缩小。 连续存储:vector 中的元素在内存中是连续存储的,这使得访问元素非常快速。 可迭代:vector 可以被迭代,你可以使用循环(如 for 循环)来访问它的元素。 元素类型:vector 可以存储任何类型的元素,包括内置类型、对象、指针等。
使用场景: 当你需要一个可以动态增长和缩小的数组时。 当你需要频繁地在序列的末尾添加或移除元素时。 当你需要一个可以高效随机访问元素的容器时。
vector相关操作 创建:
1 2 3 4 5 6 7 8 9 std::vector<int > myVector; vector<vector<int >> outer; std::vector<int > myVector (5 ) ; std::vector<int > myVector (5 , 10 ) ; std::vector<int > vec2 = {1 , 2 , 3 , 4 };
操作/访问:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 myVector.push_back (7 ); int x = myVector[0 ]; int y = myVector.at (1 ); int size = myVector.size (); for (auto it = myVector.begin (); it != myVector.end (); ++it) { std::cout << *it << " " ; } for (int element : myVector) { std::cout << element << " " ; } myVector.erase (myVector.begin () + 2 ); myVector.clear ();
使用下标访问myVector[0];
和使用at访问myVector.at(0);
的比较:
operator[](下标访问) 直接访问 vector 的元素,不进行边界检查。 如果索引超出范围,程序不一定报错行为随机(Undefined Behavior, UB),可能导致程序崩溃或访问无效内存。 性能稍快,因为没有额外的边界检查。
at() 方法 带边界检查,如果索引超出范围,会抛出 std::out_of_range 异常,防止访问非法内存。 更安全,但会略微降低性能,因为有额外的检查开销。
at搭配try-catch进行异常处理的实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> #include <vector> int main () { std::vector<int > myVector = { 10 , 20 , 30 }; int x = myVector.at (0 ); std::cout << "x = " << x << std::endl; try { int y = myVector.at (5 ); std::cout << "y = " << y << std::endl; } catch (const std::out_of_range& e) { std::cout << "异常捕获: " << e.what () << std::endl; } return 0 ; }
P.S.异常捕获-补充知识 异常捕获: 引入标准库#include <exception>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <vector> #include <exception> int main () { std::vector<int > myVector = { 10 , 20 , 30 }; int x = myVector.at (0 ); std::cout << "x = " << x << std::endl; try { int y = myVector.at (5 ); std::cout << "y = " << y << std::endl; } catch (const std::out_of_range& e) { std::cout << "越界异常捕获: " << e.what () << std::endl; } catch (const std::exception& e) { std::cout << "标准异常:" << e.what () << std::endl; } catch (...) { std::cout << "未知异常,无e实例" << std::endl; } return 0 ; }
方式
捕获类型
是否能获取异常信息
适用场景
catch (const std::exception& e)
标准异常(如 std::runtime_error)
✅ e.what() 获取详细信息
处理标准库异常
catch (…)
所有异常(包括非标准)
❌ 无法获取信息
兜底异常处理,防止程序崩溃
推荐做法
先 catch (std::exception&),再 catch (…)
✅ 既能获取信息,又能兜底
最佳实践