这可能是一个愚蠢的问题,但我想知道是否有一种有效的方法来做到这一点。
情况:
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]
然后将其地址设置为数组吗?
(为简单起见,示例中省略了错误处理和内存管理。请将其视为某些功能的一部分。)
答案 0 :(得分:2)
之后:
int* array = malloc(n * m * sizeof(int));
您可以这样做:
int (*M)[m] = (int(*)[m])array;
,然后使用M[1][2]
为例。
您也可以首先这样做:
int (*M)[m] = malloc( n * sizeof *M );
答案 1 :(得分:1)
使用一个指针数组。
#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]);
}
答案 2 :(得分:1)
如果不给全局数组指定特定的数字大小,则不能在C中声明全局数组。这是因为全局变量是静态的,并且编译器无法为全局数组分配可变数量的内存。
在C语言中,您必须记住,数组实际上只是一个指针。当您询问int *array = malloc(n * sizeof(int))
时,您告诉编译器的是您需要n
并排保留的很多4类型的int类型的4字节块,其中{{1}的值}实际上是指向第一个4字节块的指针。
访问数组的元素时,实际上是在进行指针算术并取消对指针的引用,但这在array
语法中是隐藏的。因此,当数组具有int类型时,array[i]
随即转换为数组指针给定的位置(即头部),现在在内存中移动2 * 4字节,并取消引用指针以访问存储在那里的整数。
因此,正如您所讨论的,当您创建二维数组时,确实没有更好的方法。确保牢牢掌握从编译器获得的实际结果。指针(无论如何在64位计算机上)为8个字节,整数为4个字节。因此,当您调用array[2]
时,编译器会为您分配m个宽度为8字节的块,所有块的类型均为int *。
从其他编程语言来看,似乎很重要的一点是必须声明对一个指针块的指针引用,但是通过更高级别的数组概念并将其视为指针的集合,从长远来看确实可以为您提供帮助跑。当您需要在函数之间传递这些数据类型时,您需要能够对自己实际操作的内容有一个清晰的认识。指针,值,指向指针的指针?这将极大地帮助您调试这些想法的代码,因为尝试对指针(而不是值)进行计算非常容易。
3条有用的提示:
int **M = malloc(sizeof(int*) * m
比调用malloc更合适,因为calloc会自动将您的条目初始化为零,而malloc则不会。答案 3 :(得分:1)
棘手的部分是声明变量以保存指向已分配数组的指针;其余的很简单-假设您使用的是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
数组的指针,每个数组的维度为m
。其余代码仅使用具有通常的2下标表示法的数组– M[i][j]
等。可以将其传递给函数。我在这里没有显示它,但是将初始化代码也放入一个函数中,然后在一个函数中具有几个不同大小的矩阵,这很简单。