跳到主要内容 C++ 期末复习核心知识点总结 | 极客日志
C++ 算法
C++ 期末复习核心知识点总结 本文整理了 C++ 期末复习的核心知识点,涵盖指针运算、静态变量特性、数组操作、字符串处理、内存生命周期及类对象构造等基础概念。内容包括二维数组指针访问、复制构造函数调用时机、插入排序与二分查找算法实现、以及常见语法陷阱分析。旨在帮助学习者巩固 C++ 基础语法与面向对象编程原理,适用于课程复习与考试准备。
猫巷少女 发布于 2026/3/29 更新于 2026/4/14 2 浏览1. 指针
#include <iostream>
using namespace std;
int sum (int ar2[][4 ], int size) {
int total = 0 ;
for (int r = 0 ; r < size; r++) {
for (int c = 0 ; c < 4 ; c++)
total += ar2[r][c];
}
return total;
}
int main () {
int arr[3 ][4 ] = {{1 , 2 , 3 , 4 }, {5 , 6 , 7 , 8 }, {9 , 10 , 11 , 12 }};
int total = sum (arr, 3 );
cout << total << endl;
cout << "arr[0][0] 的地址:" << arr << endl;
cout << "arr[1][0] 的地址:" << arr + 1 << endl;
cout << "arr[1][0] 的值:" << *(*(arr + 1 )) << endl;
cout << "arr[1][2] 的值:" << *(*(arr + 1 ) + 2 ) << endl;
cout << << *(arr + ) + << endl;
a[] = { , , , , , , , , , };
*p = a, *q = a;
cout << << p << << << p + << endl;
cout << << a << << << a + << endl;
cout << << &p[ ] << << << &p[ ] << endl;
cout << << &a[ ] << << << &a[ ] << endl;
cout << << endl;
cout << << *p << << << *(p + ) << endl;
cout << << *a << << << *(a + ) << endl;
;
}
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown 转 HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
HTML 转 Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
"arr[1][2] 的地址:"
1
2
int
1
2
3
4
5
6
7
8
9
0
int
"方法一:p(+i) 首元素地址"
'\t'
"p[2] 的地址"
2
"方法二:a(+i) 首元素地址"
'\t'
"p[2] 的地址"
2
"方法三:&p[] 首元素地址"
0
'\t'
"p[2] 的地址"
2
"方法四:&a[] 首元素地址"
0
'\t'
"p[2] 的地址"
2
"结论:a 与 p 完全等价"
"方法一:*(p+i) 首元素的值"
'\t'
"a[2] 的值"
2
"方法二:*(a+i) 首元素的值"
'\t'
"a[2] 的值"
2
return
0
2. static 关键字 #include <iostream>
using namespace std;
int fun () {
static int i = 0 ;
int s = 1 ;
s += i;
i++;
return s;
}
int main () {
int i, a = 0 ;
for (i = 0 ; i < 5 ; i++) {
a += fun ();
}
cout << a << endl;
return 0 ;
}
在程序中,static 关键字修饰了函数 fun() 中的局部变量 i,使其成为静态局部变量 ,具有以下关键特性:
1. 延长生命周期
普通局部变量 :在函数调用时创建,函数返回时销毁。
静态局部变量 :在程序开始运行时分配内存,直到程序结束才销毁(生命周期与全局变量相同)。
2. 保持值的持久性
变量 i 的值在函数调用之间保持不变:
第一次调用 fun() 时,i 被初始化为 0。
后续每次调用 fun() 时,i 都保留上一次调用结束时的值。
初始化 =0 只执行一次。
3. 作用域仍局限于函数内
尽管生命周期是全局的,但 i 的作用域仍然只在 fun() 函数内部,外部代码无法直接访问它。
3. 循环变量作用域 #include <iostream>
using namespace std;
void f (float *p, float &b, int n) {
int l;
for (l = 0 ; l < n; l++)
b += *p++;
b /= l;
}
const int N = 6 ;
int main () {
int l;
float a[N] = {1 , 2 , 3 , 4 , 5 };
float c = 0 ;
f (a, c, N);
cout << c << endl;
return 0 ;
}
4. 复制构造函数的调用 #include <iostream>
using namespace std;
class MyClass {
public :
MyClass (int n) { number = n; }
MyClass (MyClass &other) {
number = other.number;
cout << "调用了复制构造函数" << endl;
}
~MyClass () {}
private :
int number;
};
MyClass fun (MyClass p) {
MyClass temp (p) ;
return temp;
}
int main () {
MyClass obj1 (10 ) , obj2 (0 ) ;
MyClass obj3 (obj1) ;
obj2 = fun (obj3);
return 0 ;
}
详细分析:
MyClass obj3(obj1);:用 obj1 初始化 obj3,调用 1 次复制构造函数。
函数调用 fun(obj3) 时的参数传递:形参 p 通过值传递的方式用 obj3 初始化,调用 1 次复制构造函数。
fun 函数内部定义 temp 对象:MyClass temp(p); 用 p 初始化 temp,调用 1 次复制构造函数。
fun 函数返回 temp 对象:返回 temp 时,编译器生成临时对象,调用 1 次复制构造函数(假设无编译器优化)。
注意 :赋值操作 obj2 = fun(obj3); 使用默认的赋值运算符,不调用复制构造函数。第 4 次复制构造函数的调用发生在函数返回创建临时对象时。
5. 在有序数组中插入一个数 #include <iostream>
using namespace std;
int main () {
int a[10 ] = {10 , 20 , 30 , 40 , 50 , 60 , 70 , 80 , 90 , 100 };
int n;
cin >> n;
int j = 9 ;
while (j >= 0 && n < a[j]) {
a[j + 1 ] = a[j];
j--;
}
a[j + 1 ] = n;
for (int i = 0 ; i < 11 ; i++)
cout << a[i] << ' ' ;
cout << endl;
return 0 ;
}
6. 算式填空问题 #include <iostream>
using namespace std;
int main () {
int ei;
cin >> ei;
int x[3 ];
int c[10 ] = {0 };
int r;
int s = 0 ;
int tx = 0 , ty = 0 ;
int i, t;
for (x[0 ] = 102 ; x[0 ] <= 493 ; x[0 ]++)
for (x[1 ] = x[0 ] + 1 ; x[1 ] <= 987 - x[0 ]; x[1 ]++) {
x[2 ] = x[0 ] + x[1 ];
for (i = 0 ; i < 3 ; i++) {
t = x[i];
do {
c[t % 10 ] = 1 ;
t /= 10 ;
} while (t != 0 );
}
r = 0 ;
for (i = 0 ; i < 10 ; i++) r += c[i], c[i] = 0 ;
if (r == 9 ) {
s++;
if (s == ei) tx = x[0 ], ty = x[1 ];
}
}
cout << "一共有" << s << "个式子" << endl;
if (ei <= s)
cout << ei << "-th:" << tx << "+" << ty << "=" << tx + ty << endl;
else
cout << "no exist!" << endl;
return 0 ;
}
7. 字符串子串查找 #include <iostream>
using namespace std;
int main () {
char s1[100 ];
char s2[100 ];
cin >> s1;
cin >> s2;
int len1 = 0 , len2 = 0 ;
while (s1[len1] != '\0' ) len1++;
while (s2[len2] != '\0' ) len2++;
bool found = false ;
if (len2 <= len1) {
int i = 0 ;
while (i < len1 - len2) {
int j = 0 ;
bool match = true ;
while (j < len2) {
if (s1[i + j] != s2[j]) {
match = false ;
break ;
}
j++;
}
if (match) {
cout << i << ' ' ;
found = true ;
i += len2;
} else {
i++;
}
}
}
if (!found) {
cout << -1 << endl;
} else {
cout << endl;
}
return 0 ;
}
8. 用指针访问二维数组
(1)通过函数 #include <iostream>
using namespace std;
void printArray (int (*arr)[4 ], int rows) {
for (int i = 0 ; i < rows; i++) {
for (int j = 0 ; j < 4 ; j++) {
cout << arr[i][j] << " " ;
}
cout << endl;
}
}
int main () {
int arr[3 ][4 ] = {{1 , 2 , 3 , 4 }, {5 , 6 , 7 , 8 }, {9 , 10 , 11 , 12 }};
printArray (arr, 3 );
return 0 ;
}
(2)使用数组指针 #include <iostream>
using namespace std;
int main () {
int arr[3 ][4 ] = {{1 , 2 , 3 , 4 }, {5 , 6 , 7 , 8 }, {9 , 10 , 11 , 12 }};
int *p = &arr[0 ][0 ];
for (int i = 0 ; i < 3 ; i++) {
for (int j = 0 ; j < 4 ; j++) {
cout << *(p + i * 4 + j) << " " ;
}
cout << endl;
}
return 0 ;
}
(3)数组指针 #include <iostream>
using namespace std;
int main () {
int arr[3 ][4 ] = {{1 , 2 , 3 , 4 }, {5 , 6 , 7 , 8 }, {9 , 10 , 11 , 12 }};
int (*p)[4 ] = arr;
for (int i = 0 ; i < 3 ; i++) {
for (int j = 0 ; j < 4 ; j++) {
cout << p[i][j] << " " ;
}
cout << endl;
}
return 0 ;
}
*C++ 中,a[i] 相当于 (a+i),a[i][j] 相当于 ( (a+i)+j)
9. 字符串处理函数
10. 查找算法(二分查找) #include <iostream>
using namespace std;
int main () {
int array[] = {2 , 5 , 7 , 8 , 9 , 11 , 23 , 26 , 32 , 37 };
int high, low, mid, a;
low = 0 ;
high = 9 ;
cin >> a;
mid = (low + high) / 2 ;
while (array[mid] != a && low <= high) {
if (a > array[mid])
low = mid + 1 ;
else
high = mid - 1 ;
mid = (low + high) / 2 ;
}
if (array[mid] == a)
cout << "exist:" << mid + 1 << endl;
else
cout << "no exist" << endl;
return 0 ;
}
11. 排序算法(冒泡排序) #include <iostream>
using namespace std;
int main () {
int array[10 ] = {9 , 7 , 8 , 5 , 10 , 4 , 6 , 2 , 1 , 3 };
for (int i = 0 ; i < 10 ; i++) {
for (int j = 0 ; j < 10 - i - 1 ; j++) {
if (array[j] > array[j + 1 ]) {
int temp = array[j];
array[j] = array[j + 1 ];
array[j + 1 ] = temp;
}
}
}
for (int i = 0 ; i < 10 ; i++)
cout << array[i] << ' ' ;
cout << endl;
return 0 ;
}
12. 变量的生存期
内存分区 :
数据区 :
动态数据区(栈区) :变量离开作用域,生存期终止;数据如果没有给出初始值,为随机值。
静态数据区 :和程序一样长的生存期,一直占用内存空间。全局变量与静态变量储存在此处。数据如果没有给出初始值,自动初始化为 0。
代码区
如果一个变量结束了其生存期,那么该变量就离开了其作用域。
如果一个变量结束了其作用域,那么该变量不一定就结束了生存期。
用 static 声明局部变量:分配在静态数据区。
用 extern 声明全局变量。
13. 复制构造函数调用的三个情境
(1)初始化
(2)函数的形参为对象时 系统创建临时形参对象,并将实参对象的值赋值给形参对象(系统自动调用)。
void fun1 (MyClass c1) { c1. showTime (); }
fun1 (Beijing);
(3)当函数返回值的是对象时 MyClass fun2 () {
MyClass A (13 , 0 , 0 ) ;
return A;
}
MyClass Munich;
Munich = fun2 ();
14. 空指针错误分析 #include <iostream>
using namespace std;
int main () {
char *p = 0 ;
*p = 'a' ;
cout << *p;
return 0 ;
}
这个程序存在严重的运行时错误 ,会导致程序崩溃 (通常是段错误 Segmentation Fault)。
程序问题分析
char *p = 0;:将指针 p 初始化为空指针(nullptr/NULL)。这意味着 p 不指向任何有效的内存地址。
*p = 'a';:尝试解引用空指针并写入字符 'a'。这是未定义行为 。操作系统会阻止程序访问地址 0 的内存,导致段错误。
cout << *p;:即使能执行到这里,也是解引用空指针读取数据,同样会导致段错误。
15. 类和对象构造次数
构造函数可以重载,析构函数不可以 。
对象定义 :
class A {
};
A a, b (3 ), c[4 ], *p;
调用了多少次构造函数?
6 次 !a (1) + b (1) + c[0~3] (4)。*p 只是指针,不调用构造函数。
A* a = new A[5 ];
5 次 !
A* a = new A;
1 次 !(与 *p 做区分)