我相对知道C,我习惯用Java编程,所以我发现C在数组方面有点困难。在这种情况下我仍然赞同自己:
int a [];
int* a;
int *a;
在java中,我会做这样的事情来返回一个函数中的数组:
int [] returnArr(int [] a){
... modify a ...
return a;
}
int [] a = {...};
int [] b = returnArr(a); ##
我如何在C中做同样的事情,特别是##。
的部分EDITED: 我有这个功能:
float *normalizeValues(float *v, float maxY){
int size = sizeof(v) / sizeof(float);
float max = findMax(v);
float ratio = maxY / max;
int i;
for(i = 0; i < size ; ++i){
v[i] = v[i] * ratio;
}
return v;
}
我正在做以下事情:
float vert [] = {306, 319, 360, 357, 375, 374, 387, 391, 391, 70, 82, 94, 91, 108, 114, 125, 127, 131};
int i = 0;
float *vert2;
vert2 = normalizeValues(vert, 0.7);
for(i = 0; i < sizeof(vert2) / sizeof(float); ++i){
fprintf(stdout,": %f\n",vert2[i]);
}
输出只有1个元素。
答案 0 :(得分:1)
你做不到。当函数返回时,堆栈帧将被消除(通常),并且生成的数组将被破坏。但是,您可以编辑函数原型以接受指向要修改的数组的指针。这种函数参数称为“输出参数”。例如:
void function func(int a, int b, int[2] to_modify)
{
to_modify[0] = a;
to_modify[1] = b;
}
int main()
{
int foo[2];
func(1, 2, foo);
printf("Result: foo[0] = %d, foo[1] = %d\n", foo[0], foo[1]);
return 0;
}
这将打印“结果:foo [0] = 1,foo [1] = 2”。
答案 1 :(得分:1)
编辑:直接回答您更新的问题:您必须传入数组的大小。 C没有像Java那样存储数组大小的机制。如果编译器知道数组的大小,因为数组是全局或局部变量,而不是动态分配,那么您可以使用sizeof()运算符。否则,您必须分别知道大小,或使用数组中的sentinel值(例如最后的0.0或NULL)。
一般来说,对于数组,指针和参数,请参见下文:
您将返回一个指向数组的指针,该指针用'*'语法表示:
int *returnArr(int[] a) {
// modify a...
return a;
}
int a[] = { ... };
int *b;
b = returnArr(a);
有几点需要注意:
括号在变量名之后,与Java不同,它们是类型的一部分。尽管Java的语法更加一致,但在C语言中它并不常见,你经常在变量声明的括号中给出数组大小:
int a[3] = { ... };
没有办法指定函数返回数组而不是普通指针。在C中,数组引用衰减为指针(尽管指针和数组并不像通常所声称的那样)。这意味着无论何时传递数组,C只提供传递指向数组的指针的方法。整个数组实际上并未复制。碰巧,数组的名称也是指向数组第一个元素的指针。
请注意用户268396在回答中的内容。如果你打算创建一个新数组并返回它,你需要动态分配数组,或者传入一个指向已经分配的数组的指针(这似乎是你在做什么)
答案 2 :(得分:1)
希望这有帮助
#include<stdio.h>
void change(int *c)/*Pointer c now has the first location of the array a[]*/
{
*(c+0) = 0;/*assign values to the array by adding step-size to the first array position*/
*(c+1) = 1;
*(c+2) = 2;
*(c+3) = 3;
*(c+4) = 4;
}
main()
{
int a[5]={10,20,30,40,50}; /* Declare and Assign an array a[] of size 5.*/
int *b = a; /*Declare and assign a Pointer to the location of the array.*/
change(b); /*pass the pointer(which is now pointing to first position of array) to the change() function.*/
printf("%d,%d,%d,%d,%d,",a[0],a[1],a[2],a[3],a[4]);/*Print the changed value.*/
}
输出:0,1,2,3,4,
从Java的角度来看,指针就像(不完全是)对象引用一样。
Object O;
O = New SomeClassName();
类似对象引用O指向SomeClassName类型的某个实际对象,C中的指针也是如此:
int *b;
b = &a;
变量b只是指向a的地址位置。 深入研究数组概念:
int a[5];
int *b = a;
我们只是说 Mr. * b 指向 a 组的第一个位置,即 a [0] 。
现在C中的电源指针是从现在开始的,在此之后:
*b means a[0]
*(b+1) means a[1]
*(b+2) means a[2]
*(b+3) means a[3]
*(b+4) means a[4]
这意味着你改变了*(b + 4),你正在改变一个[4]。
答案 3 :(得分:0)
int* returnArr(int a[]){
//modify a
return a;
}
需要注意的是,当您在函数的参数列表中使用数组时,它将被转换为指针。所以在main(...)的声明中,char *argv[]
和char **argv
实际上是相同的。在这种情况下,int a[]
和int*
a是相同的。但是数组和指针不是一回事。
以下面的代码为例:
int a[10];
int main(){
int *p = a;
p[5] = 4;
return p[5];
}
p是一个指针,当我们访问p [i]时,请注意p的地址不是a的地址,p的内容是a的地址。然后代码将:
a是一个int数组,如果我们访问一个[i],a的地址只是一个[0]的地址,代码将:
指针和数组是不同的类型。因此,如果您在一个文件中声明int * p并在该文件中使用它,但将p定义为另一个文件中的数组,则会导致问题。
你可能也想知道在ANSI中,int * p = a,如果你使用一个数组(它的名字)作为表达式,编译器会把它转换成一个指针,指向数组的第一个元素。
根据Jim Balter的评论更新:
如果使用数组(其名称)作为表达式,编译器将并不总是将其转换为指针,指向数组的第一个元素。例如,在sizeof(p-> q-> a)中,p-> q-> a是表达式但是如果a是数组,则它不会被转换为指针。
“除非它是sizeof运算符或一元&amp;的操作数。 operator,或者是用于初始化数组的字符串文字,a 具有类型''数组类型''的表达式将转换为 带有''指向类型'的指针的表达式,指向初始值 数组对象的元素。
答案 4 :(得分:0)
在C中,您只能在函数中返回数组的指针。 例如,如果要在函数中返回字符串(char数组),则可以返回指向空结束字符串的指针。如果要返回其他类型的数组(int,用户定义的struct等),可以分配一些内存来存储数组,并返回数组的指针,返回参数中数组的大小。 例如:
int *function(int *size)
{
*size = 10;
int *intP = (int *)malloc((*size)*sizeof(int));
return intP;
}