【问题标题】:C++ function to return a reversed char arrayC++ 函数返回一个反转的 char 数组
【发布时间】:2020-09-15 03:05:04
【问题描述】:

有人可以帮我让这段代码正常工作吗? Reverse 方法是取一个 char 数组参数,并返回一个反转后的数组。然后我想在 main 中打印出来

#include <iostream>
#include <iomanip>
using namespace std;

char[] Reverse(char ch[]) {
    char arr[sizeof(ch)];

    for (int i=0; i< sizeof(ch); i++){
        arr[i] = ch[sizeof(ch) -i -1];
    }

    return arr;
}

int main() {
    char ch1[] = {'a', 'b', 'c'};
    char ch2[] = Reverse(ch1);


    cout << ch2[0] << endl;
    return 0;
}

【问题讨论】:

  • sizeof(ch) 在我的平台上是 8。看来您希望它是数组的大小。您需要将 Reverse 更改为具有 char ch[], size_t len 参数。 char arr[len]; 将是一个可变长度数组,标准 C++ 不支持。稍后您将需要 char* arr = new char[len];delete[] arr。假设您不能使用std::stringstd::vector
  • @tadman "此代码仅适用于sizeof(ch) 为 1" sizeof(ch)Reverse 函数内部等效于 sizeof (char*),即在大多数平台上为 4 或 8。
  • 任何处理原始 C 字符串的函数要么需要使用 strlen() 来计算长度,NOT sizeof(),要么必须使用显式的 size_t len论据。
  • @tadman • 这不是一个原始的 C 字符串,它是一个没有 '\0' 终止的字符的 C 数组。这也将返回将被破坏的局部变量。呃,这么多呜呜呜。
  • @Eljay 很好的观察,虽然这是这段代码的另一个问题。使用std::string 可以清除其中的大部分内容,或者如果存在阻止这种情况的约束,则可以使用更传统的 C 样式方法。

标签: c++ arrays char reverse function-definition


【解决方案1】:

对于初学者这个函数声明

char[] Reverse(char ch[]);

不正确。函数可能没有数组返回类型。

你可以像这样声明函数

char * Reverse(char ch[]);

但由于您的函数不处理字符串,因此在这种情况下,将您的函数声明为更符合逻辑

void Reverse( char ch[], size_t n );

由于数组类型的函数参数被编译器调整为指向数组元素类型的指针

void Reverse( char *ch, size_t n );

那么在函数中,参数ch 是一个指针。结果,在函数中使用的这个表达式sizeof( ch ) 产生的指针大小取决于所使用的系统,等于 4 或 8。所以这就是我指定函数的第二个参数的原因,因为您需要显式传递如果数组没有通过引用传递给函数,则数组大小。

在函数中,您试图返回指向本地数组第一个元素的指针

char arr[sizeof(ch)];
//...
return arr;

这使得返回的指针无效,因为退出函数后数组将不再存在。

由于函数的第一个参数声明时没有使用限定符 const,因此这意味着该函数需要反转原始数组,而不是制作原始数组的反转副本。

注意main中的这个语句

cout << ch2[0] << endl;

意义不大。它只输出数组的第一个元素。

考虑到所有这些,可以通过以下方式定义函数

#include <iostream>
#include <utility>

void Reverse( char *s, size_t n )
{
    for ( size_t i = 0; i < n / 2; i++ )
    {
        std::swap( s[i], s[n-i-1] );
    }
}

int main() 
{
    char s[] = { 'a', 'b', 'c' };

    std::cout.write( s, sizeof( s ) ) << '\n';

    Reverse( s, sizeof( s ) );

    std::cout.write( s, sizeof( s ) ) << '\n';

    return 0;
}

程序输出是

abc
cba

另一种方法是编写模板函数。在这种情况下,不需要第二个参数。

你来了。

#include <iostream>
#include <utility>

template <size_t N>
void Reverse( char ( &s )[N] )
{
    for ( size_t i = 0; i < N / 2; i++ )
    {
        std::swap( s[i], s[N-i-1] );
    }
}
int main() 
{
    char s[] = { 'a', 'b', 'c' };

    std::cout.write(s, sizeof( s ) ) << '\n';

    Reverse( s );

    std::cout.write(s, sizeof( s ) ) << '\n';

    return 0;
}

如果你想编写一个函数来反转存储在字符数组中的字符串,那么函数声明可以如下所示

char * Reverse( char s[] );

这里还有一个演示程序。

#include <iostream>
#include <utility>
#include <cstring>

char * Reverse( char *s )
{
    for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i++ )
    {
        std::swap( s[i], s[n-i-1] );
    }

    return s;
}

int main() 
{
    char s[] = { 'a', 'b', 'c', '\0' };

    std::cout << s << '\n';

    std::cout << Reverse( s ) << '\n';

    return 0;
}

程序输出将与上面显示的相同

abc
cba

请注意,您可以将标准算法 std::revrese 用于原始数组

#include <iostream>
#include <iterator>
#include <algorithm>

int main() 
{
    char s[] = { 'a', 'b', 'c' };

    std::cout.write( s, sizeof( s ) ) << '\n';

    std::reverse( std::begin( s ), std::end( s ) );

    std::cout.write( s, sizeof( s ) ) << '\n';

    return 0;
}

如果数组包含一个字符串,那么在一般情况下,算法的调用将如下所示

#include <iostream>
#include <algorithm>
#include <cstring>

int main() 
{
    char s[] = { 'a', 'b', 'c', '\0' };

    std::cout << s << '\n';

    std::reverse( s, s + std::strlen( s ) );

    std::cout << s << '\n';

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 2012-04-01
    • 2012-02-14
    • 2010-12-01
    相关资源
    最近更新 更多