我对C相对陌生,我需要一些处理数组的方法的帮助。来自Java编程,我习惯于能够说int[]方法(),以返回一个数组。然而,我发现在C语言中,当你返回数组时,你必须使用指针。作为一个新程序员,我真的不明白这一点,即使我浏览了许多论坛。

基本上,我试图写一个方法,返回一个字符数组在c。我将提供方法(让我们称之为returnArray)与一个数组。它将从前一个数组创建一个新数组,并返回指向该数组的指针。我只是需要一些帮助,如何得到这个开始,以及如何读取指针一旦它被发送出数组。

数组返回函数的建议代码格式

char *returnArray(char array []){
  char returned [10];
  // Methods to pull values from the array, interpret
  // them, and then create a new array
  return &(returned[0]); // Is this correct?
}

函数的调用方

int main(){
  int i = 0;
  char array [] = {1, 0, 0, 0, 0, 1, 1};
  char arrayCount = 0;
  char* returnedArray = returnArray(&arrayCount); // Is this correct?
  for (i=0; i<10; i++)
    printf(%d, ",", returnedArray[i]); // Is this correctly formatted?
}

我还没有测试这个,因为我的C编译器还没有工作,但我想弄清楚这一点。


当前回答

在c语言中,你不能从函数返回数组。你也不能(不应该)这样做:

char *returnArray(char array []){
 char returned [10];
 //methods to pull values from array, interpret them, and then create new array
 return &(returned[0]); //is this correct?
} 

Returned是创建时带有自动存储持续时间,一旦它离开声明作用域,即函数返回时,对它的引用将失效。

您需要动态分配函数内部的内存,或者填充调用方提供的预分配缓冲区。

选项1:

动态分配函数内部的内存(调用者负责释放ret)

char *foo(int count) {
    char *ret = malloc(count);
    if(!ret)
        return NULL;

    for(int i = 0; i < count; ++i) 
        ret[i] = i;

    return ret;
}

这样称呼它:

int main() {
    char *p = foo(10);
    if(p) {
        // do stuff with p
        free(p);
    }

    return 0;
}

选项2:

填充调用方提供的预分配缓冲区(调用方分配buf并传递给函数)

void foo(char *buf, int count) {
    for(int i = 0; i < count; ++i)
        buf[i] = i;
}

像这样称呼它:

int main() {
    char arr[10] = {0};
    foo(arr, 10);
    // No need to deallocate because we allocated 
    // arr with automatic storage duration.
    // If we had dynamically allocated it
    // (i.e. malloc or some variant) then we 
    // would need to call free(arr)
}

其他回答

在本例中,您在堆栈上创建了一个数组,一旦离开函数作用域,该数组将被释放。相反,创建一个动态分配的数组并返回指向它的指针。

char * returnArray(char *arr, int size) {
    char *new_arr = malloc(sizeof(char) * size);
    for(int i = 0; i < size; ++i) {
        new_arr[i] = arr[i];
    }
    return new_arr;
}

int main() {

    char arr[7]= {1,0,0,0,0,1,1};
    char *new_arr = returnArray(arr, 7);

    // don't forget to free the memory after you're done with the array
    free(new_arr);

}

您的方法将返回一个局部堆栈变量,该变量将严重失败。要返回一个数组,请在函数外部创建一个数组,按地址将其传递到函数中,然后修改它,或者在堆上创建一个数组并返回该变量。两者都可以工作,但是第一个不需要任何动态内存分配来使其正确工作。

void returnArray(int size, char *retArray)
{
  // work directly with retArray or memcpy into it from elsewhere like
  // memcpy(retArray, localArray, size); 
}

#define ARRAY_SIZE 20

int main(void)
{
  char foo[ARRAY_SIZE];
  returnArray(ARRAY_SIZE, foo);
}

在c语言中,你不能从函数返回数组。你也不能(不应该)这样做:

char *returnArray(char array []){
 char returned [10];
 //methods to pull values from array, interpret them, and then create new array
 return &(returned[0]); //is this correct?
} 

Returned是创建时带有自动存储持续时间,一旦它离开声明作用域,即函数返回时,对它的引用将失效。

您需要动态分配函数内部的内存,或者填充调用方提供的预分配缓冲区。

选项1:

动态分配函数内部的内存(调用者负责释放ret)

char *foo(int count) {
    char *ret = malloc(count);
    if(!ret)
        return NULL;

    for(int i = 0; i < count; ++i) 
        ret[i] = i;

    return ret;
}

这样称呼它:

int main() {
    char *p = foo(10);
    if(p) {
        // do stuff with p
        free(p);
    }

    return 0;
}

选项2:

填充调用方提供的预分配缓冲区(调用方分配buf并传递给函数)

void foo(char *buf, int count) {
    for(int i = 0; i < count; ++i)
        buf[i] = i;
}

像这样称呼它:

int main() {
    char arr[10] = {0};
    foo(arr, 10);
    // No need to deallocate because we allocated 
    // arr with automatic storage duration.
    // If we had dynamically allocated it
    // (i.e. malloc or some variant) then we 
    // would need to call free(arr)
}

你可以使用这样的代码:

char *MyFunction(some arguments...)
{
    char *pointer = malloc(size for the new array);
    if (!pointer)
        An error occurred, abort or do something about the error.
    return pointer; // Return address of memory to the caller.
}

当您这样做时,稍后应该通过将地址传递给free来释放内存。

还有其他选择。例程可以返回指向某个现有结构的一部分的数组(或数组的一部分)的指针。调用方可能传递一个数组,例程只向数组中写入,而不为新数组分配空间。

使用这个美味的邪恶实现:

array.h

#define IMPORT_ARRAY(TYPE)    \
    \
struct TYPE##Array {    \
    TYPE* contents;    \
    size_t size;    \
};    \
    \
struct TYPE##Array new_##TYPE##Array() {    \
    struct TYPE##Array a;    \
    a.contents = NULL;    \
    a.size = 0;    \
    return a;    \
}    \
    \
void array_add(struct TYPE##Array* o, TYPE value) {    \
    TYPE* a = malloc((o->size + 1) * sizeof(TYPE));    \
    TYPE i;    \
    for(i = 0; i < o->size; ++i) {    \
        a[i] = o->contents[i];    \
    }    \
    ++(o->size);    \
    a[o->size - 1] = value;    \
    free(o->contents);    \
    o->contents = a;    \
}    \
void array_destroy(struct TYPE##Array* o) {    \
    free(o->contents);    \
}    \
TYPE* array_begin(struct TYPE##Array* o) {    \
    return o->contents;    \
}    \
TYPE* array_end(struct TYPE##Array* o) {    \
    return o->contents + o->size;    \
}

c

#include <stdlib.h>
#include "array.h"

IMPORT_ARRAY(int);

struct intArray return_an_array() {
    struct intArray a;
    a = new_intArray();
    array_add(&a, 1);
    array_add(&a, 2);
    array_add(&a, 3);
    return a;
}

int main() {
    struct intArray a;
    int* it;
    int* begin;
    int* end;
    a = return_an_array();
    begin = array_begin(&a);
    end = array_end(&a);
    for(it = begin; it != end; ++it) {
        printf("%d ", *it);
    }
    array_destroy(&a);
    getchar();
    return 0;
}