c++ - C语言的函数如何返回二维数组,并获取返回的二维数组大小
高洛峰
高洛峰 2017-04-17 12:05:30
0
6
1205
    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语言如何返回二维数组,如何获取数组的大小。

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

reply all(6)
黄舟

For example, use some black magic (the black magic of C language is of course macro + pointer). Someone has proposed before that the length of an array should be recorded before the first address.

#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);
}

This method has three advantages compared to returning a structure pointer:

  • The meta-information structure is hidden from the user (a bit like a private field in object-oriented). Here array_length is a macro so it is writable. If it is rewritten as a function, it is read-only

  • You can use the traditional [] operator to directly get the offset without first dereferencing or anything like

  • Another thing is that if a structure is returned, it is equivalent to dynamic allocation twice, which makes memory management more troublesome. You only need to malloc once here and then release it once.

If you are using C++, you don’t need to bother using vector. Just use two template elements to overload arrays of different lengths and you’re done. Remember that parameters are references:

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
洪涛

Give me a method. I tested it. If an error is reported, please debug it according to the environment

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

Since you are writing Java, I can only explain it briefly:
Simple method: C language can modify the value pointed by the function parameter, and the number of rows and columns of the two-dimensional array can be returned through the function parameter.
Second method: Define a structure to store the pointer of the two-dimensional array, the number of rows and the number of columns. getInfo allocates this structure, assigns a value, and returns the pointer of this structure.

左手右手慢动作

C data (no matter how many dimensions) are represented by pointers. A simple pointer cannot describe the length of the data, so at least two pieces of data need to be returned anyway. The problem is that function can only return one piece of data, then, There are two common solutions below

  1. Define a structure to contain two data, such as

    ```c
    typedef struct {
        int** pStart;
        int size1d;
        int size2d;
    } MyResult;
    ```
    
  2. Define pointer parameters directly in the function to return

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

    What a complicated feeling!

阿神

Write getInfo as a standard function for allocating memory. The main reason is that it takes a little effort when doing pointer casting.

#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;
}
迷茫

Use vector;
vector<vector<int> > vt;
After the function finally returns vt through the object, you can get the elements of each dimension through .size() in the main function;

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;
    }
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template