【问题标题】:C -- passing a 2d array as a function argument?C - 将二维数组作为函数参数传递?
【发布时间】:2011-07-28 17:05:02
【问题描述】:

人们可以轻松地定义一个接受1d array 参数的函数,如下所示:

int MyFunction( const float arr[] )
{    
    // do something here, then return...

    return 1

}

虽然定义如下: int MyFunction( const float* arr ) 也可以。

如何定义一个接受2d array 参数的函数?

我知道这行得通: int MyFunction( const float** arr ) -- 但是,是否可以使用第一个使用 [] 的变体?

【问题讨论】:

  • float **arr 不是二维数组,尽管它“看起来像”一个。
  • 谢谢。那么如何定义一个接受2d 数组的函数呢?
  • “二维数组”是一个模糊的名称,它可以用来指定几个不同的 C 结构。请向我们出示一份声明。
  • 看我的回答。请注意,它取决于 C99。如果第二维是一个常数,你可以显式地写这个常数,然后你的代码也可以在旧版本的 C 中工作。

标签: c


【解决方案1】:

在 C99 中,您可以在传递数组之前提供数组的维度:

 void array_function(int m, int n, float a[m][n])
 {
      for (int i = 0; i < m; i++)
          for (int j = 0; j < n; j++)
              a[i][j] = 0.0;
 }


 void another_function(void)
 {
     float a1[10][20];
     float a2[15][15];
     array_function(10, 20, a1);
     array_function(15, 15, a2);
 }

【讨论】:

  • 顺便说一下,第一个维度实际上是不必要的。编译器会忽略它。
  • 乔纳森,谢谢。鉴于您的回答,上述原型是否适用于 1d 数组void array_function(int n, float a[n])?
  • @user326424:是的,您可以按照建议将其调整为一维数组。虽然你获得多少取决于 R.. 的评论。
  • @R 这是否未定义内部数组或外部数组的大小?
  • @QPaysTaxes:指定int a[][23] 意味着您有一个未知长度的数组,其中数组的每个元素都是一个已知大小的数组。
【解决方案2】:

试试这样的:

int MyFunction(size_t ncols, const float arr[][ncols])
{    
    // ...
}

【讨论】:

  • 您的回答应该注意这是一个特定于 C99 的结构。
  • 对于我和本网站上的许多人来说,“C”表示撰写本文时的 C 标准的当前版本,即 C99。但是,是的,请注意,这确实需要 C99。正如我对原帖的评论,如果 ncols 是一个常数,你可以在 C99 之前的 C 中做同样的事情。
  • 你确定 C99 之前的东西吗?你的意思是ncolsconst size_t,还是你在说别的?
  • 我说的是ncols 是否是整数常量表达式,如42 或sizeof(int)const-qualified 变量不是 C 中的常量。
  • 当然,但这与您在上面提出的建议不同!
【解决方案3】:

当我们将二维数组作为参数传递给函数时,可以选择指定最左边的维度。这里的关键点是函数中所做的任何更改都会反映在调用函数中,因为当我们将二维数组作为参数传递时意味着实际上函数接收指向一维数组的指针。其大小是列数。 例子

1 - int funct(int (*a) [4]);

这里 a 是指向整数数组的指针。 我们也可以这样简单地通过

2-void funct(int a[][4]);

正如我之前所说,最左边总是可选的。 在第一个示例中,a 的大小为 4,因为它通常只是指针。 而 *a 的大小将为 16,因为我们有 4 列,每列有 4 个字节,所以 4*4 = 16 个字节。

但最可取的方法是始终使用动态内存分配。

希望你说清楚

