首頁  >  問答  >  主體

c++ - C语言的函数如何返回二维数组,并获取返回的二维数组大小

    public int[][] getInfo() {
        int[][] result = new int[10][20];
        return result;
    }
    public void main() {
        int[][] result = getInfo();
        System.out.println("结果长度:" + result.length);
        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result.length; j++) {
                System.out.println(result[i][j]);
            }
        }
    }

上面是一段java的代码,功能就是获取返回的二维数组,并输出二维数组的大小,并遍历数组的内容,前提是我并不知道返回来得数组大小。
如何把它翻译成C语言?其实我就是想理解C语言如何返回二维数组,如何获取数组的大小。

高洛峰高洛峰2713 天前1157

全部回覆(6)我來回復

  • 黄舟

    黄舟2017-04-17 12:07:30

    例如,用點黑魔法之類的(C語言的黑魔法當然就是宏+指針)。之前就有人提出將一個陣列的長度記在首位址前。

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct array_meta_t {
        int length;
        int elem_size;
    } array_meta;
    
    #define TO_META(array) (((array_meta*)array) - 1)
    #define TO_ARRAY(meta) ((void*)(meta + 1))
    
    void* array_allocate(int length, int type_size)
    {
        array_meta* new_array = malloc(length * type_size + sizeof(array_meta));
        new_array->length = length;
        new_array->elem_size = type_size;
    
        return TO_ARRAY(new_array);
    }
    
    #define array_length(array) (TO_META(array)->length)
    #define array_type_size(array) (TO_META(array)->elem_size)
    #define array_create(type, length) ((type*)array_allocate(length, sizeof(type)))
    #define array_release(array) (free(TO_META(array)))
    
    int** return_some_array()
    {
        int** my_array = array_create(int*, 10);
    
        int value = 0;
    
        for(int i = 0; i < array_length(my_array); i++)
            my_array[i] = array_create(int, 20);
            
        return my_array;
    }
    
    int main()
    {
        int** result = return_some_array();
        printf("The array has size %dx%d\n",
            array_length(result),
            array_length(*result));
        // Output: The array has size 10x20
    
        for(int i = 0; i < array_length(result); i++)
            array_release(result[i]);
        array_release(result);
    }
    

    這種方法相較於起回傳一個結構體指標有三個好處:

    • 元資訊結構體對使用者是隱藏的(有點像是物件導向裡的私有域),這裡array_length是宏所以可寫,改寫成函數就是只讀了

    • 可以用傳統的[]運算子直接取偏移,而不需要先解引用之類的

    • 還有一個就是,如果回傳一個結構體,相當於要動態分配兩次,記憶體管理起來更加麻煩。這裡只需要malloc一次,然後釋放一次就好了。

    C++的話就不用費事用vector了,用兩個模板元把不同長度的陣列重載開,搞定。記得參數是引用:

    template<int M, int N>
    void print_length(int (&) [M][N]) {
        cout << M << ' ' << N << endl;
    }
    //...
    int arr[5][6];
    print_length(arr); // Output: 5 6

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 12:07:30

    給樓主一個方法,我測試出來的,如果報錯請依照環境調試

    int a[5][6];
    int length=((int)&a)+1-(int)&a;

    回覆
    0
  • 迷茫

    迷茫2017-04-17 12:07:30

    因你是寫java的,我只能從簡解釋:
    簡單方法:C語言可修改函數參數所指的值,可以透過函數參數傳回二維數組的行數和列數。
    第二種方法:定義一個結構體,存放二維數組的指針,行數和列數,getInfo分配這個結構,賦值,並傳回此結構的指針。

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 12:07:30

    C 的數據(不管幾維)都是用指針表示的,單純的指針並不能描述數據的長度,所以無論如何都需要返回至少兩個數據,問題在於function 只能返回一個數據,那麼,常見的有以下兩種方案

    1. 定義一個結構體來包含兩個數據,例如

      ```c
      typedef struct {
          int** pStart;
          int size1d;
          int size2d;
      } MyResult;
      ```
      
    2. 直接在函數中定義指標參數來傳回

      ```c
      function get2DArray(int*** p, int* size1d, int* size2d) {
          // 内部代码
      }
      ```
      

      好複雜的感覺!

    回覆
    0
  • 阿神

    阿神2017-04-17 12:07:30

    把getInfo寫成一個標準的 分配記憶體 的函數. 主要是 做指標 cast的時候費點勁.

    #include <stdlib.h>
    #include <stdio.h>
    
    void* getInfo(int* row, int* col)
    {
        *row = 10;
        *col = 20;
        return malloc(200 * sizeof(int));
    }
    
    int main()
    {
        int r, c, i, j;
    
        void *p = getInfo(&r, &c);
        printf("%d, %d\n", r, c);
        int (*arrp)[c] = (int (*)[c])p;
    
        for (i = 0; i < r; i++) {
            for (j = 0; j < c; j++)
                printf("%d ", arrp[i][j]);
            printf("\n");
        }
        free(arrp);
        return 0;
    }
    

    回覆
    0
  • 迷茫

    迷茫2017-04-17 12:07:30

    使用vector吧;
    vector > vt;
    函數最後透過物件回傳vt後,可以在main函數中透過.size()取到各個維度的元素;

    for(int i = 0; i< vt.size();i++)
    {
        vector<int> & v1  = vt[i];
        for( int j = 0; j < v1.size();j++)
        {
            cout << v1[j] << endl;
        }
    }

    回覆
    0
  • 取消回覆