最后,如果我想转储数组,只需:
int array[dim1][dim2]..;
A(array, dim1, dim2, dim3, dim4...);
是否可以在C?
更新
如何在array
中定义A(array, dim1, dim2, dim3, dim4...);
的类型,以便编译器不会发出任何警告?
答案 0 :(得分:5)
对A的调用必须指明维度的数量,并提供每个维度的大小。使用一些C99:
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
extern void A(int *base, int ndims, ...);
extern void B(void);
void A(int *base, int ndims, ...)
{
assert(ndims > 0);
int dims[ndims];
int size = 1;
va_list args;
va_start(args, ndims);
for (int i = 0; i < ndims; i++)
{
dims[i] = va_arg(args, int);
size *= dims[i];
}
va_end(args);
int mods[ndims];
// I suspect this 'mods' loop is suboptimal, but it works.
for (int i = 0; i < ndims; i++)
{
int v = size;
for (int j = 0; j <= i; j++) {
v /= dims[j];
mods[i] = v;
}
}
for (int offset = 0; offset < size; offset++)
{
printf("%s", "array");
for (int i = 0; i < ndims; i++)
{
int p = offset / mods[i];
printf("[%d]", p % dims[i]);
}
printf(" = %d\n", base[offset]);
}
}
void B(void)
{
enum { dim1 = 4, dim2 = 6 };
int array1[dim1][dim2] =
{
{ 0, 1, 2, 3, 4, 5 },
{ 22, 21, 20, 19, 18, 17 },
{ 32, 31, 30, 39, 38, 37 },
{ 42, 41, 40, 49, 48, 47 },
};
int array2[dim2][dim1][dim2] =
{
{
{ 15, 68, 67, 16, 105, 4 },
{ 25, 58, 67, 16, 115, 4 },
{ 35, 48, 67, 16, 125, 4 },
{ 45, 38, 67, 16, 135, 4 },
},
{
{ 19, 69, 77, 16, 205, 5 },
{ 29, 59, 77, 16, 215, 5 },
{ 39, 49, 77, 16, 225, 5 },
{ 49, 39, 77, 16, 235, 5 },
},
{
{ 12, 64, 87, 16, 305, 6 },
{ 22, 54, 87, 16, 315, 6 },
{ 32, 44, 87, 16, 325, 6 },
{ 42, 34, 87, 16, 335, 6 },
},
{
{ 17, 63, 97, 16, 405, 7 },
{ 27, 53, 67, 16, 415, 7 },
{ 37, 43, 97, 16, 425, 7 },
{ 47, 33, 97, 16, 435, 7 },
},
{
{ 10, 60, 90, 10, 500, 97 },
{ 20, 50, 60, 20, 510, 87 },
{ 30, 40, 90, 30, 520, 77 },
{ 40, 30, 90, 40, 530, 67 },
},
{
{ 11, 63, 97, 36, 605, 39 },
{ 21, 53, 67, 46, 615, 38 },
{ 31, 43, 97, 56, 625, 27 },
{ 41, 33, 97, 66, 635, 26 },
},
};
A(&array1[0][0], 2, dim1, dim2);
putchar('\n');
A(&array2[0][0][0], 3, dim2, dim1, dim2);
}
int main(void)
{
B();
return(0);
}
array[0][0] = 0
array[0][1] = 1
array[0][2] = 2
array[0][3] = 3
array[0][4] = 4
array[0][5] = 5
array[1][0] = 22
array[1][1] = 21
array[1][2] = 20
array[1][3] = 19
array[1][4] = 18
array[1][5] = 17
array[2][0] = 32
array[2][1] = 31
array[2][2] = 30
array[2][3] = 39
array[2][4] = 38
array[2][5] = 37
array[3][0] = 42
array[3][1] = 41
array[3][2] = 40
array[3][3] = 49
array[3][4] = 48
array[3][5] = 47
array[0][0][0] = 15
array[0][0][1] = 68
array[0][0][2] = 67
array[0][0][3] = 16
array[0][0][4] = 105
array[0][0][5] = 4
array[0][1][0] = 25
array[0][1][1] = 58
array[0][1][2] = 67
array[0][1][3] = 16
array[0][1][4] = 115
array[0][1][5] = 4
array[0][2][0] = 35
array[0][2][1] = 48
array[0][2][2] = 67
array[0][2][3] = 16
array[0][2][4] = 125
array[0][2][5] = 4
array[0][3][0] = 45
array[0][3][1] = 38
array[0][3][2] = 67
array[0][3][3] = 16
array[0][3][4] = 135
array[0][3][5] = 4
array[1][0][0] = 19
array[1][0][1] = 69
array[1][0][2] = 77
array[1][0][3] = 16
array[1][0][4] = 205
array[1][0][5] = 5
array[1][1][0] = 29
array[1][1][1] = 59
array[1][1][2] = 77
array[1][1][3] = 16
array[1][1][4] = 215
array[1][1][5] = 5
array[1][2][0] = 39
array[1][2][1] = 49
array[1][2][2] = 77
array[1][2][3] = 16
array[1][2][4] = 225
array[1][2][5] = 5
array[1][3][0] = 49
array[1][3][1] = 39
array[1][3][2] = 77
array[1][3][3] = 16
array[1][3][4] = 235
array[1][3][5] = 5
array[2][0][0] = 12
array[2][0][1] = 64
array[2][0][2] = 87
array[2][0][3] = 16
array[2][0][4] = 305
array[2][0][5] = 6
array[2][1][0] = 22
array[2][1][1] = 54
array[2][1][2] = 87
array[2][1][3] = 16
array[2][1][4] = 315
array[2][1][5] = 6
array[2][2][0] = 32
array[2][2][1] = 44
array[2][2][2] = 87
array[2][2][3] = 16
array[2][2][4] = 325
array[2][2][5] = 6
array[2][3][0] = 42
array[2][3][1] = 34
array[2][3][2] = 87
array[2][3][3] = 16
array[2][3][4] = 335
array[2][3][5] = 6
array[3][0][0] = 17
array[3][0][1] = 63
array[3][0][2] = 97
array[3][0][3] = 16
array[3][0][4] = 405
array[3][0][5] = 7
array[3][1][0] = 27
array[3][1][1] = 53
array[3][1][2] = 67
array[3][1][3] = 16
array[3][1][4] = 415
array[3][1][5] = 7
array[3][2][0] = 37
array[3][2][1] = 43
array[3][2][2] = 97
array[3][2][3] = 16
array[3][2][4] = 425
array[3][2][5] = 7
array[3][3][0] = 47
array[3][3][1] = 33
array[3][3][2] = 97
array[3][3][3] = 16
array[3][3][4] = 435
array[3][3][5] = 7
array[4][0][0] = 10
array[4][0][1] = 60
array[4][0][2] = 90
array[4][0][3] = 10
array[4][0][4] = 500
array[4][0][5] = 97
array[4][1][0] = 20
array[4][1][1] = 50
array[4][1][2] = 60
array[4][1][3] = 20
array[4][1][4] = 510
array[4][1][5] = 87
array[4][2][0] = 30
array[4][2][1] = 40
array[4][2][2] = 90
array[4][2][3] = 30
array[4][2][4] = 520
array[4][2][5] = 77
array[4][3][0] = 40
array[4][3][1] = 30
array[4][3][2] = 90
array[4][3][3] = 40
array[4][3][4] = 530
array[4][3][5] = 67
array[5][0][0] = 11
array[5][0][1] = 63
array[5][0][2] = 97
array[5][0][3] = 36
array[5][0][4] = 605
array[5][0][5] = 39
array[5][1][0] = 21
array[5][1][1] = 53
array[5][1][2] = 67
array[5][1][3] = 46
array[5][1][4] = 615
array[5][1][5] = 38
array[5][2][0] = 31
array[5][2][1] = 43
array[5][2][2] = 97
array[5][2][3] = 56
array[5][2][4] = 625
array[5][2][5] = 27
array[5][3][0] = 41
array[5][3][1] = 33
array[5][3][2] = 97
array[5][3][3] = 66
array[5][3][4] = 635
array[5][3][5] = 26
评论:实际上更容易获得3D情况,然后专注于2D情况,而不是将2D情况正确,然后推广到3D情况。
请注意,此技术适用于任何连续数组(如静态分配的示例)。有一些方法可以动态分配数据不连续的数组,这对这种伪数组不起作用。如果您分配一个指针数组,然后每个指针指向一个整数向量或任何类似的方案,这是一个问题。可以使用双下标表示法访问此类“数组”,但生成的代码与访问真正的多维(连续)数组完全不同。
函数A()
中的代码不会处理像这样分配的'数组'(为简洁而省略错误检查),即使初始化循环看起来与常规(连续)的初始化循环相同二维数组:
int **base = malloc(4 * sizeof(*base));
for (int i = 0; i < 4; i++)
base[i] = malloc(6 * sizeof(*base[i]));
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 6; j++)
base[i][j] = 0;
}
for (int i = 0; i < 4; i++)
free(base[i]);
free(base);
答案 1 :(得分:0)
无法检查变量参数列表并获取大小,因此您必须传递长度参数。
这是一个可以支持任意维度int数组的递归示例:
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
void print_array_v(void *a, int cnt, va_list args) {
va_list nw;
int i, j;
i = va_arg(args, int);
if(cnt > 1) {
for(j=0; j != i; ++j) {
va_copy(nw, args);
printf("[%d %d]\n", cnt-1, j);
print_array_v(((int **)a)[j], cnt - 1, nw);
va_end(nw);
}
} else {
printf("(%d, %p) ", i, a);
for(j = 0; j != i; ++j) { printf("%d ", ((int *)a)[j]); }
printf("\n");
}
}
void print_array(void *a, int cnt, ...) {
va_list lst;
va_start(lst, cnt);
print_array_v(a, cnt, lst);
va_end(lst);
}
以下是一个示例驱动程序:
int main(int argc, char ** argv) {
int i,j,k,l;
l = 0;
int ***a = malloc(2 * sizeof(int **));
for (i=0;i!=2;++i) {
a[i] = malloc(2 * sizeof(int *));
for(j=0;j!=2;++j) {
a[i][j] = malloc(2 * sizeof(int));
for(k=0;k!=2;++k) {
a[i][j][k] = ++l;
printf("(%d %d %d) %d\n", i, j, k, a[i][j][k]);
}
}
}
print_array(a, 3, 2, 2, 2);
return 0;
}