You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:59:22