C语言中的2D数组和指针-如何访问元素?

C语言中的2D数组和指针-如何访问元素?,c,pointers,C,Pointers,我有一个例子,涉及指向2D数组的指针。有人能帮我理解这个例子中发生了什么吗 int main() { int i = 0, j=0, sum0=0, sum1=0; int data[4][3] = { {23,55,50},{45,38,55},{70,43,45},{34,46,60}}; int *Ptr; Ptr = *data; //Why is the indirection operator used here?

我有一个例子,涉及指向2D数组的指针。有人能帮我理解这个例子中发生了什么吗

int main()
{

    int i = 0, j=0, sum0=0, sum1=0;
    int data[4][3] = { {23,55,50},{45,38,55},{70,43,45},{34,46,60}};
    int *Ptr;
    Ptr = *data;    //Why is the indirection operator used here? 
                    // Does Ptr = 23 by this assignment?

    for (i=0; i<4; i++) {
        sum1 = 0;
        for (j = 0; j < 3; j++) {
            sum1 += data[i][j];
        }
        if (sum1 > sum0) {
                 sum0 = sum1;
                 Ptr = *(data + i);     // Seems like this statement makes Ptr
        }                               // point one row below ... what syntax
    }                                   // can you use to access columns then?
                                       // Is it possible to use pointer arithmetic
    for (i=0; i<3; i++)                 // to access elements of data[i][j] that
        printf("%d\n", Ptr[i]);          // are not at j = 0?

  return 0;
}
intmain()
{
int i=0,j=0,sum0=0,sum1=0;
int data[4][3]={{23,55,50}、{45,38,55}、{70,43,45}、{34,46,60};
int*Ptr;
Ptr=*data;//为什么这里使用间接运算符?
//Ptr=23是否受此任务影响?
对于(i=0;i sum0){
sum0=sum1;
Ptr=*(data+i);//似乎这个语句使Ptr
}//指向下面的一行……什么语法
}//那么您可以使用访问列吗?
//可以使用指针算法吗

for(i=0;i
data
是一个由3个元素组成的整数数组。在需要“指向foo的指针”的上下文中,可以使用“foo数组”,它的行为类似于指向其第一个元素的指针,因此
*data
是指向
data
的第一个元素的指针,即(可以说)
{23,55,50}

因此,评论中第一个问题的答案是:
Ptr=23
(不可能;
Ptr
是一个
int*
,而23是一个
int

你是正确的,
Ptr=*(data+i)
使
Ptr
指向
i
data
。更准确地说,
data
是一个int的三元素数组,它的行为类似于指向int的三元素数组的指针;向它添加
i
将移动到
i
这样的数组


访问数组其他列的常用方法是普通数组索引。如果您引用
数据[i][j]
,您将获得行
i
j
。如果您想使用显式指针算法,请注意(例如,
Ptr
示例代码中的类型为“指向整数的指针”,因此
Ptr+1
(例如)是
Ptr
所指向的任何行的元素1。(但是,作为一种风格,通常不应该在实际上不需要的情况下执行显式指针算法。)

在您的示例中,循环遍历所有矩阵行,以找到所有元素之和都保持最大值的行

开始时,将指定指向第一行的指针:

Ptr = *data;
这意味着以下是正确的:

(Ptr[0] == 23 && Ptr[1] == 55 && Ptr[2] == 50)

请注意,Ptr是一个指针,因此它持有一个内存地址,因此Ptr不同于23(除非内存地址恰好是23,这是不太可能发生的)。

数据
是一个二维数组,它有4行,每行有3个元素(即4 X 3)

现在,
Ptr=*data;
表示您正在将第一行的起始地址存储到指针变量
Ptr
。此语句相当于
Ptr=*(data+0)
Ptr=*(data+1)
-表示我们正在分配第二行的起始地址

然后,
*Ptr
*(Ptr+0)
将给出所指向行的第一个元素的值。类似地,
*(Ptr+1)
将给出该行的第二个元素的值

程序中的
for
循环用于标识哪个行的元素总和(3个元素)最大。一旦控件从
for
循环中出来,
Ptr
将指向元素总和最大的行,并且
sum0
将具有总和的值

考虑数组
inta[5];
,我希望你知道
a[0]
0[a]
是相同的。这是因为
a[0]
意味着
*(a+0)
0[a]
意味着
*(0+a)
可以在二维数组中使用相同的逻辑

data[i][j]
类似于
*(*(data+i)+j)
。我们也可以将其写成
i[data][j]


有关更多详细信息,请参阅Yashavant Kanetkar的《理解C中的指针》一书。

Ptr=*data;
*(data+0)+0的缩写,它是第一行第一列元素的指针。添加数据的前0是行号,它是间接的,将我们带到第一行。
*(data+0)
仍然是一个地址,而不是它所指向的值(对于2D数组)。因此,Ptr现在指向第一行中第一列的地址。第二个零是列号。因此,选择了第一行和第一列的内存地址。再次使用间接(*)只会给出地址保持的值。如
*(*(数据+0)+0)
**数据

通常,如果p是指针名称,i行编号和j列编号

  • (*(p+i)+j)
    将给出二维数组中元素的内存地址。i是行号,j是列号
  • *(*(p+i)+j)
    将给出该元素的值
  • *(p+i)
    将访问第i行
  • 若要访问列,请将列号添加到
    *(p+i)
    。您可能需要将指针声明为
    (*p)[columns]
    ,而不仅仅是
    *p
    。这样做,您就声明了指向二维数组的指针

  • 使用指针算法将2d数组视为1D数组。将指针*Ptr初始化为第一个元素(
    int*Ptr=*data
    ),然后添加一个编号(
    Ptr+n
    )访问列。添加一个比列号高的数字将继续计算下一行第一列中的元素(如果存在)。

    C允许多维数组,将它们作为连续位置放置在内存中,并执行更多的幕后地址算法。 考虑一个二维数组。

    int arr[3][3]={{1,2,3},{4,5,6},{7,8,9}

    编译器将二维数组视为数组数组。 数组在哪里