我设法在C
中成功使用可变长度数组,现在我有以下内容:
#include <stdio.h>
#include <stdlib.h>
int (*foo(size_t row, size_t col))[3];
int main(void){
size_t row, col;
printf("Give the ROW: ");
if ( scanf("%zu",&row) != 1){
printf("Error, scanf ROW\n");
exit(1);
}
printf("Give the COL: ");
if ( scanf("%zu",&col) != 1){
printf("Error, scanf COL\n");
exit(2);
}
int (*arr)[col] = foo(row, col);
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
printf("%d ",*(*(arr+i)+j));
}
}
free(arr);
}
int (*foo(size_t row, size_t col))[3]{
int (*arr)[col] = malloc(row * col * sizeof(int));
int l=0;
if (arr == NULL){
printf("Error, malloc\n");
exit(3);
}
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
*(*(arr+i)+j) = l;
l++;
}
}
return arr;
}
输出:
Give the ROW: 2
Give the COL: 5
0 1 2 3 4 5 6 7 8 9
现在是这样的:
int (*foo(size_t row, size_t col))[3]{ /* code */ }
意思是,如果我理解正确,这将声明foo为一个带有两个参数(size_t row,size_t col)的函数,该函数返回指向int数组3的指针。
我不完全能理解这种函数,现在使用变长数组时更加复杂,因为大小只在运行时知道,但我认为这是一件好事。我仅使用C11标准。
无论如何,在这里,
int (*foo(size_t row, size_t col))[3]
中,我有这个[3],我不清楚它是如何工作的,以及如何可以在运行时使其成为可能(当然只有在可能的情况下),例如int (*foo(size_t row, size_t col))[SIZE]
。我读了一些关于C的书,但没有确切的解释关于这种情况,Google也没有帮助,所以我有两个问题:
1)是否可以实现
int (*foo(size_t row, size_t col))[SIZE]
,其中SIZE必须是参数?或者我应该用另一种方式声明此函数?2)这是我尝试的正确方法,还是有其他替代方案?
我只是尝试返回指向大小在运行时而不是编译时知道大小的数组的指针。一次调用malloc和free,这是一个很好的方法,因为每当调用malloc时,我们的程序会干扰内核来分配内存并标记页面为可写。因此,这种方法在内核上的负载较小。它可以用一个使用VLA的malloc编写。
编辑:
@ChronoKitsune说我应该尝试使用
[]
(未指定大小的数组),在这种情况下,函数将变成这样:int (*foo(size_t row, size_t col))[]{ /* code */ }
这是我应该使用的吗?
[]
(未指定大小的数组)。arr
声明为int *arr = foo(row, col);
并将其用作arr[i * col + j]
(或*(arr + i * col + j)
),或者您可以将返回值强制转换为与arr
的声明匹配,如int (*arr)[col] = (int (*)[col])foo(row, col);
以便能够使用arr[i][j]
(或*(*(arr + i) + j)
,因为您喜欢使用指针符号而不是更易读的等效数组符号)。int (*arr)[col]
。 - Michi[]
正式表示 不完整类型数组(C11 第6.7.6.2p4节)。返回指向该数组的指针是被允许的。但是,在指针赋值为具有完整类型的数组之前,不能解引用该指针。例如,如果您声明了int (*arr)[] = foo(row, col);
,则不能执行*arr
或arr[...]
。int (*arr)[col] = foo(row, col);
是被允许的,您可以按照需要成功使用指针,因为int (*arr)[col]
是一个指向完整类型的指针。 - user539810