C++ 指针数组
什么是指针数组?
指针数组是一个存储指针的数组。在C++中,指针数组是一种特殊的数组类型,其每个元素都是指针。这些指针可以指向任何兼容的数据类型,如整数、字符、结构体,甚至是其他数组。
指针数组的定义形式如下:
数据类型 *数组名[数组大小];
这里的数组名表示一个数组,其中每个元素都是指向"数据类型"的指针。
指针数组与数组指针的区别
初学者常常混淆指针数组和数组指针,这两者是完全不同的概念。
- 指针数组:是一个数组,数组元素是指针。
- 例如:
int *ptr[3];
表示一个包含3个整型指针的数组。
- 例如:
- 数组指针:是一个指针,指向一个数组。
- 例如:
int (*ptr)[3];
表示一个指向包含3个整数的数组的指针。
- 例如:
指针数组的声明和初始化
基本声明
int *ptrArray[3]; // 声明一个包含3个整型指针的数组
初始化方法
int a = 10, b = 20, c = 30;
int *ptrArray[3] = {&a, &b, &c}; // 初始化指针数组
指针数组的使用示例
让我们通过一个简单的示例来理解指针数组的使用:
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 20, c = 30;
int *ptrArray[3] = {&a, &b, &c}; // 指针数组
// 通过指针数组访问变量
cout << "通过指针数组访问变量:" << endl;
for (int i = 0; i < 3; i++) {
cout << "ptrArray[" << i << "] 指向的值: " << *ptrArray[i] << endl;
}
// 修改变量的值
*ptrArray[1] = 200;
cout << "\n修改后的b值: " << b << endl;
return 0;
}
输出结果:
通过指针数组访问变量:
ptrArray[0] 指向的值: 10
ptrArray[1] 指向的值: 20
ptrArray[2] 指向的值: 30
修改后的b值: 200
在上面的示例中,我们创建了一个包含3个整型指针的数组,并将它们分别指向变量a、b和c。通过指针数组,我们可以访问和修改这些变量的值。
字符串指针数组
指针数组的一个常见应用是创建字符串数组。在C++中,字符串可以表示为字符数组或字符指针。使用字符指针数组可以方便地管理多个字符串。
#include <iostream>
using namespace std;
int main() {
// 字符串指针数组
const char *strArray[3] = {
"Hello",
"C++",
"Programming"
};
cout << "字符串指针数组中的内容:" << endl;
for (int i = 0; i < 3; i++) {
cout << "strArray[" << i << "]: " << strArray[i] << endl;
}
return 0;
}
输出结果:
字符串指针数组中的内容:
strArray[0]: Hello
strArray[1]: C++
strArray[2]: Programming
使用const char*
是因为字符串字面量在C++中是不可修改的。如果尝试修改这些字符串,会导致未定义的行为。
指针数组与动态内存分配
指针数组可以结合动态内存分配使用,这在处理不确定大小的数据时特别有用。
#include <iostream>
using namespace std;
int main() {
int size = 3;
// 动态分配多个整数并用指针数组管理它们
int *dynamicPtrArray[3];
for (int i = 0; i < size; i++) {
dynamicPtrArray[i] = new int; // 为每个指针分配内存
*dynamicPtrArray[i] = (i + 1) * 10; // 设置值
}
// 输出动态分配的内存中的值
cout << "动态分配的内存中的值:" << endl;
for (int i = 0; i < size; i++) {
cout << "dynamicPtrArray[" << i << "] 指向的值: " << *dynamicPtrArray[i] << endl;
}
// 释放动态分配的内存
for (int i = 0; i < size; i++) {
delete dynamicPtrArray[i];
}
return 0;
}
输出结果:
动态分配的内存中的值:
dynamicPtrArray[0] 指向的值: 10
dynamicPtrArray[1] 指向的值: 20
dynamicPtrArray[2] 指向的值: 30
在使用动态内存分配时,记得释放内存以避免内存泄漏。
指针数组的实际应用场景
1. 命令行参数处理
C++程序的main函数可以接收命令行参数,这些参数通常以字符串指针数组的形式提供:
int main(int argc, char *argv[]) {
cout << "程序名称: " << argv[0] << endl;
cout << "命令行参数:" << endl;
for (int i = 1; i < argc; i++) {
cout << "参数 " << i << ": " << argv[i] << endl;
}
return 0;
}
2. 多态性和虚函数表
在C++面向对象编程中,包含虚函数的类会有一个虚函数表,这个表实际上是一个函数指针数组。
3. 数据表格管理
指针数组可以用于管理二维数据结构,特别是当行有不同长度时:
#include <iostream>
using namespace std;
int main() {
// 创建不同长度的行
int row1[] = {1, 2, 3};
int row2[] = {4, 5};
int row3[] = {6, 7, 8, 9};
// 使用指针数组管理这些行
int *table[3] = {row1, row2, row3};
int rowLengths[3] = {3, 2, 4};
// 输出表格数据
cout << "表格数据:" << endl;
for (int i = 0; i < 3; i++) {
cout << "行 " << i + 1 << ": ";
for (int j = 0; j < rowLengths[i]; j++) {
cout << table[i][j] << " ";
}
cout << endl;
}
return 0;
}
输出结果:
表格数据:
行 1: 1 2 3
行 2: 4 5
行 3: 6 7 8 9
指针数组的结构可视化
以下是指针数组的内存结构示意图:
总结
指针数组是C++中一个强大而灵活的工具,它允许我们以数组的形式组织和管理多个指针。主要要点包括:
- 指针数组是一个数组,其元素是指针
- 区分指针数组和数组指针很重要
- 指针数组常用于管理字符串、动态分配的内存以及不规则数据结构
- 使用动态内存时要记得释放内存以避免泄漏
掌握指针数组的概念和用法,可以帮助你更有效地组织和管理复杂的数据结构,尤其是在需要处理不定长数据或多级数据时。
练习
-
创建一个整型指针数组,使其指向5个不同的整数变量,然后通过指针数组修改这些变量的值。
-
实现一个函数,接受一个字符串指针数组和数组大小作为参数,按字母顺序排序这些字符串。
-
创建一个指向动态分配的二维整数数组的指针数组,实现一个简单的矩阵乘法。
-
设计一个学生成绩管理系统,使用指针数组来存储不同学生的不同科目成绩。
附加资源
- 《C++ Primer》第五版 - 关于指针和数组的章节提供了更深入的解释
- cppreference.com - C++标准库参考
- GeeksforGeeks - C++ Pointers - 更多关于C++指针的教程和练习
通过学习和实践,你将能够熟练掌握指针数组这一重要的C++编程概念,并在更复杂的项目中有效地应用它。