Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.04.2012, 23:01   #1
Tokar_1
 
Регистрация: 31.08.2010
Сообщений: 6
Вопрос Рекурсия (печать строки введенного текста в обратном порядке)

Здравствуйте! Помогите, пожалуйста, разобраться в следующей программе:
вводится строка текста с клавиатуры и выводится рекурсивно в обратном порядке
Вот код:
Код:
#include <stdio.h>

void reverse( char *);

int main( void )
{
char sentence[ 80 ]; /* create char array */

printf( "Enter a line of text:\n" );

gets( sentence);

printf( "\nThe line printed backward is:\n" );
reverse( sentence );
return 0; /* indicates successful termination */
}

/* recursively outputs characters in string in reverse order */
void reverse( char * sPtr )
{

if ( sPtr[ 0 ] == '\0' )
return;
}
else {
reverse( &sPtr[ 1 ] );
putchar( sPtr[ 0 ] );
}
}
Непонятно одно, как putchar в функции reverse печатает символы в обратном порядке. Ведь порядок следования двух операторов в части else структуры if приводит к тому что функция reverse переходит к граничному NULL строки до вывода символа на печать. Как только рекурсивный вызов завершается, символы выводятся в обратном порядке ( а почему так???).

Последний раз редактировалось ACE Valery; 12.04.2012 в 00:01.
Tokar_1 вне форума Ответить с цитированием
Старый 11.04.2012, 23:13   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2Tokar_1
во-первых, в коде ошибка. лишняя закрывающая скобка, или не хватает открывающий в if.
Код:
void reverse( char * sPtr )
{

if ( sPtr[ 0 ] == '\0' )
return;
else {
reverse( &sPtr[ 1 ] );
putchar( sPtr[ 0 ] );
}
}
вот так правильно

Цитата:
Ведь порядок следования двух операторов в части else структуры if приводит к тому что функция reverse переходит к граничному NULL строки до вывода символа на печать
мы вызываем reverse рекурсивно перед выводом на печать. когда дойдем до терминального нуля - будем возвращаться назад по стеку. т.е выведем последний символ, предпоследний и тд, до первого


Пс. а чтобы было не просто правильно, но и красиво, нужно писать так
Код:
void reverse(const char *str)
{
	if (*str != '\0' ) {
		reverse(str + 1);
		putchar(*str);
	}
}
ну или так
Код:
void reverse(const char *str)
{
	if (*str == '\0' )
		return;

	reverse(str + 1);
	putchar(*str);
}
я именно так рекурсивные функции и пишу, ибо четко видно условие завершения рекурсии
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 11.04.2012 в 23:18.
pproger вне форума Ответить с цитированием
Старый 12.04.2012, 09:15   #3
Tokar_1
 
Регистрация: 31.08.2010
Сообщений: 6
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
во-первых, в коде ошибка. лишняя закрывающая скобка, или не хватает открывающий в if.
Код:
void reverse( char * sPtr )
{

if ( sPtr[ 0 ] == '\0' )
return;
else {
reverse( &sPtr[ 1 ] );
putchar( sPtr[ 0 ] );
}
}
На самом деле в коде ошибки нет если присмотреться, просто отступов не было.

поясните, пожалуйста, а почему в обратном порядке вызову функции reverse пойдет печать?
Tokar_1 вне форума Ответить с цитированием
Старый 12.04.2012, 09:58   #4
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию

Возьмём, например, строку "12\0".

И код pproger'a

Код:
void reverse(const char *str)
{
	if (*str != '\0' ) {
		reverse(str + 1);
		putchar(*str);
	}
}
И рассмотрим выполнение по вызовам.
Псевдокод:
Код:
Вызов revers #1{  
   Получили "1". Это не "\0"  //прямой ход рекурсии
   Вызов revers #2{
      Получили "2". Это не "\0"
      Вызов revers #3{
         Получили "\0" 
         Передали управление в вызов #2
      }  
      //Обратный ход рекурсии, печатаем результаты
      Распечатали "2"
      Передали управление в вызов #1
   }
   Распечатали "1"
   Вернули управление программе
}
Примерно так
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...
sVasilich вне форума Ответить с цитированием
Старый 12.04.2012, 10:59   #5
Tokar_1
 
Регистрация: 31.08.2010
Сообщений: 6
По умолчанию

Спасибо за ответ, но меня интересует объяснение только моей программы
Tokar_1 вне форума Ответить с цитированием
Старый 12.04.2012, 11:21   #6
Tokar_1
 
Регистрация: 31.08.2010
Сообщений: 6
По умолчанию

sVasilich, pproger спасибо вам большое. Да, дошло, разобрался с помощью вас. Спасибо!!
Tokar_1 вне форума Ответить с цитированием
Старый 12.04.2012, 11:24   #7
sVasilich
Форумчанин
 
Аватар для sVasilich
 
Регистрация: 16.12.2009
Сообщений: 224
По умолчанию

Tokar_1, псевдокод для твоей функции будет точно таким же.
Люди бывают 10 типов: те, кто понимают двоичную систему счисления, и те, кто не понимают...
sVasilich вне форума Ответить с цитированием
Старый 13.04.2012, 11:22   #8
Tokar_1
 
Регистрация: 31.08.2010
Сообщений: 6
По умолчанию

sVasilich, спасибо!!
Tokar_1 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переставить строки в обратном порядке на фортране Александррррррр Помощь студентам 0 18.12.2011 19:38
в целочисленной прямоугольной матрице вывести элементы последней строки в обратном порядке fanofinter Паскаль, Turbo Pascal, PascalABC.NET 3 07.11.2011 11:14
Ввести имя, фамилию и отчество в строку. Найти длину строки, вывести фамилию в обратном порядке (Delphi) --PapaZi-- Помощь студентам 7 27.03.2011 22:44
вывод строки в обратном порядке Delphi BelialL Помощь студентам 7 19.11.2010 18:12
печать страниц в обратном порядке Олекса Microsoft Office Word 4 30.03.2009 09:45