【问题标题】:Passing three dimensional arrays into functions in C?将三维数组传递给C中的函数?
【发布时间】:2009-11-17 12:32:50
【问题描述】:

在 C 中将三维数组传递给函数的最佳方法是什么?

【问题讨论】:

    标签: c arrays


    【解决方案1】:

    typedef 是你的朋友。

    #include <stdio.h>
    typedef int dimension1[20]; /* define dimension1 as array of 20
                                   elements of type int */
    typedef dimension1 dimension2[10]; /* define dimension2 as array of 10
                                          elements of type dimension1 */
    
    int foo(dimension2 arr[], size_t siz);
    
    int main(void) {
      dimension2 dimension3[7] = {0}; /* declare dimension3 as an array of 7
                                         elements of type dimension2 */
      dimension3[4][3][2] = 9999;
      dimension3[4][0][12] = 1;
      dimension3[3][8][18] = 42;
    
      printf("%d\n", foo(dimension3, 7));
    
      return 0;
    }
    
    int foo(dimension2 arr[], size_t siz) {
      int d1, d2, d3;
      int retval = 0;
      for (d3=0; d3<siz; d3++) {
        for (d2=0; d2<sizeof *arr / sizeof **arr; d2++) {
          for (d1=0; d1<sizeof **arr / sizeof ***arr; d1++) {
            retval += arr[d3][d2][d1];
          }
        }
        /* edit: previous answer used definite types for the sizeof argument */
        //for (d2=0; d2<sizeof (dimension2) / sizeof (dimension1); d2++) {
        //  for (d1=0; d1<sizeof (dimension1) / sizeof (int); d1++) {
        //    retval += arr[d3][d2][d1];
        //  }
        //}
      }
      return retval;
    }
    

    编辑

    我不喜欢使用明确的类型作为 sizeof 的参数。
    我添加了获取(子)数组大小的方法,而不直接指定它们的类型,而是让编译器从对象定义中推断出正确的类型。


    第二次编辑

    正如Per Eckman notes typedef-ing“裸”数组可能很危险。请注意,在上面的代码中,我没有将数组本身传递给函数foo。我正在传递一个指向“较低级别”数组的指针。

    foo(),在上面的代码中,接受一个指向dimension2 类型对象的指针。 dimension3 对象是dimension2 类型的元素数组,而不是dimension3 类型的对象(甚至没有定义)。

    但请记住 Per Eckman 的说明。

    【讨论】:

      【解决方案2】:

      要求您在编译时定义除了最左边的所有维度。

      #define DIM 5
      
      void do_something(float array[][DIM][DIM])
      {
          array[0][0][0] = 0;
          ...
      }
      

      【讨论】:

        【解决方案3】:

        将它们作为指针传递。

        例子

        int a[N][M][P];
        
        foo( &a[0][0][0]);
        

        foo 在哪里

        void foo( int*)
        

        您可能还需要传递尺寸,因此在这种情况下您可能需要:

        void foo( int*, int D1, int D2, int D3)
        

        然后打电话

        foo( &a[0][0][0], N, M, P);
        

        【讨论】:

        • 那里需要[0][0][0]吗?
        • @Cory,是的,它首先获取第一个 int,并获取它的地址。这给出了结果表达式类型int*,而不是像int(*)[N][M][P] 这样的数组指针。在我看来,这是一个很好的 hack,它可以通过不必处处处理常量来提高程序的清晰度。但它在形式上并不能保证有效,因此请谨慎使用(虽然不确定会出现什么问题)。
        • @Cory,另一种写法是&amp;***aa[0][0]**a
        【解决方案4】:

        类型定义“裸”数组可能很危险。

        试试这个

        #include <stdio.h>
        
        typedef char t1[10];
        
        void foo(t1 a) {
                t1 b;
        
                printf("%d %d\n", sizeof a, sizeof b);
        }
        
        int main(void) {
                t1 a;
                foo(a);
                return 0;
        }
        

        有人会认为 sizeof 两个相同类型的变量会返回相同的大小 但在这种情况下不是。出于这个原因,包装 typedef 数组是一个好习惯 在结构中。

        typedef struct {
                char x[10];
        } t1;
        

        【讨论】:

          猜你喜欢
          • 2021-05-10
          • 2014-01-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多