一个C函数,它返回一个字符数组,而不是一个使用两个字符数组的函数

一个C函数,它返回一个字符数组,而不是一个使用两个字符数组的函数,c,function,C,Function,我是C初学者,如果这个疑问太明显,我很抱歉 解决这个问题最有效的方法是什么:假设您有一个char数组ORIG,使用它之后,您应该有一个新的char数组DEST。那么,如果我想为这个目标创建一个函数,最好的方法是: 只接受一个字符数组参数(参数ORIG)并返回字符数组DEST或 一个void函数,它接受两个char数组参数,并根据需要更改DEST 谢谢 这在很大程度上取决于函数的性质 在第一种情况下,函数必须为结果分配存储空间(或者返回指向某个静态对象的指针,但这不是线程安全的)。这可能是正确的做

我是C初学者,如果这个疑问太明显,我很抱歉

解决这个问题最有效的方法是什么:假设您有一个char数组ORIG,使用它之后,您应该有一个新的char数组DEST。那么,如果我想为这个目标创建一个函数,最好的方法是:

  • 只接受一个字符数组参数(参数ORIG)并返回字符数组DEST或
  • 一个void函数,它接受两个char数组参数,并根据需要更改DEST

  • 谢谢

    这在很大程度上取决于函数的性质

    在第一种情况下,函数必须为结果分配存储空间(或者返回指向某个
    静态
    对象的指针,但这不是线程安全的)。这可能是正确的做法,例如,对于复制字符串的函数,如POSIX'
    strdup()
    。这也意味着调用方必须在不再需要时对结果使用
    free()

    第二种情况要求调用方提供存储。在C中,这通常是做这些事情的惯用方法,因为在这种情况下,调用方只需编写

    char result[256];
    func(result, "bla bla");
    

    因此,使用自动对象保存结果。它还有一个好处,就是您可以使用实际返回值来表示错误。

    这两种方法都是有效的方法,但我建议使用后者,因为这意味着您可以将内容加载到任何内存块中,而返回的数组必须位于堆上,并通过设计释放。 同样,这两种方法都是有效的方法,这只是一个指导方针。应该做什么通常取决于情况。

    这取决于, 如果您知道DEST的长度将与ORIG的长度相同,那么我将采用第二种方法,因为这样您就不必在函数内部动态地为DEST分配内存(记住在函数外部释放内存)。 如果长度不同,则必须动态分配内存,可以通过两种方式进行分配: 1.与第一种方法一样,要从c中的函数返回数组,必须分配一个新数组并返回它的地址(指针) 2.函数可以接收两个参数,一个是ORIG,第二个是RES的双指针,因为函数接收一个双指针,所以它可以在其中分配一个数组并通过参数返回它。 1-在代码方面更“干净”,在用户过期率方面更易于使用(用户是调用方)


    祝你好运

    在选项1中,您必须动态分配(malloc)输出数组。这意味着您有可能发生内存泄漏。在选项2中,输出阵列是为您提供的,因此不存在泄漏的可能性,但输出阵列的大小可能不够,并且在写入时会出现缓冲区溢出

    这两种方法都是可以接受的,其中一种方法与另一种方法相比可能有一点性能差异,但这实际上取决于您的选择

    就个人而言,作为一名谨慎的程序员,我会选择选项3:

    /* Returns 0 on success, 1 on failure
       Requires : inputSize <= outpuSize
                  input != output
                  input != null
                  output != null 
    */
    int DoStuff (char* output, size_t outputSize, char* input, size_t inputSize);
    
    /*成功时返回0,失败时返回1
    
    Requires:inputSize使用返回值来表示错误是一个很好的观点,可以说是在函数“可以说”之外创建存储的最佳理由我认为,在选择这种方式时,存储方式的灵活性通常同样重要;)尺寸并非总是必需的,但给出提示是个好主意。还有两件事:1)对大小使用
    size\t
    ,2。)(有争议)将输出参数放在第一位,因为大多数C函数都是这样做的。对不起,我已经很久没有使用C了,但我同意你的两个观点,没有意识到C中有size\t,一个“返回数组”的函数在其他语言中,1实际上是不可能的,所以1很少有用。这类事情通常是通过将原始缓冲区和目标缓冲区传递到函数中来完成的,然后函数将填充dest缓冲区。