C语言中的可变大小矩阵
创建一个大小为n的单脚本浮点数组。我可以为双脚本数组做一些类似的事情吗?在这方面有一个很好的章节。您可以为多维数组做几乎相同的事情C语言中的可变大小矩阵,c,dynamic,size,C,Dynamic,Size,创建一个大小为n的单脚本浮点数组。我可以为双脚本数组做一些类似的事情吗?在这方面有一个很好的章节。您可以为多维数组做几乎相同的事情 float **array; array = calloc(sizeof(float*), n); for(int i = 0; i < n; i++) { array[i] = calloc(sizeof(float), n); } float**数组; 数组=calloc(sizeof(float*),n; 对于(int i=0;i3。这有点误导
float **array;
array = calloc(sizeof(float*), n);
for(int i = 0; i < n; i++)
{
array[i] = calloc(sizeof(float), n);
}
float**数组;
数组=calloc(sizeof(float*),n;
对于(int i=0;i
如果您想要一个包含n行和m列的矩阵,那么可以使用长度为m*n
的线性数组来表示,其中每个索引i
表示
row = i / n
col = i % n
以及逆映射
i = row * n + col
大多数使用矩阵(如matlab)的代数软件包实际上都使用这种表示法,因为它可以很好地推广到任何维度(您也可以将其推广到三维矩阵)。C中没有双脚本数组;只有数组的数组。例如,这:
int a[3][3];
应读作“3个3整数数组的数组”,而不是“3x3整数数组”。这可以从表达式类型中立即看到,例如,a[0]
是有效的表达式,其类型为int[3]
对于数组类型,数组大小是类型的一部分,因此必须在编译时知道。因此,虽然您可以使用“指向数组的指针”类型使一维成为动态的,但其余的类型仍然必须是固定的:
int (*p)[3] // pointer to arrays of 3 ints each
有两种传统的解决办法:
(y*width+x)
所示int** a = malloc(sizeof(int*) * height);
for (i = 0; i < height; ++i) a[i] = malloc(sizeof(int) * width);
a[0][0] = 123;
...
不,那是不可能的。或者,分配一个数组,并定义一个索引函数,该函数获取坐标并将索引返回到数组中
int Index(int i, int j, int numCols)
{
return i * numCols + j;
}
int numRows = 100;
int numCols = 200;
float *data = malloc(sizeof(float) * numRows * numCols);
data[Index(34, 56, numCols)] = 42.0f;
您可以使用C99可变长度数组(与gcc配合使用):
#包括
#包括
void foo(行大小、列大小、浮点数组[行][列])
{
printf(“%f\n”,数组[2][3]);
}
内部主(空)
{
行的大小=4;
尺寸=5;
float(*array)[cols]=calloc(sizeof(float),行*cols);
数组[2][3]=42;
foo(行、列、数组);
}
我很惊讶没有人指出“明显的”替代方案,它保留了主矩阵的单个连续分配,但有指针向量来提供双下标。(我想这意味着这并不明显。)
显然,我们还需要检查内存分配。在这一点上,我可以调用array[2][3]=5吗?当然,假设n>3。这有点误导——一个二维数组
double[][]
占用一个内存段,而它为每行存储指向段的指针数组。当然,您仍然可以使用数组下标访问它,但它肯定不是同一回事。@wolfPack88:是的,但您一定要了解它是如何工作的array[2]
是存储在数组中的第三个float*
指针,而array[3]
接受存储在array[2]
指向的内存中的第四个float
指针:这增加了允许可变长度行的灵活性。对于矩阵的数学概念建模来说,这不是必需的,但可能很有用。@Jefromi这是真的,但您可以做类似的事情,并拥有连续的内存。“您可以使用C99可变长度数组。”但请不要使用:)@鲍比:如果你的编译器支持它们,我看不出有什么理由不支持它们——特别是在这样一个不涉及堆栈分配的情况下……我想你的意思是*(数据+34*200+56)=42.0f。。。我通常更喜欢读写风格。在第二种方法中,您不需要对数组的每一行执行一次malloc
——您仍然可以在一个大的块中分配它,然后将行指针分配到该分配中的位置。有关选项1的额外示例,请参见我的回答
int Index(int i, int j, int numCols)
{
return i * numCols + j;
}
int numRows = 100;
int numCols = 200;
float *data = malloc(sizeof(float) * numRows * numCols);
data[Index(34, 56, numCols)] = 42.0f;
#include <stdio.h>
#include <stdlib.h>
void foo(size_t rows, size_t cols, float array[rows][cols])
{
printf("%f\n", array[2][3]);
}
int main(void)
{
size_t rows = 4;
size_t cols = 5;
float (*array)[cols] = calloc(sizeof (float), rows * cols);
array[2][3] = 42;
foo(rows, cols, array);
}
float **array2d = malloc(sizeof(*array2d) * height);
float *array1d = malloc(sizeof(*array1d) * height * width);
for (i = 0; i < height; ++i)
array2d[i] = &array1d[i * width];
array2d[0][0] = 123.0;