能否在C语言中通过指针变量实现二维数组的用户输入?
使用指针实现二维数组的用户输入
当然可以用指针配合scanf完成二维数组的输入,但你当前的代码存在两个关键错误,导致无法正确工作甚至引发未定义行为:
原代码的问题
指针初始化越界:
int *ptr1 = &arr1[3][3];是错误的。arr1[3][3]超出了arr1[3][3]数组的合法索引范围(数组行和列的索引都是0-2),这个指针指向的是数组末尾之后的未知内存区域,写入这里的数据会破坏其他内存,导致程序异常。地址计算逻辑错误:
二维数组在内存中是行优先连续存储的,3x3数组里,第row行第column列的元素,相对于数组起始地址的偏移量应该是row * 3 + column(每行有3个int元素)。你写的(ptr1 + row) + column只会计算连续的row+column个元素偏移,无法正确定位到后续行的元素。
修正后的代码
写法1:用偏移量计算地址
#include <stdio.h> int main(void) { int arr1[3][3]; // 让指针指向数组的第一个元素(合法起始地址) int *ptr1 = &arr1[0][0]; for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { // 计算正确的元素地址:起始地址 + 行偏移*每行元素数 + 列偏移 scanf("%d", ptr1 + row * 3 + column); } } // 验证输入结果的输出示例 for (int row = 0; row < 3; row++) { for (int column = 0; column < 3; column++) { printf("%d ", *(ptr1 + row * 3 + column)); } printf("\n"); } return 0; }
写法2:指针递增方式(更简洁)
既然数组是连续存储的,也可以不用嵌套循环的行列计算,直接用单循环让指针逐个递增:
#include <stdio.h> int main(void) { int arr1[3][3]; int *ptr1 = &arr1[0][0]; // 遍历9个元素 for (int i = 0; i < 9; i++) { scanf("%d", ptr1++); } // 验证输入结果的输出示例 ptr1 = &arr1[0][0]; // 重置指针到起始位置 for (int i = 0; i < 9; i++) { printf("%d ", *ptr1++); if ((i+1) % 3 == 0) printf("\n"); } return 0; }
和你提到的写法的关联
你说的scanf("%d", (*(arr1 + i) + j))本质和指针方式是等价的:
arr1是数组名,会退化为指向第一行的指针(类型为int (*)[3]),arr1 + i指向第i行的起始地址;*(arr1 + i)解引用后得到第i行的数组名,再次退化为指向第i行第一个元素的指针(类型为int*),加j就得到第i行第j列元素的地址;- 这个地址和
ptr1 + i*3 + j是完全相同的。
内容的提问来源于stack exchange,提问作者Asif Mahbub
相关产品推荐
相关产品推荐

