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语言如何返回二维数组,如何获取数组的大小。
黄舟2017-04-17 12:07:30
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
PHP中文网2017-04-17 12:07:30
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;
迷茫2017-04-17 12:07:30
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.
ringa_lee2017-04-17 12:07:30
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
Define a structure to contain two data, such as
```c
typedef struct {
int** pStart;
int size1d;
int size2d;
} MyResult;
```
Define pointer parameters directly in the function to return
```c
function get2DArray(int*** p, int* size1d, int* size2d) {
// 内部代码
}
```
What a complicated feeling!
阿神2017-04-17 12:07:30
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;
}
迷茫2017-04-17 12:07:30
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;
}
}