2013-10-20 126 views
1

我现在正在学习c,我正在学习指针。我读过一些例子,我想出了这个:指向2维数组的指针

#include <stdio.h> 

    int main() 
    { 
     float balance[10][5]; 
     float *p; 

     p = (float *) balance; 

     *(p + 16) = 200.0; //init the balance[3][1] with the value 200.0 
     printf("%f\n", balance[3][1]); 
     return 0;  
    } 

我的问题是这样的。为什么我必须用(float *)投下余额?这是因为数组是2维吗?所以指针也是2维的?所以我必须将它转换为1维?

回答

3

为什么我必须用(float *)来平衡?

这是因为pfloat *类型而balancefloat (*)[5]类型的衰减到指针后。

是因为这个数组是2维吗?

是的。

所以指针也是2维?

balance衰变为float (*)[5]

所以我必须将它转换为1维?

是的。

+0

为了避免使用强制转换,可以写'p =&balance [0] [0];' – sfk

+1

True。但我只是回答了这个问题。 :) – haccks

-1

这里变量“balance”存储2维数组的基地址。

什么是指针? 存储地址的变量称为指针

对!

'p'是单个浮点指针,它存储浮点变量的地址,但这里的'balance'是浮点数组变量。

你所做的是,将二维数组变量作为一维数组进行类型转换,即:根据在“平衡”是2D阵列目前已成为一维数组指派什么指针变量“P” ...

如果分配指针LYK此

浮子

** P;

然后

p =余额;是一个有效的语句,指针将其视为二维数组。

+0

'float **'是一个指向浮点值的指针,因此它指向一个或多个指针所在的内存区域。浮点[10] [5]'是一个包含50个浮点的存储区域,可用作指向该区域的指针。因此你的答案不起作用。 –

+0

您可以使用编译器进行检查,并且上述分配有效。 平衡是2D阵列2D阵列的 即 平衡存储基地址 和第一行的平衡[0]存储地址 和平衡[0] [0]的第一行中指出的值,并第一列。 此处余额携带2个地址,因此双指针有效。 – Chandu

+0

@PavelŠimerdachk上面的答案...你错了.. – Chandu

0

这个例子演示了如何在内存中分配数组。一个二维数组由行中分配,在第一行之后是内存中数组的第二行。由于数组的内存被分配为一个范围,因此您可以将其解释为一维数组。

您示例中的数组实际上有50个元素(10 * 5)。由于行在内存中顺序地容纳,因此元素balance [3] [1]的位置可以计算为等于16的3 * 5 + 1。因此,如果您将内存的范围视为一维数组,那么对应元素可以写为p [16]或(与*(p + 16)相同)。

这样解释二维数组的一种有用技巧可以应用于二维数组的排序。使用标准排序函数将二维数组排序为一维数组要简单得多。

0

为什么我要一个(浮动*)投平衡

你不不得不,你可以使用它只是作为一个数组,就如同在printf()完成。我建议你不要将平面访问和多维访问相结合。

1

此代码是一个丑陋的黑客攻击,只会让你迷惑,现在,当你回来看看这个代码在未来。指针算术背后的思想是让数组访问更容易,而不是更难。如果更改

float *p; 

float **p; 

指针现在是一个双指针,这意味着当您使用间接运算符(*)后,你会得到另一个指针。您所创建的阵列看起来像这样:

[0,0][0,1][0,2][0,3][0,4] 
[1,0][1,1][1,2][1,3][1,4] 
[2,0][2,1][2,2][2,3][2,4] 
[3,0][3,1][3,2][3,3][3,4] 
[4,0][4,1][4,2][4,3][4,4] 
[5,0][5,1][5,2][5,3][5,4] 
[6,0][6,1][6,2][6,3][6,4] 
[7,0][7,1][7,2][7,3][7,4] 
[8,0][8,1][8,2][8,3][8,4] 
[9,0][9,1][9,2][9,3][9,4] 

既然你有间接的两个层次,第一个指针会指向你行,第二个将指向你的专栏。由于间接方向是向后完成的,这意味着在指针表示法中,最里面的元素是数组表示法中最远的元素。

arr[ROW][COL] === *(*(p + ROW) + COL) 

现在,如果您要访问的元素,你可以做到这一点使用数组符号ARR [ROW] [COL],或用指针运算。使用双指针,有两个间接级别。所以,而你不得不使用

p = (float *) balance; 
    *(p + 16) 

得到你想要的位置,它实际上是一个更容易(在我看来)简单地写

p = balance; 
    *(*(p + 3) + 1) 

因为现在你正在使用指针运算类似于数组索引,并且更容易一目了然地告诉您要指向哪个元素。只要将双指针投射到单个指针,首先处理双指针就更容易了,这就是数组的名称。

int arr[ROW][COL] = {0}; 
    int **p_arr = arr; /* Valid operation. arr without array notation is a double pointer */