C++中使用指针为二维数组赋值生成10×10乘法表求助
用指针操作二维数组实现乘法表(替代索引方式)
嘿,我来帮你把这段用索引写的乘法表代码改成纯指针操作的版本,顺便给你掰扯清楚二维数组和指针的关系,保证新手也能看懂~
首先先提个小细节:你原代码里的数组定义是int matrix[10][11],但循环里i和j从0到10,赋值时用matrix[i-1][j-1],当i=0或j=0时会触发数组越界(访问matrix[-1][...]),这是未定义行为哦,后面的指针版本我会帮你修正这个问题。
先搞懂:C++里二维数组的内存布局
C++中的二维数组在内存里是连续存储的,比如int matrix[10][10],其实是把10个长度为10的一维数组挨在一起放的,没有空隙。这是我们用指针操作的核心依据。
另外,你平时用的matrix[i][j],编译器其实会偷偷转换成指针运算:*(*(matrix + i) + j)——本质上就是指针操作,只是编译器帮你做了计算而已。
方式一:用单指针遍历整个连续内存
这种方式最简单,把二维数组当成一个长的一维数组来处理,用一个普通的int*指针从头走到尾。
代码示例
#include <iostream> using namespace std; int main(void) { int matrix[10][10] = {}; // 10x10数组,刚好存1-10的乘积 int* ptr = &matrix[0][0]; // 指针指向数组第一个元素 // 填充乘法表:i从1到10,j从1到10 for(int i = 1; i <= 10; i++) { for(int j = 1; j <= 10; j++) { *ptr = i * j; // 给指针指向的位置赋值 ptr++; // 指针移动到下一个元素(int*每次+1跳4字节,正好到下一个int) } } // 打印乘法表,先把指针重置回数组开头 ptr = &matrix[0][0]; for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { cout.width(4); cout << *ptr; // 读取指针指向的元素 ptr++; } cout << endl; } return 0; }
关键知识点
&matrix[0][0]:取数组第一个元素的地址,赋值给int*类型的指针ptr。*ptr:解引用指针,访问或修改指针指向的内存位置。ptr++:因为是int*指针,每次自增会移动sizeof(int)个字节,正好跳到下一个元素的位置——不管是同一行的下一个,还是下一行的第一个,因为二维数组内存是连续的。
方式二:用指向一维数组的指针(更贴合二维数组逻辑)
如果你想更清晰地体现“行+列”的二维结构,可以用指向一维数组的指针,这种方式更贴近二维数组的设计逻辑。
代码示例
#include <iostream> using namespace std; int main(void) { int matrix[10][10] = {}; // row_ptr是指向"包含10个int的数组"的指针,初始指向第一行 int (*row_ptr)[10] = matrix; // 填充乘法表 for(int i = 1; i <= 10; i++) { int* col_ptr = *row_ptr; // 拿到当前行第一个元素的指针 for(int j = 1; j <= 10; j++) { *col_ptr = i * j; col_ptr++; // 在当前行内移动,访问下一列 } row_ptr++; // 移动到下一行 } // 打印乘法表,重置指针到第一行 row_ptr = matrix; for(int i = 0; i < 10; i++) { int* col_ptr = *row_ptr; for(int j = 0; j < 10; j++) { cout.width(4); cout << *col_ptr; col_ptr++; } cout << endl; row_ptr++; } return 0; }
关键知识点
int (*row_ptr)[10]:这是一个指向包含10个int的数组的指针,括号不能少!如果写成int* row_ptr[10],那就是一个“存放10个int*指针的数组”,完全不是一回事。row_ptr = matrix:数组名matrix会隐式转换成指向第一行的指针,正好匹配row_ptr的类型。*row_ptr:解引用row_ptr,得到当前行的数组名,而数组名又会隐式转换成指向该行第一个元素的int*指针,赋值给col_ptr。row_ptr++:因为row_ptr指向的是10个int的数组,所以自增会移动10*sizeof(int)个字节,正好跳到下一行的开头。
新手避坑:别用int**指向二维数组
很多新手会以为二维数组可以用int**(二级指针)来指向,但这是错的!
int**是指向“指针的指针”,通常用于动态分配的二维数组(比如int** arr = new int*[10];),而静态二维数组在内存里是连续的,和动态分配的“指针数组+一维数组”结构完全不同,所以类型不匹配,不能直接赋值。
内容的提问来源于stack exchange,提问作者Evelina Tokts
相关产品推荐
相关产品推荐

