函数返回一个指向数组的指针 [英] Function returning a Pointer to an Array
问题描述
我设法赢得成功在 C
有变长数组工作,我现在有以下几点:
的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;INT(*富(为size_t行,为size_t COL))[3];诠释主要(无效){
为size_t行,列;
的printf(给ROW:);
如果(scanf的(%つ,&放大器;!行)= 1){
的printf(错误,scanf函数ROW \\ n);
出口(1);
} 的printf(给COL:);
如果(scanf函数(%俎,&安培;!COL)= 1){
的printf(错误,scanf函数COL \\ n);
出口(2);
} INT(* ARR)[COL] = foo的(行,列); 用于(为size_t我= 0; I<排;我++){
用于(为size_t J = 0; J<西; J ++){
的printf(%d个*(*(ARR + I)+ J));
}
} 免费(ARR);
}
INT(*富(为size_t行,为size_t COL))[3] {
INT(* ARR)[COL] =的malloc(行* COL *的sizeof(INT));
int类型l = 0; 如果(ARR == NULL){
的printf(错误,malloc的\\ n);
出口(3);
} 用于(为size_t我= 0; I<排;我++){
用于(为size_t J = 0; J<西; J ++){
*(*(ARR + I)+ J)= 1;
升++;
}
} 返回ARR;
}
输出:
给该行:2
给COL:5
0 1 2 3 4 5 6 7 8 9
现在这样:
INT(*富(为size_t行,为size_t COL))[3] {/ * code * /}
意味着,如果我明白,返回一个指向一个int数组3右声明富与两个参数(为size_t行,为size_t COL)的功能。
我不完全能够理解这种功能,它是更复杂,我现在变长数组时的大小只在运行时知道,但我觉得这是一件好事。我与 C11
标准只工作。
任何方式在这里 INT(*富(为size_t行,为size_t COL))[3]
我有这样的[3]这我不清楚它是如何工作我怎样才能使人们有可能在运行时(当然前提是可能的),像 INT(*富(为size_t行,为size_t COL))[SIZE]
。
我读 C
一些书,但没有对这种情况的解释准确和谷歌也没有帮助,所以我有两个问题:
1)本posiible INT(*富(为size_t行,为size_t COL))[SIZE]
,其中大小必须参数?或者我应该声明此功能的另一种方式?
2),这是什么我想在这里以正确的方式,或者有另一种选择?
我只是想返回一个指向一个数组,其中大小知道在运行时,不编译时间。 的malloc
和免费
的通话只发生一次,这是一个很好的方法,因为每当的malloc
被调用时,我们的程序干扰内核分配内存和标记页面writable.So这种方法有较少的头顶上内核
。
它可以写在一个的malloc
与VLA的工作。
编辑:
@ChronoKitsune说,我应该使用/尝试 []
(未指定大小的数组)在这种情况下功能将变成这个样子:
INT(*富(为size_t行,为size_t COL))[] {/ * code * /}
这是我应该用什么?
任何方式在这里
INT(*富(为size_t行,为size_t COL))[3]
我有这样的[3]
这我不清楚它是如何工作
块引用>类型声明是最容易从里面出来读。我会从简单的开始,并建立你的例子。如果你写
INT富[3];
或
INT(富)[3];
您声明
富
为3INT
秒的数组。这里的括号服务于precedence导向分组功能,就像前pressions,但他们是不必要的,因为类型是间$ P $在这两种情况下PTED以同样的方式。如果你写
INT(*富)[3];
您声明
富
是一个的指针的到数组3INT
秒。等价地,你可以阅读的话说,事情富
指的是3INT
秒的阵列,它是隐含的富
是一个指针。在这种情况下,括号是必要的;没有他们,你会声明富
为3一个int数组*
。如果你写
INT(*富(为size_t行,为size_t COL))[3];
您声明
富
是采取类型的两个参数的函数为size_t
,其返回值指向一个数组3INT
秒。
和我怎样才能使人们有可能在运行时(当然前提是可能的),像
INT(*富(为size_t行,为size_t COL))[SIZE]
。
块引用>如果
尺寸
不是一个编译时间常数,那么你不能做到这一点。 C2011认为
如果一个标识符被声明为具有可变类型的,应当[...]没有联动,要么块范围或函数原型范围。 [...]
块引用>(6.7.6.2/2)
在换句话说,因为所有的功能的文件的范围和内部或外部联动,函数的返回类型不能VLAS,指针VLAS,或任何这样的类型(这些是可变改性的类型)。
一般地,在这种情况下,其中一个返回指针到所述阵列的所述第一元件,而不是一个指向整个阵列。所指向的地址是相同的任一方式,但类型不同的是:
为int * foo的(为size_t行,为size_t列);
返回类型不携带的长度信息所指向的数组,但如果C允许函数返回可变修饰类型那么无论如何都会依赖于该code可以知道该变量的机制尺寸在任何特定的情况下。换句话说,如果你不知道独立于函数的返回类型的预期数组长度,那么有没有办法,你也可以使用一个可变修饰的返回类型反正。
如果你确实需要的功能都返回一个指向元素的运行时确定的数也的元素的数量,那么你可以返回含有一个结构,或者你可以返回1或通过指针参数的两个值。
更新
也可以声明你的函数返回一个指向未指定大小的数组,因为@ChronoKitsune建议。语法是
INT(*栏(为size_t行,为size_t COL))[];
,但是你会发现,返回类型更难几乎在每一个方式使用。例如,它是棘手和丑陋来声明可以保存返回值的变量:
INT(* array_ptr)[] =栏(X,Y);
和访问的内容所指向的数组:
INT Z =(* array_ptr)[1];
对比度与
为int * PTR = foo的(X,Y);
INT W = ptr的[2];I managed to succed to work with Variable length Arrays in
C
and I have now the following:#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; }
Output:
Give the ROW: 2 Give the COL: 5 0 1 2 3 4 5 6 7 8 9
Now This:
int (*foo(size_t row, size_t col))[3]{ /* code */ }
means, if I understood right that declares foo as a function with two parameters (size_t row, size_t col) that returns a pointer to an array 3 of int.
I'm not entirely capable to understand this kind of Function and it is more complicated for me now working with Variable length Arrays when the size is known only at run time, but I find this a good thing. I am working only with
C11
standard.Any way here
int (*foo(size_t row, size_t col))[3]
I have this [3] which I'm not clear about how it works and how can I make it possible on run time (of course only if is possible), something likeint (*foo(size_t row, size_t col))[SIZE]
.I read some books about
C
, but there is no exactly explanations about this situation and Google doesn't help either, so I have two Questions:1) Is this posiible
int (*foo(size_t row, size_t col))[SIZE]
, where SIZE has to be parameter? Or should i declare this Function in another way?2) is this the right way for what I tried here, or there is another alternative?
I'm only trying to return a pointer to an array where the size is know at run time and not compile time. The call of
malloc
andfree
happens only one time and this is a good approach, because whenevermalloc
is called, our program disturb kernel to allocate memory and mark page as writable.So this method have less over head onkernel
. It can be written in onemalloc
working with VLA'sEDIT:
@ChronoKitsune said that i should use/try
[]
(array of unspecified size) in which case the function will become like this:int (*foo(size_t row, size_t col))[]{ /* code */ }
Is this what i should use?
解决方案Any way here
int (*foo(size_t row, size_t col))[3]
I have this[3]
which I'm not clear about how it worksType declarations are most easily read from inside out. I'll start simple, and build up to your example. If you write
int foo[3];
or
int (foo)[3];
you are declaring
foo
as an array of 3int
s. The parentheses here serve a precedence-directing grouping function, just like in expressions, but they are unnecessary because the type is interpreted the same way in both cases.If you write
int (*foo)[3];
you are declaring
foo
to be a pointer to an array of 3int
s. Equivalently, you can read that as saying that the thingfoo
points to is an array of 3int
s, with it being implicit thatfoo
is a pointer. In this case the parentheses are necessary; without them you would be declaringfoo
as an array of 3int *
.If you write
int (*foo(size_t row, size_t col))[3];
you are declaring that
foo
is a function taking two arguments of typesize_t
, whose return value points to an array of 3int
s.and how can I make it possible on run time (of course only if is possible), something like
int (*foo(size_t row, size_t col))[SIZE]
.If
SIZE
is not a compile-time constant then you cannot do that. C2011 holds thatIf an identifier is declared as having a variably modified type, it shall [...] have no linkage, and have either block scope or function prototype scope. [...]
(6.7.6.2/2)
In other words, because all functions have file scope and either internal or external linkage, function return types cannot be VLAs, pointers to VLAs, or any such type (these are "variably-modified" types).
Generally, in such cases one returns a pointer to the first element of the array rather than a pointer to the whole array. The pointed-to address is the same either way, but the type is different:
int *foo(size_t row, size_t col);
The return type does not carry information about the length of the pointed-to array, but if C allowed functions to return variably-modified types then that would rely anyway on a mechanism by which the code could know the variable dimensions in any particular context. In other words, if you don't know the expected array length independent of the function's return type, then there's no way you could have used a variably-modified return type anyway.
If indeed you need the function to return both a pointer to a runtime-determined number of elements and also the number of elements, then you can return a struct containing both, or you can return one or both values via pointer parameters.
Update:
It is also possible to declare your function to return a pointer to an array of unspecified size, as @ChronoKitsune suggested. The syntax would be
int (*bar(size_t row, size_t col))[];
, but you will find that return type harder to use in almost every way. For example, it is trickier and uglier to declare variables that can hold the return value:
int (*array_ptr)[] = bar(x, y);
and to access elements of the pointed-to array:
int z = (*array_ptr)[1];
Contrast that with
int *ptr = foo(x, y); int w = ptr[2];
这篇关于函数返回一个指向数组的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!