在C / C ++中传递多维数组

时间:2012-12-25 10:48:55

标签: c++ c arrays

为什么在C / C ++中,接收MD arr的func param需要具有所有子数组/维度的大小?

here(PDF):它说MD的唯一​​不同之处在于 “编译器会记住每个想象的维度”但是当我违反这些维度时,编译器什么都不做,例如:

char arr[3][5];
arr[0][5] = 10;

那么,记住那些尺寸有什么意义呢?

2 个答案:

答案 0 :(得分:7)

对数组的索引访问必须根据索引值声明的较低维度,按行主要顺序计算内存偏移量计算。更多相关内容。

但首先,你的问题与这个简单的观察紧密相关:

void foo( char a[] )
{
    a[5] = 'a';
}

// caller of foo() from somewhere
char arr[5];
foo(arr);

为什么编译器允许你那个?因为这是C,你完全有权利用未定义的行为射击自己的脚。记住这一点:

void foo( char a[][5] )
{
    a[0][5] = 'a';
}

// caller of foo() from somewhere
char arr[4][5];
foo(arr);

它与先前的代码一样“有效”(即您自己有权进入UB,风险和风险)。在这种情况下,它将“工作”,但仅仅因为底层数组的线性背景是20个元素宽,我们只访问第六个元素,技术上arr[1][0]

这些劣等维度的目的是正确计算 this

之类的访问权限
void foo( char a[][5] )
{
    a[2][1] = 'b';
}

2上级索引必须使用声明的下级维度(在本例中为5)来有效地计算适当元素的线性偏移量。在一维线性块中布置2D数组,用于执行此操作:

char arr[20]; // 4*5
arr[2*5+1] = 'b';

请注意5。必须知道声明的劣等维度才能正确计算行间距(演说)。

我希望这至少让它更清晰。

我应该注意这种化合物。即,以下内容:

char arr[3][4][5];
arr[1][2][3] = 'c';

有效地计算与底层数组的线性背景相对应的正确位置:

char arr[60]; // 3*4*5
arr[ 1*(4*5) + 2*(5) + 3 ] = 'c';

等等。把它带到你想要的那么多尺寸。必须知道所有较低的尺寸才能正确地做到这一点。

答案 1 :(得分:2)

数组不是一种特殊的对象,它只是一长串的项目。您的arr[3][5]实际上只是arr[15],而arr[0][5]则被编译器重定向到arr[5]

由于C / C ++不存储尺寸,因此您需要对它们进行硬编码以使[0][5]地图正确地映射到[5]

有些编译器可能会强制[0][5]出错(或警告它),但由于它映射到[5],它至少会做一些事情。