如何从C中的函数返回字符数组?

时间:2022-01-08 19:35:34

is that even possible? Let's say that I want to return an array of two characters

甚至可能吗?假设我想返回一个包含两个字符的数组

char arr[2];
arr[0] = 'c';
arr[1] = 'a';

from a function. What type do I even use for the function? Is my only choice to use pointers and void the function? So far I've tried having a char* function or a char[]. Apparently you can only have functions of char(*[]). The only reason I want to avoid using pointers is the fact that the function has to end when it encounters a "return something;" because the value of "something" is a character array (not a string!) that might change size depending on the values I pass into the function through the main function. Thanks to anyone who responds in advance.

来自一个功能。我甚至用什么类型的功能?我唯一的选择是使用指针并使函数无效吗?到目前为止,我已经尝试过使用char *函数或char []。显然你只能有char(* [])的功能。我想避免使用指针的唯一原因是函数必须在遇到“返回内容”时结束。因为“something”的值是一个字符数组(不是字符串!),它可能会根据我通过main函数传递给函数的值来改变大小。感谢提前回复的任何人。

6 个解决方案

#1


13  

You've got several options:

你有几个选择:

1) Allocate your array on the heap using malloc(), and return a pointer to it. You'll also need to keep track of the length yourself:

1)使用malloc()在堆上分配数组,并返回指向它的指针。您还需要自己跟踪长度:

void give_me_some_chars(char **arr, size_t *arr_len)
{
    /* This function knows the array will be of length 2 */
    char *result = malloc(2);

    if (result) {
        result[0] = 'c';
        result[1] = 'a';
    }

    /* Set output parameters */
    *arr = result;
    *arr_len = 2;
}

void test(void)
{
    char *ar;
    size_t ar_len;
    int i;

    give_me_some_chars(&ar, &ar_len);

    if (ar) {
        printf("Array:\n");
        for (i=0; i<ar_len; i++) {
            printf(" [%d] = %c\n", i, ar[i]);
        }
        free(ar);
    }
}

2) Allocate space for the array on the stack of the caller, and let the called function populate it:

2)在调用者的堆栈上为数组分配空间,并让被调用的函数填充它:

#define ARRAY_LEN(x)    (sizeof(x) / sizeof(x[0]))

/* Returns the number of items populated, or -1 if not enough space */
int give_me_some_chars(char *arr, int arr_len)
{
    if (arr_len < 2)
        return -1;

    arr[0] = 'c';
    arr[1] = 'a';

    return 2;
}

void test(void)
{
    char ar[2];
    int num_items;

    num_items = give_me_some_chars(ar, ARRAY_LEN(ar));

    printf("Array:\n");
    for (i=0; i<num_items; i++) {
        printf(" [%d] = %c\n", i, ar[i]);
    }
}

DO NOT TRY TO DO THIS

不要试图这样做

char* bad_bad_bad_bad(void)
{
    char result[2];      /* This is allocated on the stack of this function
                            and is no longer valid after this function returns */

    result[0] = 'c';
    result[1] = 'a';

    return result;    /* BAD! */
}

void test(void)
{
    char *arr = bad_bad_bad_bad();

    /* arr is an invalid pointer! */
}

#2


0  

You can pass the array to the function and let the function modify it, like this

你可以将数组传递给函数,然后让函数修改它,就像这样

void function(char *array)
 {
    array[0] = 'c';
    array[1] = 'a';
 }

and then

char array[2];

function(array);
printf("%c%c\n", array[0], array[1]);

If you want it as a return value, you should use dynamic memroy allocation,

如果您希望它作为返回值,则应使用动态memroy分配,

char *function(void)
 {
    char *array;

    array = malloc(2);
    if (array == NULL)
        return NULL;
    array[0] = 'c';
    array[1] = 'a';

    return array;
 }

then

char *array = function();
printf("%c%c\n", array[0], array[1]);
/* done using `array' so free it because you `malloc'ed it*/
free(array);

Important Note:

You should be aware of the fact that the array as filled above is not a string, so you can't for instance do this

您应该知道上面填充的数组不是字符串,因此您无法执行此操作

printf("%s\n", array);

