【问题标题】:Can I access type int (*)[] with [][]?我可以使用 [][] 访问类型 int (*)[] 吗?
【发布时间】:2010-06-04 12:00:39
【问题描述】:

来自这个问题“What does (int (*)[])var1 stand for?”我试图像访问多维数组一样访问强制转换的结果。但我收到以下错误:“assignment from incompatible pointer type”后跟分段错误。我还尝试了其他一些变体,但没有一个奏效。如何在example函数中直接访问var1中的元素?

谢谢!

 #include <stdlib.h>

int i(int n,int m,int var1[n][m]) {
  var1[0][0]=5;
  return var1[0][0];
}

int example() {
  int *var1 = malloc(100);

  // works
  int var2;
  var2 = i(10,10,(int (*)[])var1);
  printf("var2=%i",var2);
  //doesn't work I
  int *var3;
  var3=(int (*)[])var1; //"assignment from incompatible pointer type"
  printf("var3[0][0]=%i",var3[0][0]);


  //doesn't work II
  int *var4;
  var4=var1;
  printf("var4[0][0]=%i",var4[0][0]); //" error: subscripted value is neither array nor pointer"

  //doesn't work III
  int **var5;
  var5=var1;
  printf("var5[0][0]=%i",var5[0][0]); // assignment from incompatible pointer type


  return(1); 

} 

int main(){
  int a;
  a=example();
  return(1);
}

