O tratamento de C de matrizes é muito diferente do Java, e você terá que ajustar seu pensamento de acordo. Matrizes em C não são objetos de primeira classe (ou seja, uma expressão de matriz não mantém sua "matriz" na maioria dos contextos). Em C, uma expressão do tipo "N-elemento da matriz de T" será implicitamente convertida ("decaimento") em uma expressão do tipo "ponteiro para T", exceto quando a expressão da matriz for um operando dos sizeofoperadores ou unários &, ou se o expressão de matriz é uma cadeia de caracteres literal usada para inicializar outra matriz em uma declaração.
Entre outras coisas, isso significa que você não pode passar uma expressão de matriz para uma função e recebê-la como um tipo de matriz ; a função realmente recebe um tipo de ponteiro:
void foo(char *a, size_t asize)
{
// do something with a
}
int bar(void)
{
char str[6] = "Hello";
foo(str, sizeof str);
}
Na chamada para foo, a expressão stré convertida do tipo char [6]para char *, e é por isso que o primeiro parâmetro de fooé declarado em char *avez de char a[6]. Em sizeof str, como a expressão da matriz é um operando do sizeofoperador, ela não é convertida em um tipo de ponteiro; portanto, você obtém o número de bytes na matriz (6).
Se você estiver realmente interessado, pode ler O desenvolvimento da linguagem C, de Dennis Ritchie, para entender de onde vem esse tratamento.
O resultado é que as funções não podem retornar tipos de matriz, o que é bom, pois as expressões de matriz também não podem ser o destino de uma atribuição.
O método mais seguro é o chamador definir a matriz e passar seu endereço e tamanho para a função que deveria escrever para ela:
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);
...
}
Outro método é a função alocar a matriz dinamicamente e retornar o ponteiro e o tamanho:
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);
...
}
Nesse caso, o chamador é responsável por desalocar a matriz com a freefunção de biblioteca.
Observe que dstno código acima é um ponteiro simples para char, não um ponteiro para uma matriz de char. A semântica de ponteiro e matriz de C é tal que você pode aplicar o operador subscrito []a uma expressão do tipo de matriz ou tipo de ponteiro; ambos src[i]e dst[i]acessarão o i'ésimo elemento da matriz (mesmo que apenas srctenha um tipo de matriz).
Você pode declarar um ponteiro para uma matriz de elementos N Te fazer algo semelhante:
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]);
...
}
Várias desvantagens com o acima exposto. Antes de tudo, as versões mais antigas do C esperam SOME_SIZEser uma constante em tempo de compilação, o que significa que a função funcionará apenas com um tamanho de matriz. Em segundo lugar, é necessário desreferenciar o ponteiro antes de aplicar o subscrito, o que atrapalha o código. Ponteiros para matrizes funcionam melhor quando você está lidando com matrizes multidimensionais.