because the "%s" expects a matching string to be passed, and in c an array is not a string unless it's last character is '\0', so for a 2 character string you need to allocate space for 3 characters and set the last one to '\0'.

因为“%s”需要传递匹配的字符串,而在c中数组不是字符串,除非它的最后一个字符是'\ 0',所以对于2个字符的字符串,你需要为3个字符分配空间并设置最后一个为'\ 0'。

#3


0  

You can return a pointer for the array from a function, however you can't return pointers to local arrays, the reference will be lost.

您可以从函数返回数组的指针,但是不能返回指向本地数组的指针,引用将会丢失。

So you have 3 options:

所以你有3个选择:

  1. Use a global variable:

    使用全局变量:

    char arr[2];
    
    char * my_func(void){
        arr[0] = 'c';
        arr[1] = 'a';
        return arr;
    }
    
  2. Use dinamic allocation (the caller will have the responsability to free the pointer after using it, make it clear in your documentation)

    使用dinamic分配(调用者将负责在使用后释放指针,在文档中明确说明)

    char * my_func(void){
    
        char *arr;    
        arr = malloc(2);
        arr[0] = 'c';
        arr[1] = 'a';
    
        return arr;
    }
    
  3. Make the caller allocate the array and use as a reference (my recomendation)

    让调用者分配数组并用作参考(我的推荐)

    void my_func(char * arr){
    
        arr[0] = 'c';
        arr[1] = 'a';
    }
    

if you realy need the function to return the array, you can return the same reference as:

如果你真的需要函数来返回数组,你可以返回相同的引用:

char * my_func(char * arr){
    arr[0] = 'c';
    arr[1] = 'a';
    return arr;
}

#4


0  

Since you have a predetermined size of you array you can in-fact return the array if you wrap it with a struct:

由于你有一个预定大小的数组,如果用结构包装它,你实际上可以返回数组:

struct wrap
{
    char a[2] ;
} ;

struct wrap Get( void )
{
    struct wrap w = { 0 } ;

    w.a[0] = 'c';
    w.a[1] = 'a';

return w ;
}

#5


-1  

This works perfecly:

这完美地工作:

int comm_read_data(int file_i2c, unsigned char** buffer)
{
    *buffer = malloc(BUFFER_SIZE);
    if (i2c_read_bytes(file_i2c, *buffer, BUFFER_SIZE) != 0)
    {
        return -1;
    }
    return BUFFER_SIZE;
}

And then call the function:

然后调用函数:

unsigned char* buffer;
int length = comm_read_data(file_i2c, &buffer);

/* parse the buffer here */

free(buffer);

#6


-2  

char* getCharArray()
{
  return "ca";
}

#1


13  

You've got several options:

你有几个选择:

1) Allocate your array on the heap using malloc(), and return a pointer to it. You'll also need to keep track of the length yourself:

1)使用malloc()在堆上分配数组,并返回指向它的指针。您还需要自己跟踪长度:

void give_me_some_chars(char **arr, size_t *arr_len)
{
    /* This function knows the array will be of length 2 */
    char *result = malloc(2);

    if (result) {
        result[0] = 'c';
        result[1] = 'a';
    }

    /* Set output parameters */
    *arr = result;
    *arr_len = 2;
}

void test(void)
{
    char *ar;
    size_t ar_len;
    int i;

    give_me_some_chars(&ar, &ar_len);

    if (ar) {
        printf("Array:\n");
        for (i=0; i<ar_len; i++) {
            printf(" [%d] = %c\n", i, ar[i]);
        }
        free(ar);
    }
}

2) Allocate space for the array on the stack of the caller, and let the called function populate it:

2)在调用者的堆栈上为数组分配空间,并让被调用的函数填充它:

#define ARRAY_LEN(x)    (sizeof(x) / sizeof(x[0]))

/* Returns the number of items populated, or -1 if not enough space */
int give_me_some_chars(char *arr, int arr_len)
{
    if (arr_len < 2)
        return -1;

    arr[0] = 'c';
    arr[1] = 'a';

    return 2;
}

void test(void)
{
    char ar[2];
    int num_items;

    num_items = give_me_some_chars(ar, ARRAY_LEN(ar));

    printf("Array:\n");
    for (i=0; i<num_items; i++) {
        printf(" [%d] = %c\n", i, ar[i]);
    }
}

