C's treatment of arrays is very different from Java's, and you'll have to adjust your thinking accordingly. Arrays in C are not first class objects (that is, an array expression does not retain its "array-ness" in most contexts). In C, an expression of type "N-element array of T" will be implicitly converted ("decay") to an expression of type "pointer to T", except when the array expression is an operand of the sizeof or unary & operators, or if the array expression is a string literal being used to initialize another array in a declaration.
除此之外,这意味着您不能将数组表达式传递给函数并将其作为数组类型接收;函数实际接收一个指针类型:
void foo(char *a, size_t asize)
{
// do something with a
}
int bar(void)
{
char str[6] = "Hello";
foo(str, sizeof str);
}
在对foo的调用中,表达式str从char[6]类型转换为char *,这就是为什么foo的第一个参数声明为char *a而不是char[6]。在sizeof str中,由于数组表达式是sizeof操作符的操作数,因此它没有转换为指针类型,因此您得到数组中的字节数(6)。
如果你真的感兴趣,你可以阅读Dennis Ritchie的《C语言的发展》来了解这种处理方法的来源。
结果是函数不能返回数组类型,这很好,因为数组表达式也不能成为赋值的目标。
最安全的方法是调用者定义数组,并将其地址和大小传递给应该写入数组的函数:
void returnArray(const char *srcArray, size_t srcSize, char *dstArray, char dstSize)
{
...
dstArray[i] = some_value_derived_from(srcArray[i]);
...
}
int main(void)
{
char src[] = "This is a test";
char dst[sizeof src];
...
returnArray(src, sizeof src, dst, sizeof dst);
...
}
另一种方法是函数动态分配数组并返回指针和大小:
char *returnArray(const char *srcArray, size_t srcSize, size_t *dstSize)
{
char *dstArray = malloc(srcSize);
if (dstArray)
{
*dstSize = srcSize;
...
}
return dstArray;
}
int main(void)
{
char src[] = "This is a test";
char *dst;
size_t dstSize;
dst = returnArray(src, sizeof src, &dstSize);
...
free(dst);
...
}
在这种情况下,调用方负责使用free library函数释放数组。
注意,上面代码中的dst是一个简单的char指针,而不是一个char数组的指针。C语言的指针和数组语义是这样的,你可以将下标操作符[]应用于数组类型或指针类型的表达式;src[i]和dst[i]都将访问数组的第i个元素(即使只有src具有数组类型)。
你可以声明一个指向T的n元素数组的指针,并做类似的事情:
char (*returnArray(const char *srcArr, size_t srcSize))[SOME_SIZE]
{
char (*dstArr)[SOME_SIZE] = malloc(sizeof *dstArr);
if (dstArr)
{
...
(*dstArr)[i] = ...;
...
}
return dstArr;
}
int main(void)
{
char src[] = "This is a test";
char (*dst)[SOME_SIZE];
...
dst = returnArray(src, sizeof src);
...
printf("%c", (*dst)[j]);
...
}
上述方法有几个缺点。首先,旧版本的C语言期望SOME_SIZE是一个编译时常量,这意味着该函数只能处理一个数组大小。其次,在应用下标之前必须解除对指针的引用,这会使代码变得混乱。在处理多维数组时,指向数组的指针工作得更好。