如何从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);