使用指向2D数组行的指针来初始化其值.为什么会这样呢?

Use a pointer to the rows of 2D array to initialize its values. Why does this work?

本文关键字:为什么 初始化 2D 数组 指针      更新时间:2023-10-16

我声明了一个数组square[10][10],我想初始化它只包含1。(我已经使用普通初始化器将其声明为全零,但这只是为了在调试时打印它时数组不会充满垃圾)。我可以很容易地用双for循环初始化,但我试图使用一个指向square行的指针数组。这是我的代码。

#include <iostream>
using namespace std;
void initToOnes(int (*row)[10]) {
    for (int *rowp = row[0]; rowp != row[0] + 100; rowp += 10) {
        for (int *cs = rowp; cs != rowp + 10; ++cs)
            *cs = 1;
    }
}
int main()
{
    int square[10][10] = {0};
    int (*row)[10] = square;
    initToOnes(row);
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++)
            cout << square[i][j] << ' ';
        cout << 'n';
    }
}

现在这个工作,虽然我不完全确定为什么。函数initToOnes接受一个指向10个int型块的指针。那么,在函数的外部for循环中,rowp++不应该足以增加指针指向第二行整数吗?换句话说,我可以将相同的函数强制转换为double for循环,如下所示:

for (pointer rowp; rowp != row + 10; ++rowp){
    // inner loop;
}

这个函数现在的工作方式似乎有点违背了拥有指向某些行的指针的意义。这样(我猜)我可以将指针发送到square中的第一个条目,并在外部for循环中增加10以运行在行。这种实现是否很差,并且无法定义指向行的指针?谢谢!

编辑:评论和回答澄清了困惑。我将rowp声明为指向int型的指针,因此++rowp当然只是指向下一个int型而不是下一行。这是我更新的解决方案
#include <iostream>
using namespace std;
void initToOnes(int (*row)[10]) {
    for (int (*rowp)[10] = row; rowp != row + 10; ++rowp) {
        for (int *cs = *rowp; cs != *rowp + 10; ++cs)
            *cs = 1;
    }
}
int main()
{
    int square[10][10] = {0};
    int (*row)[10] = &square[0];
    initToOnes(row);
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++)
            cout << square[i][j] << ' ';
        cout << 'n';
    }
}

在外部循环中,循环变量为

int *rowp;

这意味着增加它将增加rowp指向下一个整数。

故事到此结束。句号。

事实上,rowp指向的内存区域在逻辑上被划分为一系列的块,每10个int s,这并不能改变rowp是一个指向int的指针,而不是一个包含10个int s的数组这一基本事实。

现在,如果你想对一个指向10的指针做点什么,int s:

int array[10][10];
int (*p)[10] = &array[0];

现在,你可以说服自己,增加p将使它向前移动10个int。如何改进循环以使用这样的指针应该是显而易见的。实际上,您已经将正确的变量作为参数传入。使用它。