[英]C - Convert array of elements into 2-d matrix
这可能是一个愚蠢的问题,但我想知道是否有一种有效的方法来做到这一点。
情况:
int* array = malloc(n * m * sizeof(int));
//want to convert array into M[n][m]
我现在在做什么:
int** M = malloc(n * sizeof(int*));
for(int i = 0; i < n; i++, array += m)
M[i] = array;
我认为转换不应该如此复杂。 是否提供任何简单的语法C? 我可以声明一个extern M[n][m]
然后将其地址设置为数组吗?
(为简单起见,示例中省略了错误处理和内存管理。请将其视为某些功能的一部分。)
后:
int* array = malloc(n * m * sizeof(int));
你可以做:
int (*M)[m] = (int(*)[m])array;
然后使用M[1][2]
。
您也可以首先这样做:
int (*M)[m] = malloc( n * sizeof *M );
如果不给全局数组指定特定的数字大小,则无法在C中声明全局数组。 这是因为全局变量是静态的,并且编译器无法为全局数组分配可变数量的内存。
在C语言中,您必须记住,数组实际上只是一个指针。 当您要求int *array = malloc(n * sizeof(int))
,您告诉编译器的是,您需要n
个并排保留在内存中的int类型的4个字节的块,其中array
实际上是指向前4个字节块的指针。
当您访问数组的元素时,您实际上是在进行指针算术并取消对指针的引用,但这被隐藏在array[i]
语法中。 因此,当array具有int类型时, array[2]
随即移至数组指针给定的位置(即头部),现在沿内存移动2 * 4字节,并取消引用指针以访问存储在其中的整数。
因此,正如您所讨论的那样,当创建二维数组时,确实没有更好的方法。 确保牢牢掌握从编译器获得的实际结果。 指针(无论如何在64位计算机上)为8个字节,整数为4个字节。 因此,当您调用int **M = malloc(sizeof(int*) * m
,编译器会为您分配m个宽度为8字节的块,所有块的类型均为int *。
从其他编程语言来看,似乎最重要的一点是必须声明对指针块的指针引用,但是从长远来看,通过数组的高级概念并将其视为指针的集合确实可以为您提供帮助。 当您需要在函数之间传递这些数据类型时,您需要能够对自己实际操作的内容有一个清晰的认识。 指针,值,指向指针的指针? 这将极大地帮助您调试这些想法的代码,因为尝试对指针(而不是值)进行计算非常容易。
3个有用的技巧:
calloc(n, sizeof(int))
比调用malloc更合适,因为calloc会自动将您的条目初始化为零,而malloc不会。 棘手的部分是声明变量以保存指向已分配数组的指针。 其余的很简单-假设您使用的是C99或更高版本的编译器。
#include <stdio.h>
#include <stdlib.h>
static void print_2dvla(int rows, int cols, int data[rows][cols])
{
for (int i = 0; i < rows; i++)
{
printf("%2d: ", i);
for (int j = 0; j < cols; j++)
printf(" %4d", data[i][j]);
putchar('\n');
}
}
int main(void)
{
int m = 10;
int n = 12;
int (*M)[m] = malloc(n * m * sizeof(M[0][0]));
if (M == NULL)
{
fprintf(stderr, "Failed to allocate %zu bytes memory\n", n * m * sizeof(M[0][0]));
exit(EXIT_FAILURE);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
M[i][j] = (i + 1) * 100 + (j + 1);
}
print_2dvla(n, m, M);
free(M);
return 0;
}
输出示例:
0: 101 102 103 104 105 106 107 108 109 110
1: 201 202 203 204 205 206 207 208 209 210
2: 301 302 303 304 305 306 307 308 309 310
3: 401 402 403 404 405 406 407 408 409 410
4: 501 502 503 504 505 506 507 508 509 510
5: 601 602 603 604 605 606 607 608 609 610
6: 701 702 703 704 705 706 707 708 709 710
7: 801 802 803 804 805 806 807 808 809 810
8: 901 902 903 904 905 906 907 908 909 910
9: 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010
10: 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
11: 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210
关键是:
int (*M)[m] = malloc(n * m * sizeof(M[0][0]));
这表示M
是指向int
数组的指针,每个int
数组的维数为m
。 其余代码仅使用具有通常的2下标符号— M[i][j]
等的数组。可以将其传递给函数。 我在这里没有显示它,但是将初始化代码也放到一个函数中,然后在一个函数中具有几个不同大小的矩阵,这很简单。
使用指针数组。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n = 3, m = 4, i, j, count=0;
int *array[n];
for(i=0; i<n; i++)
array[i] = (int *)malloc(m * sizeof(int));
if( array[i] == NULL)
{
perror("Unable to allocate array");
exit(1);
}
// going to add number to your 2d array.
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
array[i][j] = ++count;
for (i=0; i < n; i++)
for (j=0; j < m; j++)
printf("%d ", array[i][j]);
// free memory
for(i=0; i<n; i++)
free(array[i]);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.