DO NOT TRY TO DO THIS

不要试图这样做

char* bad_bad_bad_bad(void)
{
    char result[2];      /* This is allocated on the stack of this function
                            and is no longer valid after this function returns */

    result[0] = 'c';
    result[1] = 'a';

    return result;    /* BAD! */
}

void test(void)
{
    char *arr = bad_bad_bad_bad();

    /* arr is an invalid pointer! */
}

#2


0  

You can pass the array to the function and let the function modify it, like this

你可以将数组传递给函数,然后让函数修改它,就像这样

void function(char *array)
 {
    array[0] = 'c';
    array[1] = 'a';
 }

and then

char array[2];

function(array);
printf("%c%c\n", array[0], array[1]);

If you want it as a return value, you should use dynamic memroy allocation,

如果您希望它作为返回值,则应使用动态memroy分配,

char *function(void)
 {
    char *array;

    array = malloc(2);
    if (array == NULL)
        return NULL;
    array[0] = 'c';
    array[1] = 'a';

    return array;
 }

then

char *array = function();
printf("%c%c\n", array[0], array[1]);
/* done using `array' so free it because you `malloc'ed it*/
free(array);

Important Note:

You should be aware of the fact that the array as filled above is not a string, so you can't for instance do this

您应该知道上面填充的数组不是字符串,因此您无法执行此操作

printf("%s\n", array);

because the "%s" expects a matching string to be passed, and in c an array is not a string unless it's last character is '\0', so for a 2 character string you need to allocate space for 3 characters and set the last one to '\0'.

因为“%s”需要传递匹配的字符串,而在c中数组不是字符串,除非它的最后一个字符是'\ 0',所以对于2个字符的字符串,你需要为3个字符分配空间并设置最后一个为'\ 0'。

#3


0  

You can return a pointer for the array from a function, however you can't return pointers to local arrays, the reference will be lost.

您可以从函数返回数组的指针,但是不能返回指向本地数组的指针,引用将会丢失。

So you have 3 options:

所以你有3个选择:

  1. Use a global variable:

    使用全局变量:

    char arr[2];
    
    char * my_func(void){
        arr[0] = 'c';
        arr[1] = 'a';
        return arr;
    }
    
  2. Use dinamic allocation (the caller will have the responsability to free the pointer after using it, make it clear in your documentation)

    使用dinamic分配(调用者将负责在使用后释放指针,在文档中明确说明)

    char * my_func(void){
    
        char *arr;    
        arr = malloc(2);
        arr[0] = 'c';
        arr[1] = 'a';
    
        return arr;
    }
    
  3. Make the caller allocate the array and use as a reference (my recomendation)

    让调用者分配数组并用作参考(我的推荐)

    void my_func(char * arr){
    
        arr[0] = 'c';
        arr[1] = 'a';
    }
    

if you realy need the function to return the array, you can return the same reference as:

如果你真的需要函数来返回数组,你可以返回相同的引用:

char * my_func(char * arr){
    arr[0] = 'c';
    arr[1] = 'a';
    return arr;
}

#4


0  

Since you have a predetermined size of you array you can in-fact return the array if you wrap it with a struct:

由于你有一个预定大小的数组,如果用结构包装它,你实际上可以返回数组:

struct wrap
{
    char a[2] ;
} ;

struct wrap Get( void )
{
    struct wrap w = { 0 } ;

    w.a[0] = 'c';
    w.a[1] = 'a';

return w ;
}

#5


-1  

This works perfecly:

这完美地工作:

int comm_read_data(int file_i2c, unsigned char** buffer)
{
    *buffer = malloc(BUFFER_SIZE);
    if (i2c_read_bytes(file_i2c, *buffer, BUFFER_SIZE) != 0)
    {
        return -1;
    }
    return BUFFER_SIZE;
}

And then call the function:

然后调用函数:

unsigned char* buffer;
int length = comm_read_data(file_i2c, &buffer);

/* parse the buffer here */

free(buffer);

#6


-2  

char* getCharArray()
{
  return "ca";
}