【讨论】:

    【解决方案4】:

    hackish 方法是传递第一个元素并手动进行数组计算。

    这个较长的示例使用宏半自动提取要在调用中使用的数组维度。

    struct font { int disp, trig; };
    struct font font3[3][3];
    #define dim(x) (sizeof(x)/sizeof*(x))
    #define font_and_dims(x) (struct font *)x, dim(x), dim(*x)
    int print(char *s, struct font *font, int dimy, int dimx) { ... }
    
    main(){ ...   print(*av, font_and_dims(font3));   ... }
    

    被调用的函数以硬方式访问数组。

    print(){ ...   font[row*dimx+col]   ... }
    

    不要害怕向下滚动:好东西在底部!顶部的这个丑陋、迂腐的函数提供了终极的字符集可移植性;但我承认,这很碍眼。

    #include <stdio.h>
    #include <string.h>
    
    int ao(int c) {
        switch(c) {
        case '0':return 0;
        case '1':return 1;
        case '2':return 2;
        case '3':return 3;
        case '4':return 4;
        case '5':return 5;
        case '6':return 6;
        case '7':return 7;
        case '8':return 8;
        case '9':return 9;
        case 'A':case 'a':return 10;
        case 'B':case 'b':return 11;
        case 'C':case 'c':return 12;
        case 'D':case 'd':return 13;
        case 'E':case 'e':return 14;
        case 'F':case 'f':return 15;
        default:return -1;
        }
    }
    
    enum {
        A = 1 << 0,
        B = 1 << 1,
        C = 1 << 2,
        D = 1 << 3,
        E = 1 << 4,
        F = 1 << 5,
        G = 1 << 6,
        H = 1 << 7 };
    
    int seg[] = {
        /*0*/ A|B|C|D|E|F,
        /*1*/   B|C,
        /*2*/ A|B|  D|E|  G,
        /*3*/ A|B|C|D|    G,
        /*4*/   B|C|    F|G,
        /*5*/ A|  C|D|  F|G,
        /*6*/ A|  C|D|E|F|G,
        /*7*/ A|B|C,
        /*8*/ A|B|C|D|E|F|G,
        /*9*/ A|B|C|    F|G,
        /*A*/ A|B|C|D|E|  G, /*A|B|C|  E|F|G,*/
        /*b*/     C|D|E|F|G,
        /*C*/       D|E|  G, /*A|    D|E|F,*/
        /*d*/   B|C|D|E|  G,
        /*E*/ A|B|  D|E|F|G, /*A|    D|E|F|G,*/
        /*F*/ A|      E|F|G,
    };
    
    struct font {
        int disp, trig;
    };
    /* _
      |_|
      |_|
    */
    struct font font3[3][3] = {
        { {  0,0}, {'_',A}, {  0,0} },
        { {'|',F}, {'_',G}, {'|',B} },
        { {'|',E}, {'_',D}, {'|',C} },
    };
    /* ___
      |   |
      |___|
      |   |
      |___|
    */
    struct font font5[5][5] = {
        { {  0,0}, {'_',A}, {'_',A}, {'_',A}, {  0,0} },
        { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {'|',B} },
        { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'|',B} },
        { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {'|',C} },
        { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'|',C} }
    };
    /* ____
      |    |
      |    |
      |    |
      |____|
      |    |
      |    |
      |    |
      |____|
    */
    struct font font9[9][7] = {
        { {  0,0}, {'_',A}, {'_',A}, {'_',A}, {'_',A}, {  0,0}, {0,0} },
        { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
        { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
        { {'|',F}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',B}, {0,0} },
        { {'|',F}, {'_',G}, {'_',G}, {'_',G}, {'_',G}, {'|',B}, {0,0} },
        { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
        { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
        { {'|',E}, {  0,0}, {  0,0}, {  0,0}, {  0,0}, {'|',C}, {0,0} },
        { {'|',E}, {'_',D}, {'_',D}, {'_',D}, {'_',D}, {'|',C}, {0,0} },
    };
    
    #define dim(x) (sizeof(x)/sizeof*(x))
    #define font_and_dims(x) (struct font *)x, dim(x), dim(*x)
    
    int print(char *s, struct font *font, int dimy, int dimx) {
        int row, col;
        char *sp;
        for (row = 0; row < dimy; row++) {
        for (sp = s; *sp; sp++) {
            for (col = 0; col < dimx; col++) {
                putchar( seg[ao(*sp)] & font[row*dimx+col].trig ?
                    font[row*dimx+col].disp : ' ');
            }
        }
        putchar('\n');
        }
    }
    
    int main(int ac, char **av) {
        enum { F1, F2, F3 } fz = F1;
        for (++av,--ac;ac;ac--,av++) {
        if (av[0][0] == '-') {
            switch (av[0][1]) {
                case '1': fz=F1; continue;
                case '2': fz=F2; continue;
                case '3': fz=F3; continue;
                default: fprintf(stderr, "Unrecognized Option!\n");
            }
        }
        if (strspn(*av, "0123456789abcdefABCDEF") != strlen(*av))
            fprintf(stderr, "Hex only!\n");
        else
            switch(fz) {
                case F1: print(*av, font_and_dims(font3)); break;
                case F2: print(*av, font_and_dims(font5)); break;
                case F3: print(*av, font_and_dims(font9)); break;
                default: fprintf(stderr, "Invalid Font!\n");
            }
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案5】:

      在 C89 中你可以使用

      typedef float OneRow[2];
      
      void func(OneRow *arr)
      {
        printf("%f",arr[1][0]);
      }
      ...
        OneRow arr[] = {{1,2},{3,4},{5,6}};
        func(arr);
      ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-22
        • 2023-03-30
        • 2020-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多