我可以使用 char[] 或 char* 作为函数的 return 值吗?

Can I use char[] or char* as a function's return value?

我想知道(我试过了,但程序死机了)是否有办法创建一个 returns char* 或 char[] 的函数,这样我就不必修改字符串我正在发送函数,以了解如何使我的代码更 eloquent。

#include <stdio.h>
#define LOW_LETTERS 97
#define CAP_LETTERS 65
#define N_LETTERS 26
#define DIFF 32
#define NUMBERS 48
#define N_DIGITS 9


void transformText ( char text[] )
{
    for ( int i = 0 ; text[i] != '[=11=]' ; i++ )
    {
        if ( ( text[i] >= LOW_LETTERS ) && ( text[i]  <= LOW_LETTERS + N_LETTERS ) )
            text[ i ] = text [ i ] - DIFF ; //same letter, but upper case
        else
            if ( ( text [ i ] >= CAP_LETTERS ) && ( text[i] <= CAP_LETTERS + N_LETTERS ) )
                text [ i ] = text [ i ] + DIFF ; //same letter, but lower case
            else
                if ( text [i] >= NUMBERS && text[i] <= NUMBERS + N_DIGITS )
                    text[i] = '*'; //turns every number to a '*'
    }

}

int main (void)
{
    char text[] = "foOo123Oo44O99oO00" ;
    transformText ( text ) ;
    printf ( "%s\n", text ) ; //prints FOoO***oO**o**Oo**

    return 0 ;
}

这就是我解决它的方法,我想我有内存泄漏的想法,不是吗?请注意,我没有修改原始字符串,这是我打算做的,而且我真的不知道把 free(newText) 放在哪里所以它被识别,但仍然可用于 main()

#include <stdio.h>
#define LOW_LETTERS 97
#define CAP_LETTERS 65
#define N_LETTERS 26
#define DIFF 32
#define NUMBERS 48
#define N_DIGITS 9
#define BUFFER 128


char* transformText ( char text[] )
{
    char *newText = (char *) malloc (BUFFER) ;
    for ( int i = 0 ; text[i] != '[=12=]' ; i++ )
    {
        if ( ( text[i] >= LOW_LETTERS ) && ( text[i]  <= LOW_LETTERS + N_LETTERS ) )
            newText[ i ] = text [ i ] - DIFF ; //same letter, but upper case
        else
            if ( ( text [ i ] >= CAP_LETTERS ) && ( text[i] <= CAP_LETTERS + N_LETTERS ) )
                newText [ i ] = text [ i ] + DIFF ; //same letter, but lower case
            else
                if ( text [i] >= NUMBERS && text[i] <= NUMBERS + N_DIGITS )
                    newText[i] = '*'; //turns every number to a '*'
                else
                    newText[i] = text[i] ;
    }

    return newText ;
}

int main (void)
{
    char text[] = "foOo123Oo44O99oO00" ;

    printf ( "%s\n", transformText ( text ) ) ; //prints FOoO***oO**o**Oo**
    return 0 ;
}

总的来说,是的,你有一个 return 是 char * 的功能是很好的,但你需要注意一些事情,比如

  • 你需要确保不要return局部变量的地址到被调用函数。这将产生在调用者中使用无效内存的问题。更好的方法是使用 malloc() 或 family 和 return 指针分配内存。您还需要 free() 内存,一旦您使用完它。
  • 如果您要使用 returned 指针,您需要确保 returned 指针的有效性。

编辑:

因此,一旦您在调用方中获得了 returned 指针并完成了它的使用,您需要通过调用 free() 并传递指针来释放之前分配的内存。在你的情况下,它应该看起来像

char * res = transformText ( text );
printf ( "%s\n", res );   // use the returned pointer
free(res);                                  // release memory
return 0 ;                                   // done

很直:

#include <stdio.h>
#define LOW_LETTERS 97
#define CAP_LETTERS 65
#define N_LETTERS 26
#define DIFF 32
#define NUMBERS 48
#define N_DIGITS 9


char* transformText ( char text[] )
{
for ( int i = 0 ; text[i] != '[=10=]' ; i++ )
{
if ( ( text[i] >= LOW_LETTERS ) && ( text[i]  <= LOW_LETTERS + N_LETTERS ) )
text[ i ] = text [ i ] - DIFF ; //same letter, but upper case
else
if ( ( text [ i ] >= CAP_LETTERS ) && ( text[i] <= CAP_LETTERS + N_LETTERS ) )
text [ i ] = text [ i ] + DIFF ; //same letter, but lower case
else
if ( text [i] >= NUMBERS && text[i] <= NUMBERS + N_DIGITS )
text[i] = '*'; //turns every number to a '*'
}
return text;

}

int main (void)
{
char text[] = "foOo123Oo44O99oO00" ;
char* text2 = transformText ( text ) ;
printf ( "%s\n", text ) ; //prints FOoO***oO**o**Oo**
printf ( "%s\n", text2 ) ; //prints FOoO***oO**o**Oo**
free(text2);
return 0 ;
}

returns 相同值:

由于函数不能 return 数组,您需要 return 来自堆的指针。你不能 return 数组的原因是因为它们在堆栈上声明,并在函数 returns 时被擦除。而如果你 return 一个指针,你可以在你的程序中共享这个指针。

你的代码大概是这样的:

char* transformText(const char text[]) {
    char *result = malloc(........);
    /* check malloc */
    /* more code */
    return result;
}

int main(void) {
    const char text[] = "foOo123Oo44O99oO00";
    char *result = transformText(text);
    /* do more stuff */

    /* deallocate pointer */
    free(result);
}

这是另一个示例,表明您仍然可以将 void() 用于您的函数,而不是 return 任何东西:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void allocate(const char text[], char **result) {
    *result = malloc(strlen(text)+1);
}

int main(void) {
    const char text[] = "foOo123Oo44O99oO00";
    char *result; 

    allocate(text, &result);
    strcpy(result, text);

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

    free(result);

    return 0;
}

大多数情况下,您不想从函数中 return 一个 char*。在你的情况下这样做没有明显的好处。

替代方法是让调用者复制一份:

const char text[] = "foOo123Oo44O99oO00";
char text_copy [strlen(text)+1];
memcpy(text_copy, text, sizeof(text));
transformText (text_copy);

或让函数执行此操作:

void transformText (char* dst, const char* src)
{
  // iterate over src
  // store result in dst
}

没有明显的理由说明为什么动态分配在这里是有益的。使用动态内存听起来更像是一个由糟糕的程序设计引起的 side-effect。应避免返回指向动态内存的指针,因为它很可能导致内存泄漏。

尽可能将分配留给调用者。