Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从C中的函数返回字符数组?_C_Arrays_Function_Pointers_Character - Fatal编程技术网

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

如何从C中的函数返回字符数组?,c,arrays,function,pointers,character,C,Arrays,Function,Pointers,Character,这可能吗? 假设我想返回一个由两个字符组成的数组 char arr[2]; arr[0] = 'c'; arr[1] = 'a'; 从一个函数。我该使用哪种类型的函数?使用指针并使函数无效是我唯一的选择吗?到目前为止,我已经尝试过使用char*函数或char[]。显然,您只能具有char(*[])的函数。我想避免使用指针的唯一原因是,函数遇到“return something”时必须结束,因为“something”的值是一个字符数组(不是字符串!),它的大小可能会根据我通过主函数传入函数的值而

这可能吗? 假设我想返回一个由两个字符组成的数组

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

从一个函数。我该使用哪种类型的函数?使用指针并使函数无效是我唯一的选择吗?到目前为止,我已经尝试过使用char*函数或char[]。显然,您只能具有char(*[])的函数。我想避免使用指针的唯一原因是,函数遇到“return something”时必须结束,因为“something”的值是一个字符数组(不是字符串!),它的大小可能会根据我通过主函数传入函数的值而变化。感谢所有提前响应的人。

您可以将数组传递给函数,让函数修改它,如下所示

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

char array[2];

function(array);
printf("%c%c\n", array[0], array[1]);
如果要将其作为返回值,则应使用动态memroy分配

char *function(void)
 {
    char *array;

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

    return array;
 }
然后

重要注意事项

您应该知道,上面填充的数组不是字符串,因此您不能这样做

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

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

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);
    }
}

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

因此,您有3种选择:

  • 使用全局变量:

     char arr[2];
    
     char * my_func(void){
         arr[0] = 'c';
         arr[1] = 'a';
         return arr;
     }
    
  • 使用动态分配(调用者有责任在使用指针后释放指针;请在文档中说明这一点)

  • 让调用方分配数组并将其用作引用(我的建议)

  • 如果确实需要函数返回数组,可以返回与以下相同的引用:

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

    由于您有一个预先确定的数组大小,因此如果使用结构将其包装,实际上可以返回该数组:

    struct wrap
    {
        char a[2] ;
    } ;
    
    struct wrap Get( void )
    {
        struct wrap w = { 0 } ;
    
        w.a[0] = 'c';
        w.a[1] = 'a';
    
    return w ;
    }
    
    这很有效:

    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;
    }
    
    然后调用函数:

    unsigned char* buffer;
    int length = comm_read_data(file_i2c, &buffer);
    
    /* parse the buffer here */
    
    free(buffer);
    

    函数应返回char*。你预见到什么问题了?我试过了,但每次都会出错。我只使用char*函数并返回arr;当我尝试输出时,它会出错。gcc还警告我,当我从返回数组时,试图返回不带强制转换的整数above@AnnoyingQuestions因为在函数中声明数组时,它是在函数的堆栈框架中分配的,因此在返回数组时,它会在返回后立即与函数解除分配,它没有被明确解除分配。只是在函数之后使用它可能会导致未定义的行为,因为在此函数之后调用的函数可能会覆盖内存位置(堆栈中)的内容。如果您给我们的三行代码在一个函数中,那么您试图在它超出范围后返回一个局部,所以是的,这将导致故障。事实上,它是一个数组与此无关。还有另一个完全有效的选项:
    返回“ca”
    @DanKorn当然可以,但我认为您过分简化了问题。可以肯定地说,OP的代码比返回一些固定值要复杂得多(没有意义)。我不能说这背后是否有更多的复杂性。你在做假设。我能做以下工作吗
    int comm_read_info(int file_i2c,unsigned char*buffer){unsigned char*read_buffer=malloc(57);/*此函数知道它是57字节*/if(i2c_read_bytes(file_i2c,read_buffer,sizeof(read_buffer))!=0{*buffer=result;返回0;}返回-1;}
    @Elephant评论不是用来提问的——代码的长段是不可读的。你应该。但是不,那是行不通的;这里的类型不匹配:
    *buffer=result
    您需要
    comm\u read\u info(int file\u i2c,unsigned char**buffer)
    返回指向缓冲区的指针。还有一个非常有效的选项:
    返回“ca”。根据定义,硬编码字符串是静态内存。如果需要以null结尾的字符串,只需
    返回“ca”。这没有错。这是对原始问题的完全正确的回答。“上述答案”并不会以任何方式使其无效。我的解决方案没有返回指向局部变量的指针的问题,因为硬编码字符串在定义上是静态的。该函数是完全安全和有效的。
    
     void my_func(char * arr){
    
         arr[0] = 'c';
         arr[1] = 'a';
     }
    
    char * my_func(char * arr){
        arr[0] = 'c';
        arr[1] = 'a';
        return arr;
    }
    
    struct wrap
    {
        char a[2] ;
    } ;
    
    struct wrap Get( void )
    {
        struct wrap w = { 0 } ;
    
        w.a[0] = 'c';
        w.a[1] = 'a';
    
    return w ;
    }
    
    char* getCharArray()
    {
      return "ca";
    }
    
    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;
    }
    
    unsigned char* buffer;
    int length = comm_read_data(file_i2c, &buffer);
    
    /* parse the buffer here */
    
    free(buffer);