C 指向二维数组的指针

C 指向二维数组的指针,c,pointers,C,Pointers,我现在正在学习c,我正在学习指针。我读了一些例子,并提出了以下建议: #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

我现在正在学习c,我正在学习指针。我读了一些例子,并提出了以下建议:

   #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;    
   }
#包括
int main()
{ 
浮动余额[10][5];
浮动*p;
p=(浮动*)余额;
*(p+16)=200.0;//使用值200.0初始化余额[3][1]
printf(“%f\n”,余额[3][1]);
返回0;
}
我的问题是。为什么我必须用
(float*)
来平衡?这是因为数组是二维的吗?那么指针也是二维的?所以我必须把它转换成一维

为什么我必须用(浮动*)来平衡

这是因为
p
float*
类型,而
balance
float(*)[5]
类型,在衰减到指针后

这是因为数组是二维的吗

那么指针也是二维的

余额
衰减为
浮动(*)[5]

所以我必须把它转换成一维

这里变量“balance”存储二维数组的基址

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

对!

“p”是存储浮动变量地址的单浮动指针,但这里的“balance”是一个浮动数组变量

您所做的是,将2D数组变量作为1D数组键入指针…即。根据指针变量“p”,您在“balance”中指定的二维数组现在已变为一维数组

如果将指针lyk分配给此

浮动**p

然后


p=平衡;是有效语句,指针将其视为2D数组。

此示例演示如何在内存中分配数组。二维OANL数组由内存中第一行之后的第二行分配。由于数组的内存分配为一个区段,因此可以将其解释为一维数组

您示例中的数组实际上有50个元素(10*5)。由于行在存储器中顺序容纳,因此元素平衡[3][1]的位置可以计算为3*5+1,等于16。因此,如果你将内存的大小视为一维数组,那么CordSopOnod元素可以被写成P(16)或(与*(p+1)16相同)。 这种二维数组解释的一个有用技巧可以应用于二维数组的排序。使用标准排序函数将二维数组排序为一维数组要简单得多

为什么我必须用(浮动*)来平衡


您不必这样做,只需将其用作数组,就像在
printf()
中所做的那样。我建议您不要将平面访问和多维访问结合起来。

这段代码是一个丑陋的黑客行为,它只会让您感到困惑,现在和将来您回来查看这段代码时。指针算法背后的思想是使访问数组更容易,而不是更难。如果你改变

    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 */

为了避免使用cast,您可以编写
p=&balance[0][0]真。但我只是回答了问题。:)浮点**
是指向浮点值指针的指针,因此它指向一个或多个指针所在的内存区域。一个
浮点[10][5]
是一个50个浮点的内存区域,可以用作指向该区域的指针。因此,您的答案不起作用。您可以向编译器检查,并且上面的赋值是有效的。。balance是2D数组,即balance存储2D数组的基址,balance[0]存储第一行的地址,balance[0][0]指向第一行和第一列中的值。在这里,余额携带2个地址,因此双指针是有效的。
    int arr[ROW][COL] = {0};
    int **p_arr = arr; /* Valid operation. arr without array notation is a double pointer */