声明指向 3 x 3 数组的指针并使用指针打印它

Declaring pointer to a 3 by 3 array and using pointer to print it

我如何声明一个指向 3×3 数组的指针并使用该指针打印它....编译器给出错误“[错误] 下标值既不是数组也不是指针也不是向量”

#include <stdio.h>
int main(void)
{
    int A[3][3][3]={0};

    int *ptr=A;
    int i,j,k;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            for(k=0;k<3;k++)
            {
                printf("%d    ",*ptr[i][j][k] );
            }
            puts("");
        }
    }
    return 0;
}

您的代码存在的问题是您声明了一个指向 int 的指针,并向其转换了一个数组。这是不正确的,因为指针具有一个隐式 "dimension"(因此允许单个解引用),而您的数组具有三个维度。

要解决此问题,请将 ptr 声明为指向 3×3 数组的指针:

int (*ptr)[3][3]=A;

在这种情况下,您需要在访问数组元素时删除取消引用运算符

printf("%d    ", ptr[i][j][k]);

demo 1.

或指向 3×3×3 数组的指针

int (*ptr)[3][3][3]=&A;

在这种情况下,您需要在对其应用索引之前取消对指针的引用:

printf("%d    ", (*ptr)[i][j][k]);

demo 2.

任何多维数组实际上都是一维数组,其元素又是数组。

这个声明

int A[3][3][3]={0};

可以改写成下面的方式

typedef int T[3][3];

T A[3];

所以你有一个数组 A,其中元素的类型为 int[3][3] 如果你想声明一个指向数组第一个元素的指针,那么你必须写

T *ptr = A;

其中 ptr 是指向类型 T 的对象的指针。由于 Tint[3][3] 的别名,因此前面的声明可以重写为

int ( *ptr )[3][3] = A;

在这种情况下,循环看起来像

  for(i=0;i<3;i++)
  {
      for(j=0;j<3;j++)
      {
           for(k=0;k<3;k++)
           {
               printf("%d    ", ptr[i][j][k] );
           }

      puts("");

      }
  }

如果你想声明一个指向整个数组本身的指针,那么你可以这样写

int ( *ptr )[3][3][3] = &A;

循环看起来像

  for(i=0;i<3;i++)
  {
      for(j=0;j<3;j++)
      {
           for(k=0;k<3;k++)
           {
               printf("%d    ", ( *ptr )[i][j][k] );
           }

      puts("");

      }
  }

但我确信在您的作业中,您需要使用指向数组第一个元素的指针,正如我最初展示的那样。

问题在于,如果指针是单个星形指针,则使用索引表示法访问指针值适用于单个索引,就像这样

printf("%d\t", ptr[i + 3 * j + 9 * k]);

一个三星指针int ***ptr允许语法ptr[i][j][k]但它是错误的,因为指针会指向int指针的指针,这意味着数据与数组 int A[3][3][3] 的排列方式不同,数组更像是一个 int *ptr 指针,因为整数是连续存储的。

int ***方法中,它就像一个指向int指针数组的指针数组。这意味着 ptr[i] 等同于 *(ptr + i),后者与 *((char ***)ptr + sizeof(int **)) 相同,因为 sizeof(int **) 不一定与 1[=37= 相同] sizeof(int),然后它会将指针增加一个与需要不同的数量,从而导致一个明显的问题,取消引用的指针将不会指向正确的位置。

你总是可以像其他答案提到的那样声明指向数组的指针,但我会跳过那部分,因为它在其他答案中。


1可能是巧合。