2012-06-24 79 views
5

我有一个例子涉及到一个二维数组的指针。有人能帮我理解这个例子里发生了什么吗?二维数组和C中的指针 - 如何访问元素?

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; 
} 
+0

这是[标签:家庭作业]? – Alexander

+0

是!我正在参加CS介绍课程,这仅仅是我的讲义中给出的一个例子。 – shafools

回答

13

data是一个2维数组,它有4行,每行有3个元素(即4 X 3)。

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

然后*Ptr*(Ptr + 0)会给你行指向的第一个元素的值。同样,*(Ptr + 1)会为您提供该行第二个元素的值。

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

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

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

欲了解更多详细信息,请参见本书“在C理解指针”通过亚什万特kanetkar。

1

data是一个3元素整数数组的数组。在需要“指向foo的指针”的上下文中,可以使用“foo数组”,它的行为就像指向其第一个元素的指针,所以*data是指向第一个元素data的指针,也就是说(可以这么说) {23,55,50}

那么,回答第一个问题的意见是:不,那是不正确的,Ptr = 23。 (这可能不是; Ptrint *和23是int。)

你是正确Ptr = *(data+i)使得Ptr点的datai个行。更确切地说,data是一个由3个元素组成的数组的数组,它的行为类似于指向3个元素的int数组的指针;它加入i它移过i这样的阵列。

访问数组其他列的通常方法是普通数组索引。如果您参考data[i][j],您会收到第i行的j列。如果你想用显式指针算术来做,那么请注意,示例代码中的(例如)Ptr是“指向整数的指针”类型,所以Ptr+1(例如)是Ptr指向的任何行的元素1。 (但是,就风格而言,当你不需要时通常不应该进行显式指针算术运算)。

0

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

在一个指针到第一行分配的开始:

Ptr = *data; 

这意味着符合下列条件:

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

注意PTR是一个指针,所以它持有内存地址,因此Ptr不同于(除非内存地址碰巧是,这不太可能发生)。

4

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

一般地,如果p是指针名,第i行号和j列号,

  1. (*(p+i)+j)会给在2D阵列中的元素的存储器地址。我是行号。 j是col编号,
  2. *(*(p+i)+j)将给出该元素的值。
  3. *(p+i)将访问第i行
  4. 访问列,将列号添加到*(p+i)。您可能不得不声明指针为(*p)[columns]而不仅仅是*p。这样做,你正在声明指向2D数组的指针。

使用指针运算被处理二维数组像一维数组。将指针* Ptr初始化为第一个元素(int *Ptr = *data),然后添加一个no。 (Ptr + n)来访问列。添加一个比列号更高的数字就可以继续对下一行第一列的元素进行计数(如果存在)。