c++ - C语言的函数如何返回二维数组,并获取返回的二维数组大小
高洛峰
高洛峰 2017-04-17 12:05:30
0
6
1199
    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教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

全部回复(6)
黄舟

比如,用点黑魔法之类的(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
洪涛

给楼主一个方法,我测试出来的,如果报错请根据环境调试

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

因你是写java的,我只能从简解释:
简单方法:C语言可修改函数参数所指的值,可以通过函数参数返回二维数组的行数和列数。
第二种方法:定义一个结构体,存放二维数组的指针,行数和列数,getInfo分配这个结构,赋值,并返回此结构的指针。

左手右手慢动作

C 的数据(不管几维)都是用指针表示的,单纯的指针并不能描述数据的长度,所以无论如何都需要返回至少两个数据,问题在于 function 只能返回一个数据,那么,常见的有下面两种方案

  1. 定义一个结构体来包含两数据,比如

    ```c
    typedef struct {
        int** pStart;
        int size1d;
        int size2d;
    } MyResult;
    ```
    
  2. 直接在函数中定义指针参数来返回

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

    好复杂的感觉!

阿神

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

使用vector吧;
vector<vector<int> > 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;
    }
}
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板