【问题讨论】:

    标签: c pointers casting multidimensional-array


    【解决方案1】:
    int *var3;
    var3 = (int (*)[])var1;
    

    您正在将已经是 int* 的 var1 转换为 int(*)[](指向 int 数组的指针)并将其分配给 var3,这又是 int*。

    做事

    var3 = var1
    

    【讨论】:

    • 嗨,Amarghosh,我尝试实现您的示例,但收到错误消息“下标值既不是数组也不是指针”。也许我误解了你。你能检查一下我对这个问题所做的编辑吗?谢谢!
    • @Framester 你不能下标(使用[])int* 两次。要么将 var3 声明为 int** 并将 &amp;var1 分配给它,要么只读取 var3[0]。你到底想做什么?
    • 我想使用单独的函数来避免绕道。我尝试在函数example 中访问var1,因为它是通过[][] 在函数i 中访问的。
    • @Framester 将指针转换为相同类型的多维数组仅适用于函数调用 - 在正常情况下,您不能只转换指向数组的指针并分配给数组变量。如果您解释为什么需要二维访问而不是一维访问,也许我们可以提供帮助。将 var3 声明为 int** 并为其分配 &amp;var1 将编译,但对于 var3[i][j] 中 i 大于 1 的值会出现段错误
    【解决方案2】:

    试一试。以下编译没有警告并在 C99 (gcc -std=c99 -pedantic -Wall) 下运行:

    #include <stdio.h>
    #include <stdlib.h>
    
    int i(int n, int m, int (*var1)[m]) // C89 requires constant expression for
    {                                   // array size
      int j, k;
      for (j = 0; j < n; j++)
        for (k = 0; k < m; k++)
          var1[j][k] = j*m+k;
      return var1[0][0];
    }
    
    int example(void)
    {
      int *var1 = malloc(100 * sizeof *var1);   // Thanks, Joseph!
      int var2 = i(10, 10, (int (*)[10]) var1); // note the cast of var1 includes
                                                // the array size
      int (*var3)[10] = (int (*)[10]) var1;     // note the type of var3
    
      int j, k;
      for (j = 0; j < 100; j++)
        printf("var1[%2d] = %d\n", j, var1[j]);
    
      for (j = 0; j < 10; j++)
        for (k = 0; k < 10; k++)
          printf("var3[%2d][%2d] = %d\n", j, k, var3[j][k]);
    
      free(var1);
      return var2;
    }
    
    int main(void)
    {
      int x = example();
      printf("x = %d\n", x);
      return 0;
    }
    

    首先,注意类型和演员表(最重要的是,注意它们是如何匹配的)。请注意,我在指向数组的转换中指定了数组维度的大小。另请注意,我将var3 声明为指向数组的指针,而不是简单的指针。

    【讨论】:

    • 谢谢,以这种方式投射 var3 int (*var3)[10] = (int (*)[10]) var1; 是我的解决方案!
    • 我认为您的意思是malloc(400),而不是malloc(100),具体取决于您的目标。请参阅 stackoverflow.com/questions/2973856/can-i-access-type-int-with/… 了解执行此操作的简洁方式。
    • 并且,根据经验,如果最好避免不必要的强制转换(MSVC 除外!)。有关无铸件解决方案,请参见上一个链接。
    • @Joseph:关于malloc 电话——很好。我已经编辑了代码来解决这个问题(让我绊倒的总是愚蠢的废话)。关于“不必要的”演员表,我对 OP 问题的看法是,鉴于他有一个 1-D 数组,他如何访问它就好像它是一个 2-D 数组?因此演员表。就个人而言,我不会以这种方式编写代码,但我认为考虑数组类型之间的差异是一个有用的练习。
    【解决方案3】:
    int example() {
        int *var1 = malloc(100);
    
        ...
    
        int *var3;
        var3=var1;
        printf("var3[0][0]=%i",var3[0][0]); //" error: subscripted value is neither array nor pointer"
    
        return(1); 
    } 
    

    这里,var1 和var3 都是int* 类型,大致类似于int[]。您已经创建了一个一维数组并尝试将它们作为二维数组进行访问。将它们的类型更改为int**,分配必要的内存,这应该可以解决您的问题。

    【讨论】:

      【解决方案4】:

      var3 必须是 int** 而不是 int*。

      编辑

      您正在尝试使用 2D 数组语法,其中您创建的实际数据实际上是 1D 数组。您可以使用 i() 函数为您提供所需的语义,但数据访问需要在函数内转换为一维索引。让你的函数看起来像这样:

      int i(int n,int m,int* var1, int maxM) {
        return var1[(maxM * n) + m];
      }
      

      【讨论】:

      • 哎呀混淆了语言...第一部分仍然有效。
      • 嗨,bshields,我添加了一个例子来说明我是如何理解你的。请参阅//doesn't work III 但我收到错误消息// assignment from incompatible pointer type
      • 我明白,这里的 malloc 只创建一个一维数组。但是为什么我不能在example 函数中将var1 作为二维数组访问,而我可以在i 函数中将它作为二维数组访问。 困惑
      • 我认为答案是您当前的 i 函数并没有真正起作用。您已经进行了此编译,因为您已经适当地对其进行了转换,但是您是否验证了它确实可以正常工作而不会崩溃?我很确定这会崩溃。
      【解决方案5】:

      也许您正在寻找的是:

      int (*var1)[10][10] = malloc(sizeof *var1); // 400 bytes
      i(10, 10, *var1);
      printf("var1[0][0]=%i\n", (*var1)[0][0]);
      

      已添加:gcc 的完整代码片段可能是:

      #include <stdio.h>
      #include <stdlib.h>
      
      void i(int n, int m, int var1[][m]) { // n not needed
          var1[0][0] = 5;
          var1[1][2] = 6;
      }
      
      int main(void) {
          int n = 10, m = 10;
          int (*var1)[n][m] = malloc(sizeof *var1); // 400 bytes
          i(n, m, *var1);
          printf("var1[0][0]=%i\n",(*var1)[0][0]);
          printf("var1[1][2]=%i\n",(*var1)[1][2]);
          return 0;
      }
      

      对于 msvc,您需要将 n 和 m 设为常量,如下所示:

      enum {n = 10, m = 10};
      
      void i(int var1[][m]) {
          var1[0][0] = 5;
          var1[1][2] = 6;
      }
      
      int main(void) {
          int (*var1)[n][m] = malloc(sizeof *var1);
          i(*var1);
          // ...
      }
      

      【讨论】:

        猜你喜欢
        • 2011-08-19
        • 1970-01-01
        • 2017-11-11
        • 2015-03-21
        • 1970-01-01
        • 2016-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多