Функция C ++ для возврата массива обратных символов - PullRequest
0 голосов
/ 28 мая 2020

Может кто-нибудь помочь мне заставить этот код работать? Метод Reverse заключается в том, чтобы взять параметр массива char и вернуть обратный массив. Затем я хочу распечатать его в основном

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

Ответы [ 2 ]

0 голосов
/ 28 мая 2020

В нормальной ситуации вы бы просто использовали std::reverse и покончили с этим. Вы также можете использовать контейнеры C ++, для массивов переменной длины вы должны использовать std::vector, в этом конкретном случае, учитывая, что это массив char, вы должны использовать std::string.

Что касается вашего кода, чтобы он работал, вам нужно будет заменить char arr[sizeof(ch)]; на char arr[strlen(ch)];, тогда проблема станет массивы переменной длины не являются частью стандарта C ++ , тогда решение - либо передать второй массив char в качестве параметра, либо использовать выделение памяти.

Для последнего:

#include <iostream>

//using namespace std;

char *Reverse(char *ch)
{
    size_t i;
    char *arr = new char[strlen(ch) + 1]; //allocate space for a 4 char array

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

int main()
{
    char ch1[] = {'a', 'b', 'c', '\0'}; //adding a null terminator
    //or char ch1[] = "abc";
    //or even pass the size of the char array (`sizeof(ch1)`) as a parameter of Reverse
    //in this case you wouldn't need to null terminate, but you can't treat it as a string
    //this because strlen only works in null terminated char arrays aka strings
    char *ch2 = Reverse(ch1);
    std::cout << ch2 << std::endl;
    delete [] ch2;
    return EXIT_SUCCESS;
}
0 голосов
/ 28 мая 2020

Для начала, это объявление функции

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